Hi,

the hypervisor mode, which virtualization-enabled boards might boot in,
is basically a privilege level above the usual SVC mode the kernel is
running in.  It does not support the full instruction set and we, as
a "guest" OS, need to step down and run in SVC.  Otherwise we crash
really early on.

This diff makes sure the machine jumps from HYP to SVC mode, if it's
booted in HYP mode.  This should enable us to run on a few more
current machines.

If we're ever going to run virtualization on ARM, we will need to
establish a hyp mode vector table.  For now this is not needed.

This diff includes the previously sent in processor mode define diff.

Patrick

diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h
index 1748950..8eb46d9 100644
--- a/sys/arch/arm/include/armreg.h
+++ b/sys/arch/arm/include/armreg.h
@@ -69,6 +69,7 @@
 #define PSR_V_bit (1 << 28)    /* overflow */
 
 #define PSR_Q_bit (1 << 27)    /* saturation */
+#define PSR_A_bit (1 << 8)     /* Asynchronous abort disable */
 
 #define I32_bit (1 << 7)       /* IRQ disable */
 #define F32_bit (1 << 6)       /* FIQ disable */
@@ -85,7 +86,9 @@
 #define PSR_FIQ32_MODE 0x00000011
 #define PSR_IRQ32_MODE 0x00000012
 #define PSR_SVC32_MODE 0x00000013
+#define PSR_MON32_MODE 0x00000016
 #define PSR_ABT32_MODE 0x00000017
+#define PSR_HYP32_MODE 0x0000001a
 #define PSR_UND32_MODE 0x0000001b
 #define PSR_SYS32_MODE 0x0000001f
 #define PSR_32_MODE    0x00000010
diff --git a/sys/arch/armv7/armv7/armv7_start.S 
b/sys/arch/armv7/armv7/armv7_start.S
index 63e60e6..1172b36 100644
--- a/sys/arch/armv7/armv7/armv7_start.S
+++ b/sys/arch/armv7/armv7/armv7_start.S
@@ -37,6 +37,9 @@
 #undef DOMAIN_CLIENT   /* XXX */
 #include "assym.h"
 
+#define ELR    .long   0xe12ef30e              @ msr   ELR_hyp, lr
+#define ERET   .long   0xe160006e              @ eret
+
 /*
  * CPWAIT -- Canonical method to wait for CP15 update.
  * NOTE: Clobbers the specified temp reg.
@@ -87,12 +90,32 @@ _C_LABEL(bootstrap_start):
         * the low bits
         */
 
+       /*
+        * If we are running in HYP mode, try to get to SVC safely.
+        * Ensure IRQ, FIQ and Aborts are disabled in HYP mode before
+        * going to SVC.  If we are there already, just go ahead.
+        */
+       mrs     r0, cpsr
+       and     r0, r0, #(PSR_MODE)
+       teq     r0, #(PSR_HYP32_MODE)
+       bne     1f                      /* If we are not in HYP, we're done */
+       mrs     r0, cpsr
+       bic     r0, r0, #(PSR_MODE)
+       orr     r0, r0, #(PSR_SVC32_MODE)
+       orr     r0, r0, #(I32_bit | F32_bit | PSR_A_bit)
+       msr     spsr_fsxc, r0
+       adr     lr, 1f
+       ELR
+       ERET                            /* Use the HYP LR to get into SVC */
+1:
+
+       /*
+        * Now that we are in SVC, build up pagetables and start up.
+        */
        mov r9, pc
        and r9, r9, #0xf0000000 // Leave the memory base in r9
 
        /* create the bootstrap MMU table at offset 0x00200000 */
-
-       /* build page table from scratch */
        orr     r0, r9, #0x00200000
        adr     r4, mmu_init_table
 

Reply via email to