From 35684b1b7e0a04a68987056cb15abd97e3d2f0cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Tue, 20 Nov 2018 00:00:01 +0000 Subject: [PATCH] arm exception level emulator entry examples --- README.adoc | 68 ++++++++++++++++++++++++++++++++++--- baremetal/arch/aarch64/el.c | 8 +++-- baremetal/arch/arm/el.c | 11 ++++++ 3 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 baremetal/arch/arm/el.c diff --git a/README.adoc b/README.adoc index cd13a27..b9a13c5 100644 --- a/README.adoc +++ b/README.adoc @@ -10396,19 +10396,77 @@ help architecture shows ARM version up to `armv6`, so maybe `armv6` is not implemented? -=== ARM EL +=== ARM exception level -Find the ARM EL: https://stackoverflow.com/questions/31787617/what-is-the-current-execution-mode-exception-level-etc +ARM exception levels are analogous to x86 <>. -Prints the EL at the beginning of a baremetal simulation: +Print the EL at the beginning of a baremetal simulation: .... +./run --arch arm --baremetal arch/arm/el ./run --arch aarch64 --baremetal arch/aarch64/el .... -Source: link:baremetal/arch/aarch64/el.c[] +Sources: -The lower ELs are not mandatory, and in gem5 at least you can configure the lowest EL with configuration options TODO which, example. +* link:baremetal/arch/arm/el.c[] +* link:baremetal/arch/aarch64/el.c[] + +The instructions that find the ARM EL are explained at: https://stackoverflow.com/questions/31787617/what-is-the-current-execution-mode-exception-level-etc + +The lower ELs are not mandated by the architecture, and can be controlled through command line options in QEMU and gem5. + +In QEMU, you can configure the lowest EL as explained at https://stackoverflow.com/questions/42824706/qemu-system-aarch64-entering-el1-when-emulating-a53-power-up + +.... +./run --arch arm --baremetal arch/arm/el +./run --arch arm --baremetal arch/arm/el -- -machine virtualization=on +./run --arch arm --baremetal arch/arm/el -- -machine secure=on +./run --arch aarch64 --baremetal arch/aarch64/el +./run --arch aarch64 --baremetal arch/aarch64/el -- -machine virtualization=on +./run --arch aarch64 --baremetal arch/aarch64/el -- -machine secure=on +.... + +outputs respectively: + +.... +19 +19 +19 +1 +2 +3 +.... + +TODO: why is `arm` stuck at `19` which equals Supervisor mode? + +In gem5, you can configure the lowest EL with: + +.... +./run --arch arm --baremetal arch/arm/el --gem5 +cat "$(./getvar --arch arm --gem5 gem5_guest_terminal_file)" +./run --arch arm --baremetal arch/arm/el --gem5 -- --param 'system.have_virtualization = True' +cat "$(./getvar --arch arm --gem5 gem5_guest_terminal_file)" +./run --arch arm --baremetal arch/arm/el --gem5 -- --param 'system.have_security = True' +cat "$(./getvar --arch arm --gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal arch/aarch64/el --gem5 +cat "$(./getvar --arch aarch64 --gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal arch/aarch64/el --gem5 -- --param 'system.have_virtualization = True' +cat "$(./getvar --arch aarch64 --gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal arch/aarch64/el --gem5 -- --param 'system.have_security = True' +cat "$(./getvar --arch aarch64 --gem5 gem5_guest_terminal_file)" +.... + +output: + +.... +19 +26 +19 +1 +2 +3 +.... === How we got some baremetal stuff to work diff --git a/baremetal/arch/aarch64/el.c b/baremetal/arch/aarch64/el.c index be7019d..851c362 100644 --- a/baremetal/arch/aarch64/el.c +++ b/baremetal/arch/aarch64/el.c @@ -1,9 +1,11 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-level */ + #include #include int main(void) { - register uint64_t x0 __asm__ ("x0"); - __asm__ ("mrs x0, CurrentEL;" : : : "%x0"); - printf("%" PRIu64 "\n", x0); + register uint64_t x0 __asm__ ("x0"); + __asm__ ("mrs x0, CurrentEL;" : : : "%x0"); + printf("%" PRIu64 "\n", x0 >> 2); return 0; } diff --git a/baremetal/arch/arm/el.c b/baremetal/arch/arm/el.c new file mode 100644 index 0000000..5944b58 --- /dev/null +++ b/baremetal/arch/arm/el.c @@ -0,0 +1,11 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-level */ + +#include +#include + +int main(void) { + register uint32_t r0 __asm__ ("r0"); + __asm__ ("mrs r0, CPSR" : : : "%r0"); + printf("%" PRIu32 "\n", r0 & 0x1F); + return 0; +}