baremetal: working aarch64 svc example adapted from takeharukato

Not yet generalized for usage on multiple files.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-02-15 00:00:00 +00:00
parent b13b140499
commit 62d2152f39
3 changed files with 259 additions and 3 deletions

View File

@@ -8967,7 +8967,13 @@ less "$(./getvar --arch aarch64 run_dir)/trace.txt"
Output the trace to stdout instead of a file:
....
./run --arch aarch64 --eval 'm5 exit' --emulator gem5 --trace Exec --trace-stdout
./run \
--arch aarch64 \
--emulator gem5 \
--eval 'm5 exit' \
--trace Exec \
--trace-stdout \
;
....
This would produce a lot of output however, so you will likely not want that when tracing a Linux kernel boot instructions. But it can be very convenient for smaller traces.
@@ -11201,6 +11207,14 @@ output:
Setup a handler for `svc`, do an `svc`, and observe that the handler got called and returned:
....
./run --arch aarch64 --baremetal arch/aarch64/svc_asm
....
Source: link:baremetal/arch/aarch64/svc_asm.S[]
TODO: factor out the above, and make it also work on C:
....
./run --arch aarch64 --baremetal arch/aarch64/svc
....
@@ -11261,6 +11275,7 @@ This reset value is defined `UNKNOWN` by <<armarm8>> D10.2.116 "VBAR_EL1, Vector
Bibliography:
* https://github.com/torvalds/linux/blob/v4.20/arch/arm64/kernel/entry.S#L430 this is where the kernel defines the vector table
* https://github.com/dwelch67/qemu_arm_samples/tree/07162ba087111e0df3f44fd857d1b4e82458a56d/swi01
* https://github.com/NienfengYao/armv8-bare-metal/blob/572c6f95880e70aa92fe9fed4b8ad7697082a764/vector.S#L168
* https://stackoverflow.com/questions/51094092/how-to-make-timer-irq-work-on-qemu-machine-virt-cpu-cortex-a57

View File

@@ -1,6 +1,7 @@
/* Test that we can move:
* - set registers
* - read x30 */
* - read x30
*/
.global main
main:
mov x0, #1
@@ -23,6 +24,6 @@ main:
fmov d31, #2.5
/* test-gdb-d31 */
/* Exit required since we meesed up with x30 which is the lr. */
/* Exit required since we messed up with x30 which is the lr. */
mov x0, #0
bl exit

View File

@@ -0,0 +1,240 @@
/* TODO factor it out to make reusable. */
.global main
main:
/* Load the vector table. */
ldr x0, =vector_table
msr vbar_el1, x0
/* Do the svc. */
svc 0
/* Confirm that svc was called and modified myvar. */
ldr x0, myvar
ldr x1, mynewvar
cmp x0, x1
beq 1f
bl common_assert_fail
1:
/* Go home. */
ret
common_trap_handler:
/* Modify myvar as a visible side effect. */
ldr x0, mynewvar
ldr x1, =myvar
str x0, [x1]
ret
myvar:
.quad 0x0
mynewvar:
.quad 0x12346789ABCDEF0
/* .h
*
* Adapted from: https://github.com/takeharukato/sample-tsk-sw/blob/ce7973aa5d46c9eedb58309de43df3b09d4f8d8d/hal/aarch64/vector.S
*/
#define AARCH64_EXC_SYNC_SP0 (0x1)
#define AARCH64_EXC_IRQ_SP0 (0x2)
#define AARCH64_EXC_FIQ_SP0 (0x3)
#define AARCH64_EXC_SERR_SP0 (0x4)
#define AARCH64_EXC_SYNC_SPX (0x11)
#define AARCH64_EXC_IRQ_SPX (0x12)
#define AARCH64_EXC_FIQ_SPX (0x13)
#define AARCH64_EXC_SERR_SPX (0x14)
#define AARCH64_EXC_SYNC_AARCH64 (0x21)
#define AARCH64_EXC_IRQ_AARCH64 (0x22)
#define AARCH64_EXC_FIQ_AARCH64 (0x23)
#define AARCH64_EXC_SERR_AARCH64 (0x24)
#define AARCH64_EXC_SYNC_AARCH32 (0x31)
#define AARCH64_EXC_IRQ_AARCH32 (0x32)
#define AARCH64_EXC_FIQ_AARCH32 (0x33)
#define AARCH64_EXC_SERR_AARCH32 (0x34)
#if !defined(__ASSEMBLER__)
#include <stdint.h>
typedef struct _exception_frame{
uint64_t exc_type;
uint64_t exc_esr;
uint64_t exc_sp;
uint64_t exc_elr;
uint64_t exc_spsr;
uint64_t x0;
uint64_t x1;
uint64_t x2;
uint64_t x3;
uint64_t x4;
uint64_t x5;
uint64_t x6;
uint64_t x7;
uint64_t x8;
uint64_t x9;
uint64_t x10;
uint64_t x11;
uint64_t x12;
uint64_t x13;
uint64_t x14;
uint64_t x15;
uint64_t x16;
uint64_t x17;
uint64_t x18;
uint64_t x19;
uint64_t x20;
uint64_t x21;
uint64_t x22;
uint64_t x23;
uint64_t x24;
uint64_t x25;
uint64_t x26;
uint64_t x27;
uint64_t x28;
uint64_t x29;
uint64_t x30;
} exception_frame;
void common_trap_handler(exception_frame *exception);
#endif
/* .S */
#define EXC_FRAME_SIZE (288) /* sizeof(exception_frame) */
#define EXC_EXC_TYPE_OFFSET (0) /* offsetof(exception_frame, exc_type) */
#define EXC_EXC_ESR_OFFSET (8) /* offsetof(exception_frame, exc_esr) */
#define EXC_EXC_SP_OFFSET (16) /* offsetof(exception_frame, exc_sp) */
#define EXC_EXC_ELR_OFFSET (24) /* offsetof(exception_frame, exc_elr) */
#define EXC_EXC_SPSR_OFFSET (32) /* offsetof(exception_frame, exc_spsr) */
#define BUILD_TRAPFRAME(exc_type) \
stp x29, x30, [sp, -16]!; \
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]!; \
mrs x21, spsr_el1; \
stp x21, x0, [sp, -16]!; \
mrs x21, elr_el1; \
stp xzr, x21, [sp, -16]!; \
mov x21, (exc_type); \
mrs x22, esr_el1; \
stp x21, x22, [sp, -16]!
#define STORE_TRAPED_SP \
mrs x21, sp_el0; \
str x21, [sp, EXC_EXC_SP_OFFSET]
#define CALL_COMMON_TRAP_HANDLER \
mov x0, sp; \
bl common_trap_handler
#define STORE_NESTED_SP \
mov x21, sp; \
add x21, x21, EXC_FRAME_SIZE; \
str x21, [sp, EXC_EXC_SP_OFFSET]
#define RESTORE_TRAPED_SP \
ldr x21, [sp, EXC_EXC_SP_OFFSET]; \
msr sp_el0, x21
#define RESTORE_TRAPFRAME \
add sp, sp, 16; \
ldp x21, x22, [sp], 16; \
msr elr_el1, x22; \
ldp x21, x0, [sp], 16; \
msr spsr_el1, x21; \
ldp x1, x2, [sp], 16; \
ldp x3, x4, [sp], 16; \
ldp x5, x6, [sp], 16; \
ldp x7, x8, [sp], 16; \
ldp x9, x10, [sp], 16; \
ldp x11, x12, [sp], 16; \
ldp x13, x14, [sp], 16; \
ldp x15, x16, [sp], 16; \
ldp x17, x18, [sp], 16; \
ldp x19, x20, [sp], 16; \
ldp x21, x22, [sp], 16; \
ldp x23, x24, [sp], 16; \
ldp x25, x26, [sp], 16; \
ldp x27, x28, [sp], 16; \
ldp x29, x30, [sp], 16; \
eret
#define VECTOR_ENTRY(func_name) \
.align 7; \
b func_name
#define VECTOR_FUNC_ALIGN .align 2
#define VECTOR_FUNC(func_name, func_id) \
VECTOR_FUNC_ALIGN; \
func_name:; \
BUILD_TRAPFRAME(func_id); \
STORE_TRAPED_SP; \
CALL_COMMON_TRAP_HANDLER; \
RESTORE_TRAPED_SP; \
RESTORE_TRAPFRAME
#define VECTOR_FUNC_NESTED(func_name, func_id) \
VECTOR_FUNC_ALIGN; \
func_name:; \
BUILD_TRAPFRAME(func_id); \
STORE_NESTED_SP; \
CALL_COMMON_TRAP_HANDLER; \
RESTORE_TRAPFRAME
.align 11
.global vector_table
vector_table:
VECTOR_ENTRY(_curr_el_sp0_sync)
VECTOR_ENTRY(_curr_el_sp0_irq)
VECTOR_ENTRY(_curr_el_sp0_fiq)
VECTOR_ENTRY(_curr_el_sp0_serror)
VECTOR_ENTRY(_curr_el_spx_sync)
VECTOR_ENTRY(_curr_el_spx_irq)
VECTOR_ENTRY(_curr_el_spx_fiq)
VECTOR_ENTRY(_curr_el_spx_serror)
VECTOR_ENTRY(_lower_el_aarch64_sync)
VECTOR_ENTRY(_lower_el_aarch64_irq)
VECTOR_ENTRY(_lower_el_aarch64_fiq)
VECTOR_ENTRY(_lower_el_aarch64_serror)
VECTOR_ENTRY(_lower_el_aarch32_sync)
VECTOR_ENTRY(_lower_el_aarch32_irq)
VECTOR_ENTRY(_lower_el_aarch32_fiq)
VECTOR_ENTRY(_lower_el_aarch32_serror)
VECTOR_FUNC(_curr_el_sp0_sync, AARCH64_EXC_SYNC_SP0)
VECTOR_FUNC(_curr_el_sp0_irq, AARCH64_EXC_IRQ_SP0)
VECTOR_FUNC(_curr_el_sp0_fiq, AARCH64_EXC_FIQ_SP0)
VECTOR_FUNC(_curr_el_sp0_serror, AARCH64_EXC_SERR_SP0)
VECTOR_FUNC_NESTED(_curr_el_spx_sync, AARCH64_EXC_SYNC_SPX)
VECTOR_FUNC_NESTED(_curr_el_spx_irq, AARCH64_EXC_IRQ_SPX)
VECTOR_FUNC_NESTED(_curr_el_spx_fiq, AARCH64_EXC_FIQ_SPX)
VECTOR_FUNC_NESTED(_curr_el_spx_serror, AARCH64_EXC_SERR_SPX)
VECTOR_FUNC(_lower_el_aarch64_sync, AARCH64_EXC_SYNC_AARCH64)
VECTOR_FUNC(_lower_el_aarch64_irq, AARCH64_EXC_IRQ_AARCH64)
VECTOR_FUNC(_lower_el_aarch64_fiq, AARCH64_EXC_FIQ_AARCH64)
VECTOR_FUNC(_lower_el_aarch64_serror, AARCH64_EXC_SERR_AARCH64)
VECTOR_FUNC(_lower_el_aarch32_sync, AARCH64_EXC_SYNC_AARCH32)
VECTOR_FUNC(_lower_el_aarch32_irq, AARCH64_EXC_IRQ_AARCH32)
VECTOR_FUNC(_lower_el_aarch32_fiq, AARCH64_EXC_FIQ_AARCH32)
VECTOR_FUNC(_lower_el_aarch32_serror, AARCH64_EXC_SERR_AARCH32)