diff --git a/arch/cortex-m/src/semihosting.rs b/arch/cortex-m/src/semihosting.rs index 71e74d1af1..aa35b526ba 100644 --- a/arch/cortex-m/src/semihosting.rs +++ b/arch/cortex-m/src/semihosting.rs @@ -1,6 +1,6 @@ // Licensed under the Apache License, Version 2.0 or the MIT License. // SPDX-License-Identifier: Apache-2.0 OR MIT -// Copyright Tock Contributors 2022. +// Copyright Tock Contributors 2026. //! Semihosting support for ARM Cortex M Architectures. @@ -11,14 +11,14 @@ /// /// Not exposed outside this module: it's a general, unrestricted semihosting /// interface. External callers should use specific, narrow operations (e.g. -/// [`semihost_terminate`]) that encode specific commands. +/// [`terminate`]) that encode specific commands. /// /// # Safety /// /// Only meaningful when running under a semihosting host (e.g. QEMU started -/// with `-semihosting`, or an attached debug probe); otherwise the `bkpt` -/// instruction traps with no host to service it, so **the caller must not -/// assume this call takes effect**. +/// with `-semihosting`, or an attached debug probe). With no host, the `bkpt` +/// raises a debug exception instead, escalating to a `HardFault` when nothing +/// is configured to take it. /// /// The exact safety requirements depend on `operation`. This method should /// not be called directly with raw parameters. Instead, this module wraps @@ -44,8 +44,8 @@ unsafe fn semihost_command(operation: u32, parameter: u32) -> u32 { // `SYS_WRITEC`) dereference `parameter` as a pointer. // - pure, readonly: not applicable, as above. // - preserves_flags: not documented by the semihosting spec. - // - noreturn: we do fall through (there may be no host to service - // this call at all, e.g. real hardware with no debugger attached). + // - noreturn: we do fall through -- even for `SYS_EXIT`, since a + // semihosting host can choose to resume the target. // - att_syntax: not on arm. // - raw: not required. unsafe { @@ -104,7 +104,7 @@ pub enum SysexitReason { /// /// This nominally halts execution, thus the caller should have the authority to /// halt execution. This *should* only be called on under semihosting (e.g. on -/// a QEMU board); on other targets the `BPKT` will escalate to a `HardFault`. +/// a QEMU board); on other targets the `BKPT` will escalate to a `HardFault`. /// /// This **may not actually halt execution**. A debugger *can* tell semihosting /// to resume the target. Callers must assume this can fall through. diff --git a/boards/README.md b/boards/README.md index a3a1a643fa..ec66ca5e3a 100644 --- a/boards/README.md +++ b/boards/README.md @@ -118,8 +118,8 @@ Virtual hardware platforms that are regularly tested as part of the CI. |-------------------------------------------------------------------|------------------|----------------|------------|-----------------------------|---------------| | [QEMU RISC-V 32 bit `virt` platform](qemu_rv32_virt/README.md) | RISC-V RV32IMAC | QEMU | custom | custom | Yes (7.2.0) | | [QEMU RISC-V 64 bit `virt` platform](qemu_rv64_virt/README.md) | RISC-V RV64IMAC | QEMU | custom | custom | Yes | -| [QEMU ARM MPS2 AN385](qemu_arm_mps2/an385/README.md) | ARM Cortex-M3 | QEMU | custom | custom | Yes (10.2.1) | -| [QEMU ARM MPS2 AN386](qemu_arm_mps2/an386/README.md) | ARM Cortex-M4 | QEMU | custom | custom | Yes (10.2.1) | +| [QEMU ARM MPS2 AN385](qemu_arm_mps2/an385/README.md) | ARM Cortex-M3 | QEMU | custom | custom | Yes | +| [QEMU ARM MPS2 AN386](qemu_arm_mps2/an386/README.md) | ARM Cortex-M4 | QEMU | custom | custom | Yes | | [LiteX on Digilent Arty A-7](litex/arty/README.md) | RISC-V RV32IMC | LiteX+VexRiscV | custom | tockloader (flash-file)[^1] | No | | [Verilated LiteX Simulation](litex/sim/README.md) | RISC-V RV32IMC | LiteX+VexRiscv | custom | tockloader (flash-file)[^1] | No | | [VeeR EL2 simulation](veer_el2_sim/README.md) | RISC-V RV32IMC | VeeR EL2 | custom | custom | No | diff --git a/boards/qemu_arm_mps2/an385/README.md b/boards/qemu_arm_mps2/an385/README.md index a98b340624..f1f251aa9f 100644 --- a/boards/qemu_arm_mps2/an385/README.md +++ b/boards/qemu_arm_mps2/an385/README.md @@ -1,33 +1,17 @@ QEMU ARM MPS2 AN385 (Cortex-M3) Platform ========================================= -This board crate targets QEMU's `mps2-an385` machine: an emulation of ARM's own -"MPS2 + AN385" Cortex-M System Design Kit (CMSDK) reference platform, not a -real vendor chip. This is a purely virtual target for exercising the Cortex-M3 -arch under QEMU, useful for CI and kernel development without access to real -ARM hardware. +QEMU's `mps2-an385` machine, emulating ARM's "MPS2 + AN385" CMSDK reference +platform. Built for `thumbv7m-none-eabi`. -See `mps2_base`'s README for peripheral details. +See the [family README](../mps2_base/README.md) for the peripherals these +boards support and for how to run them. -Running QEMU ------------- - -To run the board in QEMU, `qemu-system-arm` must be started with the -`-machine mps2-an385` argument and `-kernel $TOCK_KERNEL.elf`. - -QEMU loads and executes a Cortex-M ELF directly from its vector table at -address 0; no bootloader or `-bios` indirection is needed. - -`-nographic` suppresses QEMU's graphical window (there is no display device). - -- **`run`**: Start Tock on an emulated QEMU board: +- **`run`**: start Tock under QEMU: ``` $ make run [...] - text data bss dec hex filename - 61484 0 15664 77148 12d5c target/thumbv7m-none-eabi/release/mps2-an385 - Running QEMU emulator version 10.2.1 with - kernel target/thumbv7m-none-eabi/release/mps2-an385.elf To exit type C-a x @@ -37,17 +21,4 @@ address 0; no bootloader or `-bios` indirection is needed. tock$ ``` -Running an application ------------------------ - -- **`run-app`**: Start Tock with one or more apps loaded at - `APP_ADDRESS` (0x00040000): - - ``` - $ make run-app APP=$PATH_TO_APP.tbf - ``` - - To load more than one app at once, concatenate their `.tbf` files (e.g. - `cat app1.tbf app2.tbf > apps.bin`) largest-first: `elf2tab` pads each - `.tbf` to a power-of-two size for MPU alignment, and the loader assumes - that ordering. +- **`run-app`**: start Tock with one or more apps loaded. diff --git a/boards/qemu_arm_mps2/an385/src/main.rs b/boards/qemu_arm_mps2/an385/src/main.rs index 054cc369e1..62b6655f08 100644 --- a/boards/qemu_arm_mps2/an385/src/main.rs +++ b/boards/qemu_arm_mps2/an385/src/main.rs @@ -4,8 +4,7 @@ //! Tock kernel for the QEMU ARM MPS2 AN385 (Cortex-M3) machine. //! -//! This board and `an386` are identical other than their CPU core; -//! all the shared setup lives in `mps2_base`. +//! The shared setup lives in `mps2_base`. #![no_std] #![no_main] diff --git a/boards/qemu_arm_mps2/an386/README.md b/boards/qemu_arm_mps2/an386/README.md index 3ae9f95db8..d8e6da4d4d 100644 --- a/boards/qemu_arm_mps2/an386/README.md +++ b/boards/qemu_arm_mps2/an386/README.md @@ -1,28 +1,20 @@ QEMU ARM MPS2 AN386 (Cortex-M4) Platform ========================================= -This board crate targets QEMU's `mps2-an386` machine: an emulation of ARM's own -"MPS2 + AN386" Cortex-M System Design Kit (CMSDK) reference platform, not a -real vendor chip. This is a purely virtual target for exercising the Cortex-M4 -arch under QEMU, useful for CI and kernel development without access to real -ARM hardware. +QEMU's `mps2-an386` machine, emulating ARM's "MPS2 + AN386" CMSDK reference +platform. Built for `thumbv7em-none-eabi`. -The AN386 does have a FPU available, but this board does not yet exercise that +The AN386 does have an FPU available, but this board does not yet exercise it (i.e., it uses the `cortexm4` architecture crate, not `cortexm4f`). -See `mps2_base`'s README for peripheral details. +See the [family README](../mps2_base/README.md) for the peripherals these +boards support and for how to run them. -Running QEMU ------------- - -- **`run`**: Start Tock on an emulated QEMU board: +- **`run`**: start Tock under QEMU: ``` $ make run [...] - text data bss dec hex filename - 63532 0 15664 79196 1355c target/thumbv7em-none-eabi/release/mps2-an386 - Running QEMU emulator version 10.2.1 with - kernel target/thumbv7em-none-eabi/release/mps2-an386.elf To exit type C-a x @@ -32,5 +24,4 @@ Running QEMU tock$ ``` -- **`run-app`**: same as `mps2-an385`'s (`make run-app - APP=$PATH_TO_APP.tbf`). +- **`run-app`**: start Tock with one or more apps loaded. diff --git a/boards/qemu_arm_mps2/an386/src/main.rs b/boards/qemu_arm_mps2/an386/src/main.rs index cfe984f17c..a798b0da6b 100644 --- a/boards/qemu_arm_mps2/an386/src/main.rs +++ b/boards/qemu_arm_mps2/an386/src/main.rs @@ -4,8 +4,7 @@ //! Tock kernel for the QEMU ARM MPS2 AN386 (Cortex-M4) machine. //! -//! This board and `an385` are identical other than their CPU core; -//! all the shared setup lives in `mps2_base`. +//! The shared setup lives in `mps2_base`. #![no_std] #![no_main] diff --git a/boards/qemu_arm_mps2/mps2_base/README.md b/boards/qemu_arm_mps2/mps2_base/README.md index 4ce852862f..be8bbd5905 100644 --- a/boards/qemu_arm_mps2/mps2_base/README.md +++ b/boards/qemu_arm_mps2/mps2_base/README.md @@ -1,9 +1,11 @@ QEMU ARM MPS2 Family ==================== -ARM provides the `MPS + ANXXX` Cortex-M System Design Kit (CMSDK) reference -platforms for hardware bringup. These are a common peripheral suite coupled with -differing cores. This crate is the shared base platform. +ARM's `MPS + ANXXX` Cortex-M System Design Kit (CMSDK) reference platforms pair +one peripheral suite with a range of cores. QEMU emulates several of them; the +`an385` and `an386` boards beside this crate are purely virtual targets for +exercising the Cortex-M architecture crates under CI, with no real hardware +involved. This crate is the platform code they share. Peripherals ----------- @@ -39,3 +41,18 @@ default is, not meaningful data. The driver therefore always enables `CR1.LBM` a zero-sized placeholder for the same reason GPIO is unavailable: there's no functional GPIO pin to toggle for it, and no real device to select in the first place. + +Running +------- + +`qemu-system-arm` needs `-machine mps2-an38x` and `-kernel $TOCK_KERNEL.elf`; +each board's `make run` supplies both. QEMU executes a Cortex-M ELF directly +from its vector table at address 0, so no bootloader or `-bios` indirection is +needed, and `-nographic` suppresses the graphical window (there is no display +device). + +`make run-app APP=$PATH_TO_APP.tbf` boots with one or more apps loaded at +`APP_ADDRESS` (0x00040000). To load several at once, concatenate their `.tbf` +files largest-first (e.g. `cat app1.tbf app2.tbf > apps.bin`): `elf2tab` pads +each `.tbf` to a power-of-two size for MPU alignment, and the loader assumes +that ordering. diff --git a/boards/qemu_arm_mps2/mps2_base/src/lib.rs b/boards/qemu_arm_mps2/mps2_base/src/lib.rs index 632f003bf2..3babc66aea 100644 --- a/boards/qemu_arm_mps2/mps2_base/src/lib.rs +++ b/boards/qemu_arm_mps2/mps2_base/src/lib.rs @@ -141,9 +141,8 @@ pub struct EarlyInit { /// `static_init!()`, which does not itself guard against being called more /// than once. `C` must be the actual `CortexMVariant` of the CPU this is /// running on. -/// This is in a separate, inline(never) function so that its stack frame is -/// removed when this function returns. Otherwise, the stack space used for -/// these static_inits is wasted. +// inline(never) so this frame, and the stack the `static_init!()`s below use, +// is reclaimed when it returns rather than held for the life of the kernel. #[inline(never)] pub unsafe fn early_init( panic_resources: &'static SingleThreadValue, ProcessPrinterInUse>>, @@ -190,9 +189,8 @@ pub unsafe fn early_init( /// from the same boot, same `C`) -- this allocates more `'static` state and /// starts loading processes from the linker-defined app regions, neither of /// which is safe to repeat. -/// This is in a separate, inline(never) function so that its stack frame is -/// removed when this function returns. Otherwise, the stack space used for -/// these static_inits is wasted. +// inline(never) so this frame, and the stack the `static_init!()`s below use, +// is reclaimed when it returns rather than held for the life of the kernel. #[inline(never)] pub unsafe fn finish_start( early: EarlyInit, diff --git a/chips/qemu_arm_mps2/README.md b/chips/qemu_arm_mps2/README.md index ab870b7d05..d6149ccc8a 100644 --- a/chips/qemu_arm_mps2/README.md +++ b/chips/qemu_arm_mps2/README.md @@ -1,22 +1,25 @@ -# ARM MPS2 "Chip" Family +ARM MPS2 "Chip" Family +====================== The MPS2 is an FPGA board from ARM designed for hardware/software co-design. - -The `mps2-an*` family of boards all use the same peripheral hardware, they just -swap in different CPU cores. The naming scheme refers to the Application Note -that defines the full FPGA image, and pragmatically which CPU core is attached. - -For more details on the platform, see the QEMU documentation on the MPS2 family: +Its `mps2-an*` configurations share a peripheral suite and differ mainly in the +CPU core they attach; the name refers to the ARM Application Note defining the +FPGA image. For more on the platform, see the QEMU documentation: https://www.qemu.org/docs/master/system/arm/mps2.html -As the only difference is the underlying core, and all that amounts to is the -vector table, this crate holds the shared peripherals and each image has its -own crate for the rest: `qemu_arm_mps2_an385` and `qemu_arm_mps2_an386`. +This crate holds the peripherals shared across those images. What differs per +image -- the core and its vector table -- lives in `qemu_arm_mps2_an385` and +`qemu_arm_mps2_an386`. + +QEMU's `hw/arm/mps2.c` implements four of these configurations: -The upstream MPS2 family supports the following configurations (as of Aug 2026): - mps2-an385, a Cortex-M3 - mps2-an386, a Cortex-M4 - - mps2-an500, a Cortex-M7 [not yet implemented here] - - mps2-an505, a Cortex-M33 [not yet implemented here] - - mps2-an511, the "DesignStart" variant of the M3 [not supported here; different hardware mappings] - - mps2-an521, dual Cortex-M33 [not supported here] + - mps2-an500, a Cortex-M7 [not implemented here; PSRAM is at a different + base and there is no block RAM] + - mps2-an511, the "DesignStart" variant of the M3 [not implemented here; + different hardware mappings] + +The TrustZone-enabled MPS2 images (`mps2-an505`, `mps2-an521`) are a separate +QEMU machine family in `hw/arm/mps2-tz.c`, built on the IoTKit/SSE-200 rather +than the peripheral layout above, and are out of scope for this crate. diff --git a/chips/qemu_arm_mps2_an385/README.md b/chips/qemu_arm_mps2_an385/README.md index 7c1a0398a2..417d875d1c 100644 --- a/chips/qemu_arm_mps2_an385/README.md +++ b/chips/qemu_arm_mps2_an385/README.md @@ -1,5 +1,6 @@ ARM MPS2 AN385 chip crate ========================= -Core and vector table for QEMU's `mps2-an385`. Shared peripherals are in -`qemu_arm_mps2`. +The Cortex-M3 and its vector table, for QEMU's `mps2-an385`. See +[`qemu_arm_mps2`](../qemu_arm_mps2/README.md) for the peripherals shared with +the other MPS2 images. diff --git a/chips/qemu_arm_mps2_an386/README.md b/chips/qemu_arm_mps2_an386/README.md index 53daf4a371..e9225b97ea 100644 --- a/chips/qemu_arm_mps2_an386/README.md +++ b/chips/qemu_arm_mps2_an386/README.md @@ -1,5 +1,6 @@ ARM MPS2 AN386 chip crate ========================= -Core and vector table for QEMU's `mps2-an386`. Shared peripherals are in -`qemu_arm_mps2`. +The Cortex-M4 and its vector table, for QEMU's `mps2-an386`. See +[`qemu_arm_mps2`](../qemu_arm_mps2/README.md) for the peripherals shared with +the other MPS2 images.