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
31 changes: 29 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,54 @@
# 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.armv4t-none-eabi]
[target.thumbv5te-none-eabi]
runner = "qemu-system-arm -machine versatileab -cpu arm926 -semihosting -nographic -audio none -kernel"

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

[target.thumbv4t-none-eabi]
Expand Down
37 changes: 32 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,34 @@ jobs:
run: |
just build-tier2 ${{ matrix.target }}

# These targets need build-std, and have no atomics
# These targets need build-std
build-tier3:
runs-on: ubuntu-24.04
needs: setup
strategy:
matrix:
target:
- thumbv7r-none-eabi
- thumbv7r-none-eabihf
- thumbv7a-none-eabi
- thumbv7a-none-eabihf
- thumbv8r-none-eabihf
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Just
uses: taiki-e/install-action@just
- name: Install Rust
run: |
rustup install nightly-2026-01-26
rustup component add rust-src --toolchain nightly-2026-01-26
rustup default nightly-2026-01-26
- name: Build
run: |
just build-tier3 ${{ matrix.target }}

# These targets need build-std, and have no atomics so we have to skip
# the 'critical-section-multi-core' feature
build-tier3-no-atomics:
runs-on: ubuntu-24.04
needs: setup
Expand All @@ -62,9 +89,9 @@ jobs:
uses: taiki-e/install-action@just
- name: Install Rust
run: |
rustup install nightly-2025-10-29
rustup component add rust-src --toolchain nightly-2025-10-29
rustup default nightly-2025-10-29
rustup install nightly-2026-01-26
rustup component add rust-src --toolchain nightly-2026-01-26
rustup default nightly-2026-01-26
- name: Build
run: |
just build-tier3-no-atomics ${{ matrix.target }}
Expand Down Expand Up @@ -92,7 +119,7 @@ jobs:
# Gather all the above build jobs together for the purposes of getting an overall pass-fail
build-all:
runs-on: ubuntu-24.04
needs: [build-tier2, build-tier3-no-atomics, build-arm-targets]
needs: [build-tier2, build-tier3-no-atomics, build-tier3, build-arm-targets]
steps:
- run: /bin/true

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ examples/mps3-an536/target-d32
examples/versatileab/target
examples/versatileab/target-d32
Cargo.lock
**/.DS_Store

12 changes: 10 additions & 2 deletions aarch32-cpu/src/register/cpsr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ impl Cpsr {
/// `thumb*` targets, as Thumb-1 cannot do an MRS.
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(
any(arm_architecture = "v4t", arm_architecture = "v5te"),
any(
arm_architecture = "v4t",
arm_architecture = "v5te",
arm_architecture = "v6"
),
instruction_set(arm::a32)
)]
pub fn read() -> Self {
Expand Down Expand Up @@ -108,7 +112,11 @@ impl Cpsr {
/// `thumb*` targets, as Thumb-1 cannot do an MSR.
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(
any(arm_architecture = "v4t", arm_architecture = "v5te"),
any(
arm_architecture = "v4t",
arm_architecture = "v5te",
arm_architecture = "v6"
),
instruction_set(arm::a32)
)]
pub unsafe fn write(_value: Self) {
Expand Down
12 changes: 10 additions & 2 deletions aarch32-cpu/src/register/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,11 @@ pub trait SysRegRead: SysReg {
/// may have side-effects.
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(
any(arm_architecture = "v4t", arm_architecture = "v5te"),
any(
arm_architecture = "v4t",
arm_architecture = "v5te",
arm_architecture = "v6"
),
instruction_set(arm::a32)
)]
unsafe fn read_raw() -> u32 {
Expand Down Expand Up @@ -261,7 +265,11 @@ pub trait SysRegWrite: SysReg {
/// writing valid data here.
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(
any(arm_architecture = "v4t", arm_architecture = "v5te"),
any(
arm_architecture = "v4t",
arm_architecture = "v5te",
arm_architecture = "v6"
),
instruction_set(arm::a32)
)]
unsafe fn write_raw(_value: u32) {
Expand Down
12 changes: 8 additions & 4 deletions aarch32-rt/src/arch_v7/svc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ core::arch::global_asm!(
r#"
mrs r0, spsr // Load processor status that was banked on entry
tst r0, {t_bit} // SVC occurred from Thumb state?
ldrhne r0, [lr,#-2] // Yes: Load halfword and...
bicne r0, r0, #0xFF00 // ...extract comment field
ldreq r0, [lr,#-4] // No: Load word and...
biceq r0, r0, #0xFF000000 // ...extract comment field
beq 1f
ldrh r0, [lr,#-2] // Yes: Load halfword and...
bic r0, r0, #0xFF00 // ...extract comment field
b 2f
1:
ldr r0, [lr,#-4] // No: Load word and...
bic r0, r0, #0xFF000000 // ...extract comment field
2:
// r0 now contains SVC number
bl _svc_handler
"#,
Expand Down
44 changes: 40 additions & 4 deletions arm-targets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,21 @@ impl Arch {
Some(Arch::Armv8MBase)
} else if target.starts_with("thumbv8m.main-") {
Some(Arch::Armv8MMain)
} else if target.starts_with("armv7r-") || target.starts_with("armebv7r") {
} else if target.starts_with("armv7r-")
|| target.starts_with("armebv7r-")
|| target.starts_with("thumbv7r-")
{
Some(Arch::Armv7R)
} else if target.starts_with("armv8r-") {
} else if target.starts_with("armv8r-") || target.starts_with("thumbv8r-") {
Some(Arch::Armv8R)
} else if target.starts_with("armv7a-") {
} else if target.starts_with("armv7a-") || target.starts_with("thumbv7a-") {
Some(Arch::Armv7A)
} else if target.starts_with("aarch64-") || target.starts_with("aarch64be-") {
Some(Arch::Armv8A)
} else if target.starts_with("arm-") {
} else if target.starts_with("arm-")
|| target.starts_with("armv6-")
|| target.starts_with("thumbv6-")
{
// If not specified, assume Armv6
Some(Arch::Armv6)
} else {
Expand Down Expand Up @@ -404,6 +410,26 @@ mod test {
assert_eq!(target_info.abi(), Some(Abi::Eabi));
}

#[test]
fn armv6_none_eabi() {
let target = "armv6-none-eabi";
let target_info = process_target(target);
assert_eq!(target_info.isa(), Some(Isa::A32));
assert_eq!(target_info.arch(), Some(Arch::Armv6));
assert_eq!(target_info.profile(), Some(Profile::Legacy));
assert_eq!(target_info.abi(), Some(Abi::Eabi));
}

#[test]
fn armv6_none_eabihf() {
let target = "armv6-none-eabihf";
let target_info = process_target(target);
assert_eq!(target_info.isa(), Some(Isa::A32));
assert_eq!(target_info.arch(), Some(Arch::Armv6));
assert_eq!(target_info.profile(), Some(Profile::Legacy));
assert_eq!(target_info.abi(), Some(Abi::EabiHf));
}

#[test]
fn arm_unknown_linux_gnueabi() {
let target = "arm-unknown-linux-gnueabi";
Expand Down Expand Up @@ -484,6 +510,16 @@ mod test {
assert_eq!(target_info.abi(), Some(Abi::EabiHf));
}

#[test]
fn thumbv8r_none_eabihf() {
let target = "thumbv8r-none-eabihf";
let target_info = process_target(target);
assert_eq!(target_info.isa(), Some(Isa::T32));
assert_eq!(target_info.arch(), Some(Arch::Armv8R));
assert_eq!(target_info.profile(), Some(Profile::R));
assert_eq!(target_info.abi(), Some(Abi::EabiHf));
}

#[test]
fn armv7a_none_eabi() {
let target = "armv7a-none-eabi";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Hello, this is an data abort exception example
data abort occurred
DFSR (Fault Status Register): DFSR { ext=false wnr=false Domain=0b0010 Status=0b00001 }
DFSR Status: Ok(AlignmentFault)
caught unaligned_from_a32
caught fault on COUNTER
Doing it again
data abort occurred
DFSR (Fault Status Register): DFSR { ext=false wnr=false Domain=0b0010 Status=0b00001 }
DFSR Status: Ok(AlignmentFault)
caught unaligned_from_a32
caught fault on COUNTER
Skipping instruction
Recovered from fault OK!
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Hello, this is an data abort exception example
data abort occurred
DFSR (Fault Status Register): DFSR { ext=false wnr=false Domain=0b0010 Status=0b00001 }
DFSR Status: Ok(AlignmentFault)
caught unaligned_from_t32
caught fault on COUNTER
Doing it again
data abort occurred
DFSR (Fault Status Register): DFSR { ext=false wnr=false Domain=0b0010 Status=0b00001 }
DFSR Status: Ok(AlignmentFault)
caught unaligned_from_t32
caught fault on COUNTER
Skipping instruction
Recovered from fault OK!
27 changes: 27 additions & 0 deletions examples/mps3-an536/reference/el2_hello-thumbv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Hello, this is semihosting! x = 1.000, y = 2.000
Region 0: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 1: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 2: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 3: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 4: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 5: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 6: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 7: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 8: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 9: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 10: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 11: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 12: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 13: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 14: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
Region 15: El2Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL10, no_exec: false, mair: 0, enable: false }
PANIC: PanicInfo {
message: I am an example panic,
location: Location {
file: "src/bin/el2_hello.rs",
line: 28,
column: 5,
},
can_unwind: true,
force_no_backtrace: false,
}
Loading