.section .text.drivers.psci
// Initializes the PSCI with a fixed method.
//
// ## Arguments
//
// - x0: 0 if the SMC method should be used, 1 if the HVC method should be used.
.global psci.init_with
psci.init_with:
cmp x0, #2
b.hs psci.init_with.error
ldr x1, =psci.init_with.funcs
ldr x0, [x1, x0, lsl 3]
ldr x1, =psci.function
str x0, [x1]
ret
psci.init_with.error:
ldr x0, =psci.init_with.error_msg
mov x1, psci.init_with.error_msg.len
bl panic
// Performs a call to the hypervisor. This should be used if the PSCI node in
// the devicetree has a method of `hvc`.
psci.function_hvc:
hvc #0
ret
// Performs a call to the secure monitor. This should be used if the PSCI node
// in the devicetree has a method of `smc`.
psci.function_smc:
smc #0
ret
// Powers off the system.
.global psci.system_off
psci.system_off:
ldr x15, =psci.function
ldr x15, [x15]
mov x0, #0x84000000
movk x0, #0x8
br x15
// Resets the system.
.global psci.system_reset
psci.system_reset:
ldr x15, =psci.function
ldr x15, [x15]
mov x0, #0x84000000
movk x0, #0x9
br x15
.section .rodata.drivers.psci
psci.init_with.error_msg: .ascii "Invalid value passed to psci.init_with!"
.set psci.init_with.error_msg.len, . - psci.init_with.error_msg
.align 8
psci.init_with.funcs:
.quad psci.function_smc
.quad psci.function_hvc
.section .bss.drivers.psci
.align 8
psci.function: .skip 8
// vi: set ft=arm64asm :