.text\r
.align 3\r
\r
-ASM_GLOBAL ASM_PFX(SetupExceptionLevel3)\r
ASM_GLOBAL ASM_PFX(SwitchToNSExceptionLevel1)\r
ASM_GLOBAL ASM_PFX(enter_monitor_mode)\r
ASM_GLOBAL ASM_PFX(return_from_exception)\r
ASM_GLOBAL ASM_PFX(copy_cpsr_into_spsr)\r
ASM_GLOBAL ASM_PFX(set_non_secure_mode)\r
\r
-ASM_PFX(SetupExceptionLevel3):\r
- // Check for the primary CPU to avoid a race on the distributor registers.\r
- mrs x0, mpidr_el1\r
- tst x0, #15\r
- b.ne 1f // secondary CPU\r
-\r
- LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1)\r
- mov w0, #3 // EnableGrp0 | EnableGrp1\r
- str w0, [x1]\r
-\r
-1: LoadConstantToReg (FixedPcdGet32(PcdGicDistributorBase), x1)\r
- add x1, x1, #0x80\r
- mov w0, #~0 // Grp1 interrupts\r
- str w0, [x1], #4\r
- b.ne 2f // Only local interrupts for secondary CPUs\r
- str w0, [x1], #4\r
- str w0, [x1], #4\r
-\r
-2: LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1)\r
- ldr w0, [x1]\r
- mov w0, #3 // EnableGrp0 | EnableGrp1\r
- str w0, [x1]\r
-\r
- mov w0, #1 << 7 // allow NS access to GICC_PMR\r
- str w0, [x1, #4] // GICC_PMR\r
-\r
- ret\r
-\r
// Switch from EL3 to NS-EL1\r
ASM_PFX(SwitchToNSExceptionLevel1):\r
// Now setup our EL1. Controlled by EL2 config on Model\r
// We may need to do some config before we change to another Mode.\r
ASM_PFX(return_from_exception):\r
msr elr_el3, x0\r
-\r
- mrs x7, spsr_el3\r
- ands w7, w7, #0xC\r
- cmp w7, #0xC // EL3?\r
- b.eq 3f\r
- bl ASM_PFX(SetupExceptionLevel3)\r
- cmp w7, #0x8 // EL2?\r
- b.eq 2f\r
- cmp w7, #0x4 // EL1?\r
- b.eq 1f\r
- b dead // We should never get here.\r
-\r
-1: bl ASM_PFX(SwitchToNSExceptionLevel1)\r
-2: // EL2: No more setup required.\r
-3: // EL3: Not sure why we would do this.\r
eret\r
\r
// For AArch64 we need to construct the spsr we want from individual bits and pieces.\r