diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2017-02-06 16:11:03 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-02-13 08:35:42 +0100 |
commit | cc407b41135d4a427dfb09fb6e32b831e6c98a31 (patch) | |
tree | 0ba793b8a0c041819e4409f0c31b2d4f297c997a /arch/arm/lib32/armlinux.c | |
parent | cdf33e6ecf4ca724d8be64fefbc4896eb8baf046 (diff) | |
download | barebox-cc407b41135d4a427dfb09fb6e32b831e6c98a31.tar.gz barebox-cc407b41135d4a427dfb09fb6e32b831e6c98a31.tar.xz |
ARM: Add PSCI support
This patch contains the barebox implementation for the ARM
"Power State Coordination Interface" (PSCI).
The interface is aimed at the generalization of code in the following
power management scenarios:
* Core idle management.
* Dynamic addition and removal of cores, and secondary core boot.
* big.LITTLE migration.
* System shutdown and reset.
In practice, all that's currently implemented is a way to enable the
secondary core one some SoCs.
With PSCI the Kernel is either started in nonsecure or in Hypervisor
mode and PSCI is used to apply power to the secondary cores.
The start mode is passed in the global.bootm.secure_state variable. This
enum can contain "secure" (Kernel is started in secure mode, means no
PSCI), "nonsecure" (Kernel is started in nonsecure mode, PSCI available)
or "hyp" (Kernel is started in hyp mode, meaning it can support
virtualization).
We currently only support putting the secure monitor code into SDRAM,
which means we always steal some amount of memory from the Kernel.
To keep things simple for now we simply keep the whole barebox binary in
memory
The PSCI support has been tested on i.MX7 only so far. The only
supported operations are CPU_ON and CPU_OFF.
The PSCI and secure monitor code is based on the corresponding U-Boot
code.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/lib32/armlinux.c')
-rw-r--r-- | arch/arm/lib32/armlinux.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/arch/arm/lib32/armlinux.c b/arch/arm/lib32/armlinux.c index 6c7bd101c2..2520fe210c 100644 --- a/arch/arm/lib32/armlinux.c +++ b/arch/arm/lib32/armlinux.c @@ -38,6 +38,7 @@ #include <asm/barebox-arm.h> #include <asm/armlinux.h> #include <asm/system.h> +#include <asm/secure.h> static struct tag *params; static void *armlinux_bootparams = NULL; @@ -258,11 +259,19 @@ static void setup_tags(unsigned long initrd_address, } void start_linux(void *adr, int swap, unsigned long initrd_address, - unsigned long initrd_size, void *oftree) + unsigned long initrd_size, void *oftree, + enum arm_security_state state) { void (*kernel)(int zero, int arch, void *params) = adr; void *params = NULL; int architecture; + int ret; + + if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state > ARM_STATE_SECURE) { + ret = armv7_secure_monitor_install(); + if (ret) + pr_err("Failed to install secure monitor\n"); + } if (oftree) { pr_debug("booting kernel with devicetree\n"); @@ -274,6 +283,10 @@ void start_linux(void *adr, int swap, unsigned long initrd_address, architecture = armlinux_get_architecture(); shutdown_barebox(); + + if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state == ARM_STATE_HYP) + armv7_switch_to_hyp(); + if (swap) { u32 reg; __asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg)); |