On Fri, Jan 22, 2016 at 09:36:49PM +0100, Patrick Wildt wrote: > 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.
This seems to be based on the code in FreeBSD? I'd prefer A32_bit for consistency with the other mask bit defines but otherwise I think this should go in. > > 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 > >