Now rather than summarizing what I read online about aarch64 topics, I want to get my hands dirty and try some things. I am working with an RK3328 chip on an Orange Pi R1+ LTS board. I am using U-boot to network boot code I build. I have learned that the code runs at EL 2.
I add this code to a bare metal project I am currently working on and give it a try:
void
try_syscall ( void )
{
asm volatile("svc #0x123" );
}
As expected (and hoped for) I get a synchronous abort.
Apparently U-boot handled it and prints the following:
"Synchronous Abort" handler, esr 0x56000123 elr: ffffffffc22d72e0 lr : ffffffffc22d7350 (reloc) elr: 00000000020002e0 lr : 0000000002000350 x0 : 0000000000000000 x1 : 000000000000000aU-boot doesn't try to analyze the synchronous abort in any way shape or form, but it is kind enough to dump the ESR register for us. Notice the value in the ESR register, which has 0x0123 in the last 16 bits!
Also notice the first 6 bits. The first 8 are:
0x56 = 0101_0110A value of 0101_01xx would indicate an SVC call. How about that?
My makefile is set up to disassemble the image and show me the assembly language. I see this:
00000000020002d8Notice that the value of ELR shown by U-boot is 020002e0, which is the address of the "nop" that follows the SVC instruction. Everything looks like it should and makes sense.: 20002d8: d503245f bti c 20002dc: d4002461 svc #0x123 20002e0: d503201f nop 20002e4: d65f03c0 ret
What about the value 2000350 in the LR register, you might ask. This is the return address for the call to try_syscall(). The LR register pertains to ordinary code execution, whereas ELR pertains to exceptions. After printing this information, U-boot does a reset which results in a boot loop, trying this code over and over.
My code displays the value of a number of important registers, including VBAR_el2:
VBAR_el2 = 3FF2B800We can get to the U-boot prompt and ask U-boot to show us what is there, but we better be prepared to read ARM code as binary:
3ff2b800: a9bf7bfd 94000003 9400041e 14000040 3ff2b810: a9bf73fb a9bf6bf9 a9bf63f7 a9bf5bf5 3ff2b820: a9bf53f3 a9bf4bf1 a9bf43ef a9bf3bed 3ff2b830: a9bf33eb a9bf2be9 a9bf23e7 a9bf1be5 3ff2b840: a9bf13e3 a9bf0be1 14000012 d503201f 3ff2b850: d503201f d503201f d503201f d503201f 3ff2b860: d503201f d503201f d503201f d503201f 3ff2b870: d503201f d503201f d503201f d503201f 3ff2b880: a9bf7bfd 97ffffe3 9400040e 14000020 3ff2b890: d538424b f100217f 5400006c 540000c0 3ff2b8a0: 5400012b d53e5201 d53e4022 d53e4003 3ff2b8b0: 14000008 d53c5201 d53c4022 d53c4003 3ff2b8c0: 14000004 d5385201 d5384022 d5384003 3ff2b8d0: a9bf03e1 a9bf0be3 910003e0 d65f03c0 3ff2b8e0: d503201f d503201f d503201f d503201f 3ff2b8f0: d503201f d503201f d503201f d503201fJust for the record d503201f is a "nop" instruction. The instructions that begin with a9bf are "stp". The instruction that begins with 1400 is a "b" d69f03e0 is an "eret", but we don't see that.
Should we disassemble this code or try to find it in the U-boot sources? It didn't take that long to find what looks like the correct source file:
RK3328/sources/u-boot/arch/arm/cpu/armv8/exceptions.SHere is the source from there for the Synchronous abort handler, which certainly looks like a match for the above.
.align 11
.globl vectors
vectors:
.align 7 /* Current EL Synchronous Thread */
stp x29, x30, [sp, #-16]!
bl _exception_entry
bl do_bad_sync
b exception_exit
_exception_entry:
stp x27, x28, [sp, #-16]!
stp x25, x26, [sp, #-16]!
stp x23, x24, [sp, #-16]!
stp x21, x22, [sp, #-16]!
stp x19, x20, [sp, #-16]!
stp x17, x18, [sp, #-16]!
stp x15, x16, [sp, #-16]!
stp x13, x14, [sp, #-16]!
stp x11, x12, [sp, #-16]!
stp x9, x10, [sp, #-16]!
stp x7, x8, [sp, #-16]!
stp x5, x6, [sp, #-16]!
stp x3, x4, [sp, #-16]!
stp x1, x2, [sp, #-16]!
b _save_el_regs /* jump to the second part */
We now know where we could patch in some kind of branch to our own code.
Perhaps more importantly, we have the source code for this part of U-boot
to study and contemplate.
I need to add the code to save/restore registers, then set up the SVC handler to do the LED blinking. Just for fun.
Tom's Computer Info / tom@mmto.org