Skip to content
Open
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
56 changes: 0 additions & 56 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,56 +0,0 @@
[target.armv8r-none-eabihf]
# Note, this requires QEMU 9 or higher
runner = "qemu-system-arm -machine mps3-an536 -cpu cortex-r52 -semihosting -nographic -audio none -kernel"

[target.thumbv8r-none-eabihf]
# Note, this requires QEMU 9 or higher
runner = "qemu-system-arm -machine mps3-an536 -cpu cortex-r52 -semihosting -nographic -audio none -kernel"

[target.armv7r-none-eabihf]
runner = "qemu-system-arm -machine versatileab -cpu cortex-r5f -semihosting -nographic -audio none -kernel"

[target.thumbv7r-none-eabihf]
runner = "qemu-system-arm -machine versatileab -cpu cortex-r5f -semihosting -nographic -audio none -kernel"

[target.armv7r-none-eabi]
# change '-mcpu=cortex-r5' to '-mcpu=cortex-r5f' if you use eabi-fpu feature, otherwise
# qemu-system-arm will lock up
runner = "qemu-system-arm -machine versatileab -cpu cortex-r5 -semihosting -nographic -audio none -kernel"

[target.thumbv7r-none-eabi]
# change '-mcpu=cortex-r5' to '-mcpu=cortex-r5f' if you use eabi-fpu feature, otherwise
# qemu-system-arm will lock up
runner = "qemu-system-arm -machine versatileab -cpu cortex-r5 -semihosting -nographic -audio none -kernel"

[target.armv7a-none-eabihf]
runner = "qemu-system-arm -machine versatileab -cpu cortex-a8 -semihosting -nographic -audio none -kernel"

[target.thumbv7a-none-eabihf]
runner = "qemu-system-arm -machine versatileab -cpu cortex-a8 -semihosting -nographic -audio none -kernel"

[target.armv7a-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu cortex-a8 -semihosting -nographic -audio none -kernel"

[target.thumbv7a-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu cortex-a8 -semihosting -nographic -audio none -kernel"

[target.armv6-none-eabihf]
runner = "qemu-system-arm -machine versatileab -cpu arm1176 -semihosting -nographic -audio none -kernel"

[target.armv6-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm1176 -semihosting -nographic -audio none -kernel"

[target.thumbv6-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm1176 -semihosting -nographic -audio none -kernel"

[target.armv5te-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"

[target.thumbv5te-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"

[target.armv4t-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"

[target.thumbv4t-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"
46 changes: 46 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,50 @@ jobs:
export PATH=/opt/qemu/bin:$PATH
just test-qemu-v8r
# Run some SMP programs in QEMU 9 for Armv8-R
# These tests build with nightly as pinned by the rust-toolchain.toml file, because they include Tier 3 targets
test-qemu-v8r-smp:
runs-on: ubuntu-24.04
needs: [build-all]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Just
uses: taiki-e/install-action@just
- name: Install Dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64
- name: Install custom QEMU into /opt
run: |
curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C /
- name: Run tests in QEMU
run: |
export PATH=/opt/qemu/bin:$PATH
just test-qemu-v8r-smp
# Run some EL2 programs in QEMU 9 for Armv8-R
# These tests build with nightly as pinned by the rust-toolchain.toml file, because they include Tier 3 targets
test-qemu-v8r-el2:
runs-on: ubuntu-24.04
needs: [build-all]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Just
uses: taiki-e/install-action@just
- name: Install Dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64
- name: Install custom QEMU into /opt
run: |
curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C /
- name: Run tests in QEMU
run: |
export PATH=/opt/qemu/bin:$PATH
just test-qemu-v8r-el2
# Gather all the above QEMU jobs together for the purposes of getting an overall pass-fail
test-qemu-all:
runs-on: ubuntu-24.04
Expand All @@ -417,6 +461,8 @@ jobs:
test-qemu-v7a,
test-qemu-v7r,
test-qemu-v8r,
test-qemu-v8r-smp,
test-qemu-v8r-el2,
]
steps:
- run: /bin/true
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
target
examples/mps3-an536/target
examples/mps3-an536/target-d32
examples/mps3-an536-smp/target
examples/mps3-an536-smp/target-d32
examples/mps3-an536-el2/target
examples/mps3-an536-el2/target-d32
examples/versatileab/target
examples/versatileab/target-d32
Cargo.lock
Expand Down
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
"rust-analyzer.checkOnSave": true,
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
"./arm-targets/Cargo.toml",
"examples/versatileab/Cargo.toml",
"examples/mps3-an536/Cargo.toml"
"examples/mps3-an536/Cargo.toml",
"examples/mps3-an536-smp/Cargo.toml",
"examples/mps3-an536-el2/Cargo.toml"
]
}
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ exclude = [
"arm-targets",
"examples/versatileab",
"examples/mps3-an536",
"examples/mps3-an536-smp",
"examples/mps3-an536-el2",
]
members = [
"aarch32-cpu",
Expand Down
4 changes: 2 additions & 2 deletions aarch32-cpu/src/generic_timer/el2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{El1PhysicalTimer, El1VirtualTimer, GenericTimer};
pub struct El2PhysicalTimer(El1PhysicalTimer);

impl El2PhysicalTimer {
/// Create an EL1 Generic Timer handle
/// Create an EL2 Physical Timer handle
///
/// # Safety
///
Expand Down Expand Up @@ -79,7 +79,7 @@ impl GenericTimer for El2PhysicalTimer {
pub struct El2VirtualTimer(El1VirtualTimer);

impl El2VirtualTimer {
/// Create an EL1 Generic Timer handle
/// Create an EL2 Generic Timer handle
///
/// # Safety
///
Expand Down
39 changes: 29 additions & 10 deletions aarch32-cpu/src/register/armv8r/hcptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@
use crate::register::{SysReg, SysRegRead, SysRegWrite};

/// HCPTR (*Hyp Architectural Feature Trap Register*)
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Hcptr(pub u32);
pub struct Hcptr {
/// TCPAC - Traps EL1 accesses to the CPACR to Hyp mode
#[bit(31, rw)]
tcpac: bool,
/// TTA - Traps System register accesses to all implemented trace registers to Hyp mode
#[bit(20, rw)]
tta: bool,
/// TASE - Traps execution of Advanced SIMD instructions to Hyp mode when the value of HCPTR.TCP10 is 0.
#[bit(15, rw)]
tase: bool,
/// TCP - Trap accesses to Advanced SIMD and floating-point functionality to Hyp mode
#[bit(10, rw)]
tcp: bool,
}

impl SysReg for Hcptr {
const CP: u32 = 15;
Expand All @@ -22,7 +34,18 @@ impl Hcptr {
#[inline]
/// Reads HCPTR (*Hyp Architectural Feature Trap Register*)
pub fn read() -> Hcptr {
unsafe { Self(<Self as SysRegRead>::read_raw()) }
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
}

/// Modify HCPTR (*Hyp Architectural Feature Trap Register*)
#[inline]
pub fn modify<F>(f: F)
where
F: FnOnce(&mut Self),
{
let mut value = Self::read();
f(&mut value);
Self::write(value);
}
}

Expand All @@ -31,13 +54,9 @@ impl crate::register::SysRegWrite for Hcptr {}
impl Hcptr {
#[inline]
/// Writes HCPTR (*Hyp Architectural Feature Trap Register*)
///
/// # Safety
///
/// Ensure that this value is appropriate for this register
pub unsafe fn write(value: Self) {
pub fn write(value: Self) {
unsafe {
<Self as SysRegWrite>::write_raw(value.0);
<Self as SysRegWrite>::write_raw(value.raw_value());
}
}
}
121 changes: 112 additions & 9 deletions aarch32-cpu/src/register/armv8r/hcr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,106 @@
use crate::register::{SysReg, SysRegRead, SysRegWrite};

/// HCR (*Hyp Configuration Register*)
#[derive(Debug, Copy, Clone)]
#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Hcr {
/// TCPAC - Traps EL1 accesses to the CPACR to Hyp mode
#[bit(31, rw)]
tcpac: bool,
/// TRVM - Trap Reads of Memory controls
#[bit(30, rw)]
trvm: bool,
/// HCD - HVC instruction disable
#[bit(29, rw)]
hcd: bool,
/// TGE - Trap General Exceptions from EL0
#[bit(27, rw)]
tge: bool,
/// TVM - Trap Memory controls
#[bit(26, rw)]
tvm: bool,
/// TPU - Trap cache maintenance instructions that operate to the Point of Unification
#[bit(24, rw)]
tpu: bool,
/// TPC - Trap data or unified cache maintenance instructions that operate to the Point of Coherency
#[bit(23, rw)]
tpc: bool,
/// TSW - Trap data or unified cache maintenance instructions that operate by Set/Way
#[bit(22, rw)]
tsw: bool,
/// TAC - Trap Auxiliary Control Registers
#[bit(21, rw)]
tac: bool,
/// TIDCP - Trap IMPLEMENTATION DEFINED functionality
#[bit(20, rw)]
tidcp: bool,
/// TID3 - Trap ID group 3
#[bit(18, rw)]
tid3: bool,
/// TID2 - Trap ID group 2
#[bit(17, rw)]
tid2: bool,
/// TID1 - Trap ID group 1
#[bit(16, rw)]
tid1: bool,
/// TID0 - Trap ID group 0
#[bit(15, rw)]
tid0: bool,
/// TWE - Traps EL0 and EL1 execution of WFE instructions to Hyp mode
#[bit(14, rw)]
twe: bool,
/// TWI - Traps EL0 and EL1 execution of WFI instructions to Hyp mode
#[bit(13, rw)]
twi: bool,
/// DC - Default Cacheability
#[bit(12, rw)]
dc: bool,
/// BSU - Barrier Shareability upgrade.
#[bits(10..=11, rw)]
bsu: Bsu,
/// FB - Force broadcast
#[bit(9, rw)]
fb: bool,
/// VA - Virtual SError interrupt exception
#[bit(8, rw)]
va: bool,
/// VI - Virtual IRQ exception
#[bit(7, rw)]
vi: bool,
/// VF - Virtual FIQ exception
#[bit(6, rw)]
vf: bool,
/// AMO - SError interrupt Mask Override
#[bit(5, rw)]
amo: bool,
/// IMO - IRQ Mask Override
#[bit(4, rw)]
imo: bool,
/// FMO - FIQ Mask Override
#[bit(3, rw)]
fmo: bool,
/// SWIO - Set/Way Invalidation Override
#[bit(1, rw)]
swio: bool,
/// VM - Virtualization enable
#[bit(0, rw)]
vm: bool,
}

/// Barrier Shareability upgrade
///
/// This field determines the minimum Shareability domain that is applied to any
/// barrier instruction executed from EL1 or EL0
#[bitbybit::bitenum(u2, exhaustive = true)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Hcr(pub u32);
#[derive(Debug, PartialEq, Eq)]
pub enum Bsu {
NoEffect = 0b00,
InnerShareable = 0b01,
OuterShareable = 0b10,
FullSystem = 0b11,
}

impl SysReg for Hcr {
const CP: u32 = 15;
Expand All @@ -22,7 +118,7 @@ impl Hcr {
#[inline]
/// Reads HCR (*Hyp Configuration Register*)
pub fn read() -> Hcr {
unsafe { Self(<Self as SysRegRead>::read_raw()) }
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
}
}

Expand All @@ -31,13 +127,20 @@ impl crate::register::SysRegWrite for Hcr {}
impl Hcr {
#[inline]
/// Writes HCR (*Hyp Configuration Register*)
///
/// # Safety
///
/// Ensure that this value is appropriate for this register
pub unsafe fn write(value: Self) {
pub fn write(value: Self) {
unsafe {
<Self as SysRegWrite>::write_raw(value.0);
<Self as SysRegWrite>::write_raw(value.raw_value());
}
}

#[inline]
/// Modify HCR (*Hyp Configuration Register*)
pub fn modify<F>(f: F)
where
F: FnOnce(&mut Self),
{
let mut value = Self::read();
f(&mut value);
Self::write(value);
}
}
Loading