I looked at the Fire3 where I have notes that say "interrupts just worked". Those notes were wrong. It is running at EL2 and interrupts do not work.
ARM provides what looks like nice example code, but you will find that a few things are missing, and that it simply doesn't work.
ELR_el2 -- has the address to branch to SPSR_el2 -- has the values to be loaded into the PSRNote the _el2 suffixes. This is for a transition from EL2 to EL1. The level is part of what goes into the SPSR register (saved PSR).
SPSR is a 64 bit register. For our purposes, the entire upper 32 bits can be zero.
bits 31:27 -- condition codes NZCVQ (can all be zero) bit 9 - D bit (debug) bit 8 - A bit (SError) bit 7 - I bit (IRQ mask) bit 6 - F bit (FIQ mask) bit 5 - 0 bit 4 - M bit (1 selects 32 bit aarch32 state) bits 3:0 -- EL and selected stackHere are the values for the last 4 bits (EL)
0000 - EL0 0100 - EL1 with SP_EL0 0101 - EL1 with SP_EL1 1000 - EL2 with SP_EL0 1001 - EL2 with SP_EL2There are values to select EL3, but they will just cause exceptions if they are attempted for ERET from EL2.
The whole business of choosing which stack gets used is peculiar (if you ask me). We do have 4 different stack pointers (for EL0,1,2, and 3), but we can decide to always use the EL0 stack for all levels, if that is what we want to do.
I learned by experiment on the RK3328 that U-boot hands the processor to us running at EL2 with SP_EL0, so I will continue with that for EL1.
Tom's electronics pages / tom@mmto.org