From 975fe73b2cf2c01a3c74678ba6bcdee32d20afea Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 23 Feb 2026 14:58:31 +0000 Subject: [PATCH 1/4] Reflect the owning team's name change from Cortex-A Team to Arm Team. --- CHANGELOG.md | 2 ++ README.md | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 992a380..5071e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Noted change from Cortex-A Team to Arm Team in README + ## [11.2.0](https://github.com/rust-embedded/aarch64-cpu/compare/v11.1.0...v11.2.0) - 2025-11-29 ### Added diff --git a/README.md b/README.md index 2d6af72..1e94fd8 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,8 @@ additional terms or conditions. ## Code of Conduct Contribution to this crate is organized under the terms of the [Rust Code of -Conduct][CoC], the maintainer of this crate, the [Cortex-A team][team], promises -to intervene to uphold that code of conduct. +Conduct][CoC], the maintainer of this crate, the [Embedded Devices Working +Group's Arm Team][team], promises to intervene to uphold that code of conduct. [CoC]: CODE_OF_CONDUCT.md -[team]: https://github.com/rust-embedded/wg#the-cortex-a-team +[team]: https://github.com/rust-embedded/wg#the-arm-team From 2fa63909c0abb80987f0dd12823272f566eafc71 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 23 Feb 2026 14:59:27 +0000 Subject: [PATCH 2/4] Adds an example program for Armv8-R AArch64 - the 64-bit version of Armv8-R. The example can be executed inside the free Arm Base Architecture Envelope Model (AEM) Fixed Virtual Platform (FVP), available from https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms/Arm%20Architecture%20FVPs. --- .github/workflows/build.yml | 13 ++++-- CHANGELOG.md | 1 + Makefile | 3 ++ examples/armv8-r/.cargo/config.toml | 8 ++++ examples/armv8-r/.gitignore | 1 + examples/armv8-r/Cargo.lock | 37 +++++++++++++++++ examples/armv8-r/Cargo.toml | 13 ++++++ examples/armv8-r/README.md | 59 ++++++++++++++++++++++++++++ examples/armv8-r/build.rs | 17 ++++++++ examples/armv8-r/fvp_cfg.txt | 14 +++++++ examples/armv8-r/memory.ld | 12 ++++++ examples/armv8-r/rust-toolchain.toml | 4 ++ examples/armv8-r/src/bin/hello.rs | 28 +++++++++++++ 13 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 examples/armv8-r/.cargo/config.toml create mode 100644 examples/armv8-r/.gitignore create mode 100644 examples/armv8-r/Cargo.lock create mode 100644 examples/armv8-r/Cargo.toml create mode 100644 examples/armv8-r/README.md create mode 100644 examples/armv8-r/build.rs create mode 100644 examples/armv8-r/fvp_cfg.txt create mode 100644 examples/armv8-r/memory.ld create mode 100644 examples/armv8-r/rust-toolchain.toml create mode 100644 examples/armv8-r/src/bin/hello.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 77d7660..9c5ae3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v1 + uses: actions/checkout@v6 - name: Install Rustup (macOS) run: | @@ -66,8 +66,9 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 2 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v6 - run: cargo fmt -- --check + - run: cd examples/armv8-r && cargo fmt -- --check clippy: name: Clippy @@ -85,6 +86,12 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v6 - run: rustup target add ${{ matrix.target }} - run: cargo clippy --target=${{ matrix.target }} + + armv8r-examples: + name: Build Armv8-R Examples + steps: + - uses: actions/checkout@v6 + - run: cd examples/armv8-r && cargo build --bins diff --git a/CHANGELOG.md b/CHANGELOG.md index 5071e66..ee4da5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Noted change from Cortex-A Team to Arm Team in README +- Added Armv8-R AArch64 example program ## [11.2.0](https://github.com/rust-embedded/aarch64-cpu/compare/v11.1.0...v11.2.0) - 2025-11-29 diff --git a/Makefile b/Makefile index 532bacb..c5dcaef 100644 --- a/Makefile +++ b/Makefile @@ -3,13 +3,16 @@ TARGET := aarch64-unknown-none-softfloat default: cargo build --target $(TARGET) cargo build + cd examples/armv8-r && cargo build clippy: cargo clippy --target $(TARGET) cargo clippy + cd examples/armv8-r && cargo clippy fmt: cargo fmt + cd examples/armv8-r && cargo fmt ready: clippy fmt git pull diff --git a/examples/armv8-r/.cargo/config.toml b/examples/armv8-r/.cargo/config.toml new file mode 100644 index 0000000..4c61b4b --- /dev/null +++ b/examples/armv8-r/.cargo/config.toml @@ -0,0 +1,8 @@ +[build] +target = "aarch64v8r-unknown-none" + +[target.aarch64v8r-unknown-none] +runner = "FVP_BaseR_AEMv8R -f fvp_cfg.txt" + +[unstable] +build-std = ["core", "compiler_builtins"] diff --git a/examples/armv8-r/.gitignore b/examples/armv8-r/.gitignore new file mode 100644 index 0000000..1a5314b --- /dev/null +++ b/examples/armv8-r/.gitignore @@ -0,0 +1 @@ +!/Cargo.lock diff --git a/examples/armv8-r/Cargo.lock b/examples/armv8-r/Cargo.lock new file mode 100644 index 0000000..8a7bae0 --- /dev/null +++ b/examples/armv8-r/Cargo.lock @@ -0,0 +1,37 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aarch64-cpu" +version = "11.2.0" +dependencies = [ + "tock-registers", +] + +[[package]] +name = "aarch64-rt" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b64de198c6b65a80f7b8e799c2c9b957de30ef161d676bbc4b52943313bc4f27" + +[[package]] +name = "armv8-r" +version = "0.0.0" +dependencies = [ + "aarch64-cpu", + "aarch64-rt", + "semihosting", +] + +[[package]] +name = "semihosting" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e896488941756e5de3ee8449495464dbbf2201c85d2d1ace47d4fb81c74b99ec" + +[[package]] +name = "tock-registers" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2d250f87fb3fb6f225c907cf54381509f47b40b74b1d1f12d2dccbc915bdfe" diff --git a/examples/armv8-r/Cargo.toml b/examples/armv8-r/Cargo.toml new file mode 100644 index 0000000..e76f226 --- /dev/null +++ b/examples/armv8-r/Cargo.toml @@ -0,0 +1,13 @@ +[package] +edition = "2024" +name = "armv8-r" +# these examples should not be published to crates.io +publish = false + +[dependencies] +aarch64-rt = { version = "=0.4.0", default-features = false } +aarch64-cpu.path = "../.." +semihosting = { version = "0.1.24", default-features = false, features = [ + "panic-handler", + "stdio", +] } diff --git a/examples/armv8-r/README.md b/examples/armv8-r/README.md new file mode 100644 index 0000000..3fc64d7 --- /dev/null +++ b/examples/armv8-r/README.md @@ -0,0 +1,59 @@ +# Examples for Armv8-R AArch64 systems + +This folder contains example programs for the Armv8-R AArch64 architecture. + +## Dependencies + +* Arm's Fixed Virtual Platform (FVP) Architecture Envelope Model (AEM) Base R, + AKA `FVP_BaseR_AEMv8R` [1] + + The FVP is used to execute the examples. Ensure that it's part of your + `$PATH`. Version 'Fast Models [11.30.27 (Nov 14 2025)]' has been tested. + +* A Rust toolchain that supports the `aarch64v8r-unknown-none` compilation target. + + At the time of writing that target is not yet available on stable so `nightly-2026-02-13` is + specified in `rust-toolchain.toml`. Cargo has been configured to build `libcore` from source, + because this is a Tier 3 target and so not available through `rustup`. + +[1]: https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms/Arm%20Architecture%20FVPs + +## Running the examples + +All commands in this section are meant to be executed using this directory as the working directory. + +### `hello` + +This program uses semihosting to print to the host's console. +It also validates that static variables are initialized before the start of `main`. + +``` console +$ cargo run --bin hello +Hello, world! running from EL2 +static variables: X=0, Y=1 +``` + +## License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](../../LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) +- MIT License ([LICENSE-MIT](../../LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the +work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. + +## Code of Conduct + +Contribution to this crate is organized under the terms of the [Rust Code of +Conduct][CoC], the maintainer of this crate, the [Embedded Devices Working +Group's Arm Team][team], promises to intervene to uphold that code of conduct. + +[CoC]: CODE_OF_CONDUCT.md +[team]: https://github.com/rust-embedded/wg#the-arm-team diff --git a/examples/armv8-r/build.rs b/examples/armv8-r/build.rs new file mode 100644 index 0000000..0e79109 --- /dev/null +++ b/examples/armv8-r/build.rs @@ -0,0 +1,17 @@ +use std::{env, error::Error, fs, path::PathBuf}; + +fn main() -> Result<(), Box> { + let out_dir = PathBuf::from(env::var("OUT_DIR")?); + let script = "memory.ld"; + + // put memory layout (linker script) in the linker search path + fs::copy(script, out_dir.join(script))?; + println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rustc-link-arg=-T{script}"); + println!("cargo:rerun-if-changed={script}"); + + // linker script provided by aarch64-rt + println!("cargo:rustc-link-arg=-Timage.ld"); + + Ok(()) +} diff --git a/examples/armv8-r/fvp_cfg.txt b/examples/armv8-r/fvp_cfg.txt new file mode 100644 index 0000000..3b5919e --- /dev/null +++ b/examples/armv8-r/fvp_cfg.txt @@ -0,0 +1,14 @@ +# disable pop-up GUI +bp.vis.disable_visualisation=1 + +# disable SMP +cluster0.NUM_CORES=1 + +# the FVP defaults to AArch32 (e.g. Cortex-R52); we want AArch64 (e.g. Cortex-R82) +cluster0.has_aarch64=1 + +# required by `cluster0.has_aarch64=1` setting; suppresses warnings +cluster0.gicv3.cpuintf-mmap-access-level = 2 +cluster0.gicv3.SRE-enable-action-on-mmap = 2 +cluster0.gicv3.SRE-EL2-enable-RAO = 1 +cluster0.gicv3.extended-interrupt-range-support = 1 diff --git a/examples/armv8-r/memory.ld b/examples/armv8-r/memory.ld new file mode 100644 index 0000000..8da212f --- /dev/null +++ b/examples/armv8-r/memory.ld @@ -0,0 +1,12 @@ +MEMORY { + /* + NOTE as per the Fast Models Reference 11.28, the BaseR model has the same + memory layout as the Base model but swaps the first and second 2 GiB blocks at + the start of the memory space. Thus DRAM0 starts at address 0x0000_0000 on BaseR, rather + than 0x8000_0000 it appears at on other Base FVPs. see + https://developer.arm.com/documentation/100964/1128/Base-Platform/Base-Platform-memory/BaseR-Platform-memory-map/ + */ + DRAM0 : ORIGIN = 0x00000000, LENGTH = 1 << 31 +} + +REGION_ALIAS("image", DRAM0); diff --git a/examples/armv8-r/rust-toolchain.toml b/examples/armv8-r/rust-toolchain.toml new file mode 100644 index 0000000..d39e113 --- /dev/null +++ b/examples/armv8-r/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2026-02-13" +components = ["llvm-tools", "rust-src", "rustfmt"] +profile = "minimal" diff --git a/examples/armv8-r/src/bin/hello.rs b/examples/armv8-r/src/bin/hello.rs new file mode 100644 index 0000000..fa65ce8 --- /dev/null +++ b/examples/armv8-r/src/bin/hello.rs @@ -0,0 +1,28 @@ +#![no_std] +#![no_main] + +use core::sync::atomic::{self, AtomicU64}; + +use aarch64_cpu::registers::{self, Readable}; +use aarch64_rt::entry; +use semihosting::{println, process}; + +static X: AtomicU64 = AtomicU64::new(0); +static Y: AtomicU64 = AtomicU64::new(1); + +entry!(main); + +fn main(_arg0: u64, _arg1: u64, _arg2: u64, _arg3: u64) -> ! { + let el = registers::CurrentEL.read(registers::CurrentEL::EL); + println!("Hello, world! running from EL{el}"); + + let x = X.fetch_add(1, atomic::Ordering::Relaxed); + let y = Y.fetch_add(1, atomic::Ordering::Relaxed); + println!("static variables: X={x}, Y={y}"); + + // sanity check that static variables are initialized by `aarch64-rt` + assert_eq!(0, x, ".bss was not initialized"); + assert_eq!(1, y, ".data was not initialized"); + + process::exit(0) +} From a76c7c81c05775ee880c7ba6d99c3261a8c03b11 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 23 Feb 2026 14:59:38 +0000 Subject: [PATCH 3/4] Update MIT file copyright line to 2026. --- LICENSE-MIT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE-MIT b/LICENSE-MIT index af7f918..b0f847a 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,6 +1,6 @@ MIT License -Copyright (C) 2018-2023 by the respective authors +Copyright (C) 2018-2026 by the respective authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From ec3277664c0d621ae0aa8d42b13ba2c5fafb3ddf Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 23 Feb 2026 15:04:54 +0000 Subject: [PATCH 4/4] Add missing runs-on: line to CI --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c5ae3e..c0f474c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -91,6 +91,7 @@ jobs: - run: cargo clippy --target=${{ matrix.target }} armv8r-examples: + runs-on: ubuntu-latest name: Build Armv8-R Examples steps: - uses: actions/checkout@v6