Build Cortex-M0+ guest programs from assembly sources to exercise the minimal Pico boot path, UART0 output, and the Cortex-M0+ MPU. Keep the vector table at the XIP base so these tests match the initial synthetic boot stub without depending on boot2 or the later flash controller model.
Signed-off-by: gilles grimaud <[email protected]> --- MAINTAINERS | 1 + tests/tcg/arm/system/meson.build | 14 +++++++ tests/tcg/arm/system/rp2040-boot.S | 30 +++++++++++++++ tests/tcg/arm/system/rp2040-minimal.ld | 40 +++++++++++++++++++ tests/tcg/arm/system/rp2040-uart.S | 53 ++++++++++++++++++++++++++ tests/tcg/arm/system/rp2040-uart.ref | 1 + 6 files changed, 139 insertions(+) create mode 100644 tests/tcg/arm/system/rp2040-boot.S create mode 100644 tests/tcg/arm/system/rp2040-minimal.ld create mode 100644 tests/tcg/arm/system/rp2040-uart.S create mode 100644 tests/tcg/arm/system/rp2040-uart.ref diff --git a/MAINTAINERS b/MAINTAINERS index caee8aa0cc..a03fb0575c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1033,6 +1033,7 @@ S: Maintained F: hw/*/rp2040* F: include/hw/*/rp2040* F: hw/arm/raspi_pico.c +F: tests/tcg/arm/system/rp2040* Real View M: Peter Maydell <[email protected]> diff --git a/tests/tcg/arm/system/meson.build b/tests/tcg/arm/system/meson.build index e92a83a8d5..42e7614a11 100644 --- a/tests/tcg/arm/system/meson.build +++ b/tests/tcg/arm/system/meson.build @@ -15,6 +15,11 @@ qemu_base_args = ['-display', 'none', '-semihosting-config', 'enable=on', '-kernel'] qemu_def_args = ['-M', 'virt', '-cpu', 'max', qemu_base_args] +rp2040_cflags = ['-mcpu=cortex-m0plus', '-mthumb', '-mfloat-abi=soft', + '-nostdlib', '-Wl,--build-id=none', + '-T', files('rp2040-minimal.ld')] +rp2040_qemu_args = ['-M', 'raspi-pico', '-monitor', 'none', + qemu_base_args] # Multi arch tests multi_src = [] @@ -51,6 +56,15 @@ tests += { '-T', files('test-armv6m-undef.ld')], 'qemu_args': ['-M', 'microbit', qemu_base_args], }, + 'rp2040-boot.S': { + 'cflags': rp2040_cflags, + 'qemu_args': rp2040_qemu_args, + }, + 'rp2040-uart.S': { + 'cflags': rp2040_cflags, + 'qemu_args': ['-serial', 'stdio', rp2040_qemu_args], + 'expected_output': 'rp2040-uart.ref', + }, 'semiconsole.c': { 'cflags': cflags, 'qemu_args': ['-serial', 'none', '-chardev', 'stdio,mux=on,id=stdio0', diff --git a/tests/tcg/arm/system/rp2040-boot.S b/tests/tcg/arm/system/rp2040-boot.S new file mode 100644 index 0000000000..0537a54d44 --- /dev/null +++ b/tests/tcg/arm/system/rp2040-boot.S @@ -0,0 +1,30 @@ +/* + * Raspberry Pi Pico boot smoke test. + * + * Copyright 2026 Gilles Grimaud + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +.syntax unified +.cpu cortex-m0plus +.thumb + +#define SRAM_END 0x20042000 +#define SYS_EXIT 0x18 +#define ADP_STOPPED_APPLICATION_EXIT 0x20026 + +.section .vectors, "a", %progbits +vector_table: + .word SRAM_END + .word reset_handler + 1 + +.section .text, "ax", %progbits +.thumb_func +.global reset_handler +reset_handler: + movs r0, SYS_EXIT + ldr r1, =ADP_STOPPED_APPLICATION_EXIT + bkpt 0xab + +1: + b 1b diff --git a/tests/tcg/arm/system/rp2040-minimal.ld b/tests/tcg/arm/system/rp2040-minimal.ld new file mode 100644 index 0000000000..ebfbac8cf2 --- /dev/null +++ b/tests/tcg/arm/system/rp2040-minimal.ld @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +ENTRY(reset_handler) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 2M + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 264K +} + +SECTIONS +{ + .vectors ORIGIN(FLASH) : + { + KEEP(*(.vectors)) + } > FLASH + + .text : + { + *(.text*) + *(.rodata*) + } > FLASH + + .data : + { + *(.data*) + } > SRAM AT > FLASH + + .bss (NOLOAD) : + { + *(.bss*) + *(COMMON) + } > SRAM + + /DISCARD/ : + { + *(.ARM.attributes) + *(.comment) + } +} diff --git a/tests/tcg/arm/system/rp2040-uart.S b/tests/tcg/arm/system/rp2040-uart.S new file mode 100644 index 0000000000..bdb58cc7f2 --- /dev/null +++ b/tests/tcg/arm/system/rp2040-uart.S @@ -0,0 +1,53 @@ +/* + * Raspberry Pi Pico UART boot smoke test. + * + * Copyright 2026 Gilles Grimaud + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +.syntax unified +.cpu cortex-m0plus +.thumb + +#define SRAM_END 0x20042000 +#define UART0_DR 0x40034000 +#define SYS_EXIT 0x18 +#define ADP_STOPPED_APPLICATION_EXIT 0x20026 + +.section .vectors, "a", %progbits +vector_table: + .word SRAM_END + .word reset_handler + 1 + .word default_handler + 1 + .word default_handler + 1 + +.section .text, "ax", %progbits +.thumb_func +.global reset_handler +reset_handler: + ldr r0, =UART0_DR + ldr r1, =message + +1: + ldrb r2, [r1] + cmp r2, 0 + beq 2f + str r2, [r0] + adds r1, 1 + b 1b + +2: + movs r0, SYS_EXIT + ldr r1, =ADP_STOPPED_APPLICATION_EXIT + bkpt 0xab + +3: + b 3b + +.thumb_func +default_handler: + b default_handler + +.section .rodata, "a", %progbits +message: + .asciz "PICO TCG UART OK\n" diff --git a/tests/tcg/arm/system/rp2040-uart.ref b/tests/tcg/arm/system/rp2040-uart.ref new file mode 100644 index 0000000000..1ef16e8299 --- /dev/null +++ b/tests/tcg/arm/system/rp2040-uart.ref @@ -0,0 +1 @@ +PICO TCG UART OK -- 2.55.0
