From de05e91689824ac78d1af89de83a46daac2ffde9 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: Thu, 22 Nov 2018 00:00:00 +0000 Subject: [PATCH] baremetal: arm multicore attempt --- README.adoc | 27 +++++++++++++- .../arch/aarch64/no_bootloader/multicore.S | 35 +++++++++++++++++++ .../aarch64/no_bootloader/semihost_exit.S | 2 ++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 baremetal/arch/aarch64/no_bootloader/multicore.S diff --git a/README.adoc b/README.adoc index f68d2e3..5bec407 100644 --- a/README.adoc +++ b/README.adoc @@ -10419,7 +10419,13 @@ help architecture shows ARM version up to `armv6`, so maybe `armv6` is not implemented? -=== ARM exception level +=== ARM baremetal + +In this section we will focus on learning ARM architecture concepts that can only learnt on baremetal setups. + +Userland information can be found at: https://github.com/cirosantilli/arm-assembly-cheat + +==== ARM exception level ARM exception levels are analogous to x86 <>. @@ -10491,6 +10497,25 @@ output: 3 .... +==== ARM multicore + +TODO get working: CPU1 not waking up: + +.... +./run --arch aarch64 --baremetal arch/aarch64/no_bootloader/multicore +.... + +Source: link:baremetal/arch/aarch64/no_bootloader/multicore.S[] + +CPU 0 of this program enters a spinlock loop: it repeatedly checks if a given memory address is `1`. + +So, we need CPU 1 to come to the rescue to that memory address be `1`, otherwise CPU 0 will be stuck there forever. + +Bibliography: + +* https://stackoverflow.com/questions/20055754/arm-start-wakeup-bringup-the-other-cpu-cores-aps-and-pass-execution-start-addre +* https://stackoverflow.com/questions/980999/what-does-multicore-assembly-language-look-like/33651438#33651438 + === How we got some baremetal stuff to work It is nice when thing just work. diff --git a/baremetal/arch/aarch64/no_bootloader/multicore.S b/baremetal/arch/aarch64/no_bootloader/multicore.S new file mode 100644 index 0000000..4494e6c --- /dev/null +++ b/baremetal/arch/aarch64/no_bootloader/multicore.S @@ -0,0 +1,35 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#arm-multicore */ + +.global mystart +mystart: + /* Reset spinlock. */ + mov x0, #0 + ldr x1, =spinlock + str x0, [x1] + + /* Read cpu id into x1. */ + mrs x1, mpidr_el1 + and x1, x1, #3 + cbz x1, 1f + /* Only CPU 1 reaches this point and sets the spinlock. */ + mov x0, #1 + ldr x1, =spinlock + str x0, [x1] + b . +1: + /* Only CPU 0 reaches this point. */ + ldr x0, spinlock + cbz x0, 1b + + /* Semihost exit. */ + mov x1, #0x26 + movk x1, #2, lsl #16 + str x1, [sp,#0] + mov x0, #0 + str x0, [sp,#8] + mov x1, sp + mov w0, #0x18 + hlt 0xf000 + +spinlock: + .skip 8 diff --git a/baremetal/arch/aarch64/no_bootloader/semihost_exit.S b/baremetal/arch/aarch64/no_bootloader/semihost_exit.S index b0e1d88..fd96772 100644 --- a/baremetal/arch/aarch64/no_bootloader/semihost_exit.S +++ b/baremetal/arch/aarch64/no_bootloader/semihost_exit.S @@ -1,3 +1,5 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#semihosting */ + .global mystart mystart: mov x1, #0x26