Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions arch/cortex-m/src/semihosting.rs
Original file line number Diff line number Diff line change
@@ -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.

Expand All @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions boards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
41 changes: 6 additions & 35 deletions boards/qemu_arm_mps2/an385/README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
3 changes: 1 addition & 2 deletions boards/qemu_arm_mps2/an385/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
23 changes: 7 additions & 16 deletions boards/qemu_arm_mps2/an386/README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
3 changes: 1 addition & 2 deletions boards/qemu_arm_mps2/an386/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
23 changes: 20 additions & 3 deletions boards/qemu_arm_mps2/mps2_base/README.md
Original file line number Diff line number Diff line change
@@ -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
-----------
Expand Down Expand Up @@ -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.
10 changes: 4 additions & 6 deletions boards/qemu_arm_mps2/mps2_base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,8 @@ pub struct EarlyInit<C: CortexMVariant + 'static> {
/// `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<C: CortexMVariant>(
panic_resources: &'static SingleThreadValue<PanicResources<ChipHw<C>, ProcessPrinterInUse>>,
Expand Down Expand Up @@ -190,9 +189,8 @@ pub unsafe fn early_init<C: CortexMVariant>(
/// 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<C: CortexMVariant>(
early: EarlyInit<C>,
Expand Down
33 changes: 18 additions & 15 deletions chips/qemu_arm_mps2/README.md
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 3 additions & 2 deletions chips/qemu_arm_mps2_an385/README.md
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 3 additions & 2 deletions chips/qemu_arm_mps2_an386/README.md
Original file line number Diff line number Diff line change
@@ -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.
Loading