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