Commit fa036ea44cf070a7688c36531938b28f41aed45e

Authored by Lennart Sorensen
Committed by Greg Kroah-Hartman
1 parent 3af7a88e25

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

commit 999f934de195a1506089b52c77429fdba25da688 upstream.

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.

Signed-off-by: Len Sorensen <lsorense@csclub.uwaterloo.ca>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 3 changed files with 33 additions and 2 deletions Side-by-side Diff

arch/arm/mach-omap2/common.h
... ... @@ -249,6 +249,7 @@
249 249 extern struct smp_operations omap4_smp_ops;
250 250  
251 251 extern void omap5_secondary_startup(void);
  252 +extern void omap5_secondary_hyp_startup(void);
252 253 #endif
253 254  
254 255 #if defined(CONFIG_SMP) && defined(CONFIG_PM)
arch/arm/mach-omap2/omap-headsmp.S
... ... @@ -22,6 +22,7 @@
22 22  
23 23 /* Physical address needed since MMU not enabled yet on secondary core */
24 24 #define AUX_CORE_BOOT0_PA 0x48281800
  25 +#define API_HYP_ENTRY 0x102
25 26  
26 27 /*
27 28 * OMAP5 specific entry point for secondary CPU to jump from ROM
... ... @@ -40,6 +41,26 @@
40 41 bne wait
41 42 b secondary_startup
42 43 ENDPROC(omap5_secondary_startup)
  44 +/*
  45 + * Same as omap5_secondary_startup except we call into the ROM to
  46 + * enable HYP mode first. This is called instead of
  47 + * omap5_secondary_startup if the primary CPU was put into HYP mode by
  48 + * the boot loader.
  49 + */
  50 +ENTRY(omap5_secondary_hyp_startup)
  51 +wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
  52 + ldr r0, [r2]
  53 + mov r0, r0, lsr #5
  54 + mrc p15, 0, r4, c0, c0, 5
  55 + and r4, r4, #0x0f
  56 + cmp r0, r4
  57 + bne wait_2
  58 + ldr r12, =API_HYP_ENTRY
  59 + adr r0, hyp_boot
  60 + smc #0
  61 +hyp_boot:
  62 + b secondary_startup
  63 +ENDPROC(omap5_secondary_hyp_startup)
43 64 /*
44 65 * OMAP4 specific entry point for secondary CPU to jump from ROM
45 66 * code. This routine also provides a holding flag into which
arch/arm/mach-omap2/omap-smp.c
... ... @@ -22,6 +22,7 @@
22 22 #include <linux/irqchip/arm-gic.h>
23 23  
24 24 #include <asm/smp_scu.h>
  25 +#include <asm/virt.h>
25 26  
26 27 #include "omap-secure.h"
27 28 #include "omap-wakeupgen.h"
... ... @@ -227,8 +228,16 @@
227 228 if (omap_secure_apis_support())
228 229 omap_auxcoreboot_addr(virt_to_phys(startup_addr));
229 230 else
230   - writel_relaxed(virt_to_phys(omap5_secondary_startup),
231   - base + OMAP_AUX_CORE_BOOT_1);
  231 + /*
  232 + * If the boot CPU is in HYP mode then start secondary
  233 + * CPU in HYP mode as well.
  234 + */
  235 + if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
  236 + writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
  237 + base + OMAP_AUX_CORE_BOOT_1);
  238 + else
  239 + writel_relaxed(virt_to_phys(omap5_secondary_startup),
  240 + base + OMAP_AUX_CORE_BOOT_1);
232 241  
233 242 }
234 243