diff --git a/README.adoc b/README.adoc index f84bd19..1ca5979 100644 --- a/README.adoc +++ b/README.adoc @@ -13376,14 +13376,14 @@ ARM exception levels are analogous to x86 <>. Print the EL at the beginning of a baremetal simulation: .... -./run --arch arm --baremetal baremetal/arch/arm/el.c -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c .... Sources: -* link:baremetal/arch/arm/el.c[] -* link:baremetal/arch/aarch64/el.c[] +* link:baremetal/arch/arm/dump_regs.c[] +* link:baremetal/arch/aarch64/dump_regs.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 @@ -13392,53 +13392,53 @@ The lower ELs are not mandated by the architecture, and can be controlled throug 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 baremetal/arch/arm/el.c -./run --arch arm --baremetal baremetal/arch/arm/el.c -- -machine virtualization=on -./run --arch arm --baremetal baremetal/arch/arm/el.c -- -machine secure=on -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c -- -machine virtualization=on -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c -- -machine secure=on +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c | grep CPSR.M +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c -- -machine virtualization=on | grep CPSR.M +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c -- -machine secure=on | grep CPSR.M +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c | grep CurrentEL.EL +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c -- -machine virtualization=on | grep CurrentEL.EL +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c -- -machine secure=on | grep CurrentEL.EL .... outputs respectively: .... -19 -19 -19 -1 -2 -3 +CPSR.M 0x3 +CPSR.M 0x3 +CPSR.M 0x3 +CurrentEL.EL 0x1 +CurrentEL.EL 0x2 +CurrentEL.EL 0x3 .... -TODO: why is `arm` stuck at `19` which equals Supervisor mode? +TODO: why is arm `CPSR.M` stuck at `0x3` which equals Supervisor mode? In gem5, you can configure the lowest EL with: .... -./run --arch arm --baremetal baremeta/arch/arm/el.c --emulator gem5 -cat "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" -./run --arch arm --baremetal baremetal/arch/arm/el.c --emulator gem5 -- --param 'system.have_virtualization = True' -cat "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" -./run --arch arm --baremetal baremetal/arch/arm/el.c --emulator gem5 -- --param 'system.have_security = True' -cat "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c --emulator gem5 -cat "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c --emulator gem5 -- --param 'system.have_virtualization = True' -cat "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" -./run --arch aarch64 --baremetal baremetal/arch/aarch64/el.c --emulator gem5 -- --param 'system.have_security = True' -cat "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c --emulator gem5 +grep CPSR.M "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c --emulator gem5 -- --param 'system.have_virtualization = True' +grep CPSR.M "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" +./run --arch arm --baremetal baremetal/arch/arm/dump_regs.c --emulator gem5 -- --param 'system.have_security = True' +grep CPSR.M "$(./getvar --arch arm --emulator gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c --emulator gem5 +grep CurrentEL.EL "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c --emulator gem5 -- --param 'system.have_virtualization = True' +grep CurrentEL.EL "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" +./run --arch aarch64 --baremetal baremetal/arch/aarch64/dump_regs.c --emulator gem5 -- --param 'system.have_security = True' +grep CurrentEL.EL "$(./getvar --arch aarch64 --emulator gem5 gem5_guest_terminal_file)" .... output: .... -19 -26 -19 -1 -2 -3 +CPSR.M 0x3 +CPSR.M 0x3 +CPSR.M 0x3 +CurrentEL.EL 0x1 +CurrentEL.EL 0x2 +CurrentEL.EL 0x3 .... ==== svc diff --git a/baremetal/arch/aarch64/dump_regs.c b/baremetal/arch/aarch64/dump_regs.c index 3aa8fc8..9846465 100644 --- a/baremetal/arch/aarch64/dump_regs.c +++ b/baremetal/arch/aarch64/dump_regs.c @@ -6,6 +6,13 @@ int main(void) { uint32_t sctlr_el1; __asm__ ("mrs %0, sctlr_el1" : "=r" (sctlr_el1) : :); - printf("sctlr_el1 0x%" PRIx32 "\n", sctlr_el1); + printf("SCTLR_EL1 0x%" PRIX32 "\n", sctlr_el1); + printf("SCTLR_EL1.A 0x%" PRIX32 "\n", (sctlr_el1 >> 1) & 1); + + uint64_t CurrentEL; + __asm__ ("mrs %0, CurrentEL;" : "=r" (CurrentEL) : :); + printf("CurrentEL 0x%" PRIX64 "\n", CurrentEL); + /* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-levels */ + printf("CurrentEL.EL 0x%" PRIX64 "\n", CurrentEL >> 2); return 0; } diff --git a/baremetal/arch/aarch64/el.c b/baremetal/arch/aarch64/el.c deleted file mode 100644 index 4d2b201..0000000 --- a/baremetal/arch/aarch64/el.c +++ /dev/null @@ -1,11 +0,0 @@ -/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-levels */ - -#include -#include - -int main(void) { - uint64_t el; - __asm__ ("mrs %0, CurrentEL;" : "=r" (el) : :); - printf("%" PRIu64 "\n", el >> 2); - return 0; -} diff --git a/baremetal/arch/arm/dump_regs.c b/baremetal/arch/arm/dump_regs.c index acafb18..b0ab2b2 100644 --- a/baremetal/arch/arm/dump_regs.c +++ b/baremetal/arch/arm/dump_regs.c @@ -4,12 +4,14 @@ int main(void) { uint32_t cpsr; __asm__ ("mrs %0, cpsr" : "=r" (cpsr) : :); - printf("cpsr %" PRIx32 "\n", cpsr); + printf("CPSR 0x%" PRIX32 "\n", cpsr); + /* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-levels */ + printf("CPSR.M 0x%" PRIX32 "\n", cpsr & 0xF); /* TODO this is blowing up an exception, how to I read from it? */ /*uint32_t mvfr1;*/ /*__asm__ ("vmrs %0, mvfr1" : "=r" (mvfr1) : :);*/ - /*printf("mvfr1 %" PRIx32 "\n", mvfr1);*/ + /*printf("MVFR1 0x%" PRIX32 "\n", mvfr1);*/ return 0; } diff --git a/baremetal/arch/arm/el.c b/baremetal/arch/arm/el.c deleted file mode 100644 index 733ec59..0000000 --- a/baremetal/arch/arm/el.c +++ /dev/null @@ -1,11 +0,0 @@ -/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-exception-levels */ - -#include -#include - -int main(void) { - uint32_t cpsr; - __asm__ ("mrs %0, CPSR" : "=r" (cpsr) : :); - printf("%" PRIu32 "\n", cpsr & 0x1F); - return 0; -}