Skip to content

Use QEMU 9 #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 9, 2025
Merged
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
10 changes: 5 additions & 5 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[target.armv8r-none-eabihf]
# Note, this requires QEMU 9 or higher
runner = "qemu-system-arm -machine mps3-an536 -cpu cortex-r52 -semihosting -nographic -kernel"
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 -kernel"
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 -kernel"
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 -kernel"
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 -kernel"
runner = "qemu-system-arm -machine versatileab -cpu cortex-a8 -semihosting -nographic -audio none -kernel"

[unstable]
build-std = ["core", "alloc"]
17 changes: 14 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ jobs:
cargo build

# Build the workspace for the target architecture but using nightly to compile libcore
# Technically it doens't need 'setup' but it makes the graph look nicer
build-tier3:
runs-on: ubuntu-24.04
needs: setup
strategy:
matrix:
target:
Expand Down Expand Up @@ -292,15 +294,24 @@ jobs:
run: |
cargo test --manifest-path cortex-ar/Cargo.toml

# Run some programs in QEMU
# Run some programs in QEMU 9
qemu-test:
runs-on: ubuntu-24.04
needs: [build-all]
steps:
- run: sudo apt-get -y update && sudo apt-get -y install qemu-system-arm
- name: Checkout
uses: actions/checkout@v4
- run: ./tests.sh
- 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
./tests.sh

# Gather all the above xxx-all jobs together for the purposes of getting an overall pass-fail
all:
Expand Down
23 changes: 23 additions & 0 deletions examples/mps3-an536/reference/generic_timer-armv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cntfrq = 62.500 MHz
Using physical timer ************************
Print five, every 100ms...
i = 0
i = 1
i = 2
i = 3
i = 4
Waiting for 31250000 physical ticks to count up...
Matched! physical
Waiting for 31250000 physical ticks to count down...
physical countdown hit zero!
Using virtual timer ************************
Print five, every 100ms...
i = 0
i = 1
i = 2
i = 3
i = 4
Waiting for 31250000 virtual ticks to count up...
Matched! virtual
Waiting for 31250000 virtual ticks to count down...
virtual countdown hit zero!
12 changes: 12 additions & 0 deletions examples/mps3-an536/reference/gic-armv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Found PERIPHBASE 0xf0000000
Creating GIC driver @ 0xf0000000 / 0xf0100000
Calling git.setup(0)
Configure SGI...
gic.enable_interrupt()
Enabling interrupts...
CPSR: CPSR { N=0 Z=1 C=1 V=0 Q=0 J=0 E=0 A=0 I=1 F=1 T=0 MODE=Ok(Sys) }
CPSR: CPSR { N=0 Z=1 C=1 V=0 Q=0 J=0 E=0 A=0 I=0 F=1 T=0 MODE=Ok(Sys) }
Send SGI
> IRQ
- IRQ handle SGI 3
< IRQ
11 changes: 11 additions & 0 deletions examples/mps3-an536/reference/hello-armv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Hello, this is semihosting! x = 1.000, y = 2.000
PANIC: PanicInfo {
message: I am an example panic,
location: Location {
file: "src/bin/hello.rs",
line: 26,
col: 5,
},
can_unwind: true,
force_no_backtrace: false,
}
39 changes: 39 additions & 0 deletions examples/mps3-an536/reference/registers-armv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
MIDR { implementer=0x41 variant=0x1 arch=0xf part_no=0xd13 rev=0x3 }
CPSR { N=0 Z=1 C=1 V=0 Q=0 J=0 E=0 A=0 I=1 F=1 T=0 MODE=Ok(Sys) }
IMP_CBAR { 0xf0000000 }
VBAR { 0x08000000 }
PMSA-v8 MPUIR: Mpuir { iregions: 0, dregions: 16, non_unified: false }
Region 0: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 1: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 2: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 3: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 4: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 5: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 6: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 7: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 8: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 9: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 10: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 11: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 12: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 13: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 14: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 15: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 0: Region { range: 0x0..=0x3fffffff, shareability: OuterShareable, access: ReadWrite, no_exec: true, mair: 0, enable: true }
Region 1: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 2: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 3: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 4: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 5: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 6: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 7: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 8: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 9: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 10: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 11: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 12: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 13: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 14: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
Region 15: Region { range: 0x0..=0x3f, shareability: NonShareable, access: ReadWriteNoEL0, no_exec: false, mair: 0, enable: false }
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=1 FI=0 DZ=1 BR=1 RR=0 V=0 I=0 Z=1 SW=0 C=0 A=0 M=0 } before setting C, I and Z
SCTLR { IE=0 TE=0 NMFI=0 EE=0 U=1 FI=0 DZ=1 BR=1 RR=0 V=0 I=1 Z=1 SW=0 C=1 A=0 M=0 } after
14 changes: 14 additions & 0 deletions examples/mps3-an536/reference/svc-armv8r-none-eabihf.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
x = 1, y = 2, z = 3.000
In _svc_handler, with arg=0xabcdef
In _svc_handler, with arg=0x456789
x = 1, y = 2, z = 3.000
PANIC: PanicInfo {
message: I am an example panic,
location: Location {
file: "src/bin/svc.rs",
line: 29,
col: 5,
},
can_unwind: true,
force_no_backtrace: false,
}
15 changes: 5 additions & 10 deletions examples/mps3-an536/src/bin/generic_timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn main() {
let cntfrq = cortex_ar::register::Cntfrq::read().0;
println!("cntfrq = {:.03} MHz", cntfrq as f32 / 1_000_000.0);

let delay_ticks = cntfrq * 2;
let delay_ticks = cntfrq / 2;

let mut pgt = unsafe { El1PhysicalTimer::new() };
let mut vgt = unsafe { El1VirtualTimer::new() };
Expand All @@ -34,21 +34,20 @@ fn main() {
for (timer, name) in [(pgt_ref, "physical"), (vgt_ref, "virtual")] {
println!("Using {} timer ************************", name);

println!("Print five, one per second...");
println!("Print five, every 100ms...");
for i in 0..5 {
println!("i = {}", i);
timer.delay_ms(1000);
timer.delay_ms(100);
}

let now = timer.counter();
println!("{} is now: {}", name, now);
println!("Waiting for {} {} ticks to count up...", delay_ticks, name);
timer.counter_compare_set(now + delay_ticks as u64);
timer.enable(true);
while !timer.interrupt_status() {
core::hint::spin_loop();
}
println!("Matched! {} count now {}", name, timer.counter());
println!("Matched! {}", name);

println!(
"Waiting for {} {} ticks to count down...",
Expand All @@ -58,10 +57,6 @@ fn main() {
while !timer.interrupt_status() {
core::hint::spin_loop();
}
println!(
"{} countdown hit zero! (and is now {})",
name,
timer.countdown() as i32
);
println!("{} countdown hit zero!", name,);
}
}
32 changes: 24 additions & 8 deletions tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
rustup target add armv7r-none-eabi
rustup target add armv7r-none-eabihf
rustup target add armv7a-none-eabi
rustup toolchain add nightly
rustup component add rust-src --toolchain=nightly

FAILURE=0

Expand All @@ -19,31 +21,45 @@ fail() {
mkdir -p ./target

versatile_ab_cargo="--manifest-path examples/versatileab/Cargo.toml"
mps3_an536_cargo="--manifest-path examples/mps3-an536/Cargo.toml"

my_diff() {
file_a=$1
file_b=$2
# - Fix Windows path separators (\\) to look like UNIX ones (/) in the QEMU
# output
# - Fix the CRLF line endings in the files on disk, because git adds them to
# text files.
diff <(cat $file_a | tr -d '\r') <(cat $file_b | sed 's~\\\\~/~g')
}

# armv7r-none-eabi tests
for binary in hello registers svc; do
cargo run ${versatile_ab_cargo} --target=armv7r-none-eabi --bin $binary | tee ./target/$binary-armv7r-none-eabi.out
diff ./examples/versatileab/reference/$binary-armv7r-none-eabi.out ./target/$binary-armv7r-none-eabi.out || fail $binary "armv7r-none-eabi"
my_diff ./examples/versatileab/reference/$binary-armv7r-none-eabi.out ./target/$binary-armv7r-none-eabi.out || fail $binary "armv7r-none-eabi"
done

# armv7r-none-eabihf tests
for binary in hello registers svc undef-exception prefetch-exception abt-exception; do
cargo run ${versatile_ab_cargo} --target=armv7r-none-eabihf --bin $binary | tee ./target/$binary-armv7r-none-eabihf.out
diff ./examples/versatileab/reference/$binary-armv7r-none-eabihf.out ./target/$binary-armv7r-none-eabihf.out || fail $binary "armv7r-none-eabihf"
my_diff ./examples/versatileab/reference/$binary-armv7r-none-eabihf.out ./target/$binary-armv7r-none-eabihf.out || fail $binary "armv7r-none-eabihf"
done

# armv7a-none-eabi tests
for binary in hello registers svc undef-exception prefetch-exception abt-exception; do
cargo run ${versatile_ab_cargo} --target=armv7a-none-eabi --bin $binary | tee ./target/$binary-armv7a-none-eabi.out
diff ./examples/versatileab/reference/$binary-armv7a-none-eabi.out ./target/$binary-armv7a-none-eabi.out || fail $binary "armv7a-none-eabi"
my_diff ./examples/versatileab/reference/$binary-armv7a-none-eabi.out ./target/$binary-armv7a-none-eabi.out || fail $binary "armv7a-none-eabi"
done

# These tests only run on QEMU 9 or higher.
# Ubuntu 24.04 supplies QEMU 8, which doesn't support the machine we have configured for this target
# # armv8r-none-eabihf tests
# for binary in hello registers svc gic; do
# cargo +nightly run --target=armv8r-none-eabihf --bin $binary --features=gic -Zbuild-std=core | tee ./target/$binary-armv8r-none-eabihf.out
# diff ./cortex-r-examples/reference/$binary-armv8r-none-eabihf.out ./target/$binary-armv8r-none-eabihf.out || fail $binary "armv8r-none-eabihf"
# done
if qemu-system-arm --version | grep "version 9"; then
# armv8r-none-eabihf tests
for binary in hello registers svc gic generic_timer; do
cargo +nightly run ${mps3_an536_cargo} --target=armv8r-none-eabihf --bin $binary --features=gic -Zbuild-std=core | tee ./target/$binary-armv8r-none-eabihf.out
my_diff ./examples/mps3-an536/reference/$binary-armv8r-none-eabihf.out ./target/$binary-armv8r-none-eabihf.out || fail $binary "armv8r-none-eabihf"
done
fi

if [ "$FAILURE" == "1" ]; then
echo "***************************************************"
Expand Down