From f175d81739b98b2ce61a7d71c9975e2392eca63a Mon Sep 17 00:00:00 2001 From: ppannuto-claude Date: Wed, 2 Sep 2026 07:31:52 -0700 Subject: [PATCH] qemu_arm_mps2: cut duplicated documentation "The MPS2 images share peripherals and differ in their core" was stated in eight places across four READMEs and three module docs, and the "purely virtual target, not a real vendor chip" framing in four. State each once, where a reader looking for it would land. The two board READMEs are peers, but an386's was written as a footnote to an385's: it deferred run-app to "same as mps2-an385's" and so never mentioned APP_ADDRESS or the largest-first .tbf packing rule, both of which apply to it identically. Move the shared material -- the QEMU invocation, APP_ADDRESS, packing -- into mps2_base's README, which both boards already point at, and make those pointers actual links; nothing in boards/README.md could reach that file otherwise. What is left per board is what differs: machine, core, target triple, the AN386 FPU note. Also: - an385's sample `make run` output quoted a size line that no longer matches the build, while an386's did; drop the block rather than carry a number that goes stale. - The chips README listed mps2-an505 and mps2-an521 as "not yet implemented here". They are not part of this machine family at all -- they live in QEMU's hw/arm/mps2-tz.c on the IoTKit/SSE-200, with a different peripheral layout. Say so, drop the "as of Aug 2026" stamp, note that an500 also differs in its PSRAM base, and use the same heading style as every other README here. - boards/README.md advertised "Yes (10.2.1)", which is the version this was developed against, not a minimum, in a column whose other entries read as minimums. Neither the true minimum nor CI's pinned build has been tested here, so claim no version. - semihosting.rs said a `bkpt` with no host "traps with no host to service it"; with C_DEBUGEN clear it raises a debug exception that escalates to a HardFault, which terminate()'s own doc already said. Fix that, the reason given for omitting `noreturn`, a broken doc link, a BPKT/BKPT typo, and a 2022 copyright year on a new file. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01L56it8rfV2vkZF9YRN5fa8 --- arch/cortex-m/src/semihosting.rs | 16 ++++----- boards/README.md | 4 +-- boards/qemu_arm_mps2/an385/README.md | 41 ++++------------------- boards/qemu_arm_mps2/an385/src/main.rs | 3 +- boards/qemu_arm_mps2/an386/README.md | 23 ++++--------- boards/qemu_arm_mps2/an386/src/main.rs | 3 +- boards/qemu_arm_mps2/mps2_base/README.md | 23 +++++++++++-- boards/qemu_arm_mps2/mps2_base/src/lib.rs | 10 +++--- chips/qemu_arm_mps2/README.md | 33 +++++++++--------- chips/qemu_arm_mps2_an385/README.md | 5 +-- chips/qemu_arm_mps2_an386/README.md | 5 +-- 11 files changed, 73 insertions(+), 93 deletions(-) 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.