ARM: omap5/dra7xx: Enable booting secondary CPU in HYP mode

If the boot loader enables HYP mode on the boot CPU, the secondary CPU
also needs to call into the ROM to switch to HYP mode before booting.
The firmwares on the omap5 and dra7xx unfortunately do not take care
of this, so it has to be handled by the kernel.

This patch is based on "[PATCH 2/2] ARM: OMAP5: Add HYP mode entry support
for secondary CPUs" by Santosh Shilimkar <santosh.shilimkar@ti.com>,
except this version does not require a compile time CONFIG to control
if it should enable HYP mode or not, it simply does it based on the mode
of the boot CPU, so it works whether the CPU boots in SVC or HYP mode,
and should even work as a guest kernel inside kvm if qemu decides to
support emulating the omap5 or dra7xx.

Cc: stable@vger.kernel.org #v3.16+
Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: Tony Lindgren <tony@atomide.com>
This commit is contained in:
Lennart Sorensen 2015-01-05 15:45:45 -08:00 коммит произвёл Tony Lindgren
Родитель afc9d590b8
Коммит 999f934de1
3 изменённых файлов: 33 добавлений и 2 удалений

Просмотреть файл

@ -249,6 +249,7 @@ extern void omap4_cpu_die(unsigned int cpu);
extern struct smp_operations omap4_smp_ops; extern struct smp_operations omap4_smp_ops;
extern void omap5_secondary_startup(void); extern void omap5_secondary_startup(void);
extern void omap5_secondary_hyp_startup(void);
#endif #endif
#if defined(CONFIG_SMP) && defined(CONFIG_PM) #if defined(CONFIG_SMP) && defined(CONFIG_PM)

Просмотреть файл

@ -22,6 +22,7 @@
/* Physical address needed since MMU not enabled yet on secondary core */ /* Physical address needed since MMU not enabled yet on secondary core */
#define AUX_CORE_BOOT0_PA 0x48281800 #define AUX_CORE_BOOT0_PA 0x48281800
#define API_HYP_ENTRY 0x102
/* /*
* OMAP5 specific entry point for secondary CPU to jump from ROM * OMAP5 specific entry point for secondary CPU to jump from ROM
@ -40,6 +41,26 @@ wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
bne wait bne wait
b secondary_startup b secondary_startup
ENDPROC(omap5_secondary_startup) ENDPROC(omap5_secondary_startup)
/*
* Same as omap5_secondary_startup except we call into the ROM to
* enable HYP mode first. This is called instead of
* omap5_secondary_startup if the primary CPU was put into HYP mode by
* the boot loader.
*/
ENTRY(omap5_secondary_hyp_startup)
wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
ldr r0, [r2]
mov r0, r0, lsr #5
mrc p15, 0, r4, c0, c0, 5
and r4, r4, #0x0f
cmp r0, r4
bne wait_2
ldr r12, =API_HYP_ENTRY
adr r0, hyp_boot
smc #0
hyp_boot:
b secondary_startup
ENDPROC(omap5_secondary_hyp_startup)
/* /*
* OMAP4 specific entry point for secondary CPU to jump from ROM * OMAP4 specific entry point for secondary CPU to jump from ROM
* code. This routine also provides a holding flag into which * code. This routine also provides a holding flag into which

Просмотреть файл

@ -22,6 +22,7 @@
#include <linux/irqchip/arm-gic.h> #include <linux/irqchip/arm-gic.h>
#include <asm/smp_scu.h> #include <asm/smp_scu.h>
#include <asm/virt.h>
#include "omap-secure.h" #include "omap-secure.h"
#include "omap-wakeupgen.h" #include "omap-wakeupgen.h"
@ -227,8 +228,16 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
if (omap_secure_apis_support()) if (omap_secure_apis_support())
omap_auxcoreboot_addr(virt_to_phys(startup_addr)); omap_auxcoreboot_addr(virt_to_phys(startup_addr));
else else
writel_relaxed(virt_to_phys(omap5_secondary_startup), /*
base + OMAP_AUX_CORE_BOOT_1); * If the boot CPU is in HYP mode then start secondary
* CPU in HYP mode as well.
*/
if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
base + OMAP_AUX_CORE_BOOT_1);
else
writel_relaxed(virt_to_phys(omap5_secondary_startup),
base + OMAP_AUX_CORE_BOOT_1);
} }