January 7, 2022
Orange Pi 4 (Rockchip 3399) AArch64 ARM execution levels
In 64 bit mode, the processor can run at any one of 4 "execution levels".
Level 3 is the most privileged and level 0 might be for "user code".
So typically level 3 and/or 2 are reserved for some kind of hypervisor,
level 1 would be used by an operating system, and level 0 for user code.
32 bit ARM has only 2 levels (user and supervisor).
Note that it is possible for a 64 bit operating system to run
32 bit user code (but not for a 32 bit operating system to run
64 bit user code).
Execution level can only change when the processor takes an exception.
This is certainly the right thing when we want an event in user code
to cause an exception to be handled by the operating system.
Causing an intentional transition to a less privileged level (as when
an operating system starts user code running) involves some trickery.
So .. what are we running in
I performed some experiments. We are running in EL 2 (not 3) which suggests
that some hypervisor is running in EL 3. I did the some experiment for the
Allwinner h5 code and found the same thing. I also attempted to access the
SCR_EL3 register, but this yields a fault.
I was doing this to learn whether or not I was in "secure mode" (see below).
A fault is to be expected, given that I am trying to access an EL3
register from EL2.
There is no corresponding register for EL2.
If I was able to inspect this register, that would tell me
if I was in secure mode or not. I use some inline assembly to look at these
registers, as in the following:
static inline unsigned int
unsigned int val;
asm volatile("mrs %0, CurrentEL" : "=r" (val) : : "cc");
return val >> 2;
So my conclusion? I am running at EL 2 and almost certainly not in secure mode.
Secure versus Non-secure
This is an entirely different business that you would think might be handled
by the execution level business above, but isn't.
In fact people like to say that this secure/non-secure business is
orthogonal to the execution level business described above.
The ARM people call this "trust zone", which sounds a lot like
a marketing name to me.
Note that "trust zone" is available (though rare in my experience)
as an option for 32 bit ARM processors.
It seems all but ubiquitous in the 64 bit ARM world.
A processor boots up in "secure mode", which can access both secure and
non-secure resources. It can divide the memory map into secure and
non-secure regions. Once it switches to non-secure mode, the secure
regions will not be accessible.
The on chip bootrom in some chips protects itself and then switches to the non-secure mode
before transfering control to the loaded bootloader. This makes it impossible to:
A chip like this would simply be leveraging the marketing hype about "TrustZone" without
making it available for any practical use (such as storing encryption keys or such).
- Examine the bootloader itself.
- Perform any experiments or configuration of secure mode.
Interestingly a processor in non-secure mode cannot detect whether or not it is running in secure
mode or not. There is an SCR register, but attempting to access it will yield an exception in
non-secure mode (that should tell you if you are running in secure mode or not, eh?).
You get something like a undefined exception trap. Note that the SCR is called SCR_EL3 most likely.
It apparently exists only in EL3.
Have any comments? Questions?
Drop me a line!
Tom's electronics pages / email@example.com