This allows us to record information about exceptions using a small
area of memory, and continue with the test so it can verify exceptions
have been taken where expected.

ALT_VECTOR_TABLE is added to switch this on, and altboot.o
is built from boot.S with this flag. Since boot.o is created for multiple
test targets, we have to build a separate object and selectively link this
new altboot.o into particular test binaries.

Signed-off-by: Jim MacArthur <[email protected]>
---
 tests/tcg/aarch64/Makefile.softmmu-target | 11 ++++--
 tests/tcg/aarch64/system/boot.S           | 62 +++++++++++++++++++++++++++++++
 tests/tcg/aarch64/system/boot.h           | 14 +++++++
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/tests/tcg/aarch64/Makefile.softmmu-target 
b/tests/tcg/aarch64/Makefile.softmmu-target
index f7a7d2b800..47b32968fb 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -25,7 +25,7 @@ LDFLAGS=-Wl,-T$(LINK_SCRIPT)
 TESTS+=$(AARCH64_TESTS) $(MULTIARCH_TESTS)
 EXTRA_RUNS+=$(MULTIARCH_RUNS)
 CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
-LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
+LDFLAGS+=-static -nostdlib $(MINILIB_OBJS) -lgcc
 
 config-cc.mak: Makefile
        $(quiet-@)( \
@@ -36,17 +36,20 @@ config-cc.mak: Makefile
 # building head blobs
 .PRECIOUS: $(CRT_OBJS)
 
+altboot.o: $(CRT_PATH)/boot.S
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DALT_VECTOR_TABLE -x 
assembler-with-cpp -Wa,--noexecstack -c $< -o $@
+
 %.o: $(CRT_PATH)/%.S
        $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -Wa,--noexecstack 
-c $< -o $@
 
 # Build and link the tests
 %: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) boot.o
 
 memory: CFLAGS+=-DCHECK_UNALIGNED=1
 
 memory-sve: memory.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) boot.o
 
 memory-sve: CFLAGS+=-DCHECK_UNALIGNED=1 -march=armv8.1-a+sve -O3
 
@@ -107,7 +110,7 @@ QEMU_MTE_ENABLED_MACHINE=-M virt,mte=on -cpu max -display 
none
 QEMU_OPTS_WITH_MTE_ON = $(QEMU_MTE_ENABLED_MACHINE) $(QEMU_BASE_ARGS) -kernel
 mte: CFLAGS+=-march=armv8.5-a+memtag
 mte: mte.S $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) boot.o
 
 run-mte: QEMU_OPTS=$(QEMU_OPTS_WITH_MTE_ON)
 run-mte: mte
diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
index 8bfa4e4efc..57bddda976 100644
--- a/tests/tcg/aarch64/system/boot.S
+++ b/tests/tcg/aarch64/system/boot.S
@@ -60,6 +60,40 @@ curr_sp0_irq:
 curr_sp0_fiq:
 curr_sp0_serror:
 curr_spx_sync:
+#ifdef ALT_VECTOR_TABLE
+       sub     sp, sp, #16
+       stp     x0, x1, [sp, #0]
+       mrs     x0, ESR_EL3
+       lsr     x0, x0, #26
+       and     x0, x0, #0x3f
+       cmp     x0, #37
+       beq     data_fault
+       cmp     x0, #30
+       beq     gpc_fault
+       b       generic_exception
+
+data_fault:
+       mrs     x0, FAR_EL3
+       adrp    x1, exception_log
+       str     x0, [x1]
+       ldr     x0, =0x1001
+       str     x0, [x1, #8]
+       b       skip_return
+gpc_fault:
+       mrs     x0, FAR_EL3
+       adrp    x1, exception_log
+       str     x0, [x1]
+       ldr     x0, =0x1002
+       str     x0, [x1, #8]
+       /* Fall through */
+skip_return:
+       mrs     x0, ELR_EL3
+       add     x0, x0, #4 /* Skip faulting instruction */
+       msr     ELR_EL3, x0
+       ldp     x0, x1, [sp, #0]
+       add     sp, sp, #16
+       eret
+#endif
 curr_spx_irq:
 curr_spx_fiq:
 curr_spx_serror:
@@ -71,6 +105,7 @@ lower_a32_sync:
 lower_a32_irq:
 lower_a32_fiq:
 lower_a32_serror:
+generic_exception:
        adr     x1, .unexp_excp
 exit_msg:
        mov     x0, SYS_WRITE0
@@ -404,6 +439,33 @@ ttb_stage2:
        .space  4096, 0
 
        .align  12
+       .global realms_gpt0
+       /* GPT stage 0 table */
+realms_gpt0:
+       .space 4096, 0
+       .align 17
+       .global realms_gpt1
+       /* GPT stage 1 table, initialised to all 0xFF (full access) */
+realms_gpt1:
+       .space 524288, 0xFF
+#ifdef ALT_VECTOR_TABLE
+       .align 12
+       .global exception_log
+       .global exception_fault_address
+       .global exception_type_code
+exception_log:
+       /*
+        *These fields record details of the last exception, if ALT_VECTOR_TABLE
+        * is defined.
+        */
+exception_fault_address:
+       /* The contents of FAR_EL3 when an exception is taken. */
+       .space 8, 0
+exception_type_code:
+       /* A generic code indicating what type of exception occurred. */
+       .space 8, 0
+#endif
+       .align 12
 system_stack:
        .space 4096, 0
 system_stack_end:
diff --git a/tests/tcg/aarch64/system/boot.h b/tests/tcg/aarch64/system/boot.h
new file mode 100644
index 0000000000..cb9ab6c1b9
--- /dev/null
+++ b/tests/tcg/aarch64/system/boot.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *
+ *
+ * Copyright (c) 2026 Linaro Ltd
+ *
+ */
+
+
+/* Global variables exported in boot.S */
+extern volatile uint64_t exception_fault_address; /* Updated by ISR */
+extern volatile uint64_t exception_type_code; /* Updated by ISR */
+extern uint64_t realms_gpt0[];
+extern uint64_t realms_gpt1[];

-- 
2.43.0


Reply via email to