Skip to content

Commit e9a504a

Browse files
Decode HSR in HVC handler.
1 parent 9d52a61 commit e9a504a

7 files changed

Lines changed: 67 additions & 18 deletions

File tree

aarch32-cpu/src/register/armv8r/hsr.rs

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,64 @@
22
33
use crate::register::{SysReg, SysRegRead, SysRegWrite};
44

5+
use arbitrary_int::u25;
6+
57
/// HSR (*Hyp Syndrome Register*)
6-
#[derive(Debug, Copy, Clone)]
8+
#[bitbybit::bitfield(u32, debug, defmt_bitfields(feature = "defmt"))]
9+
pub struct Hsr {
10+
/// Exception Class.
11+
///
12+
/// Indicates the reason for the exception that this register holds
13+
/// information about.
14+
#[bits(26..=31, rw)]
15+
ec: Option<ExceptionClass>,
16+
/// Instruction length bit.
17+
///
18+
/// Indicates the size of the instruction that has been trapped to Hyp mode.
19+
#[bit(25, rw)]
20+
il: InstructionLength,
21+
/// Instruction Specific Syndrome.
22+
///
23+
/// Architecturally, this field can be defined independently for each
24+
/// defined Exception class. However, in practice, some ISS encodings are
25+
/// used for more than one Exception class.
26+
#[bits(0..=24, rw)]
27+
iss: u25,
28+
}
29+
30+
#[bitbybit::bitenum(u6, exhaustive = false)]
731
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
832
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9-
pub struct Hsr(pub u32);
33+
#[derive(Debug, PartialEq, Eq)]
34+
pub enum ExceptionClass {
35+
Unknown = 0b00_0000,
36+
TrappedWfiWfe = 0b00_0001,
37+
TrappedCp15McrMrc = 0b00_0011,
38+
TrappedCp15McrrMrrc = 0b00_0100,
39+
TrappedCp14McrMrc = 0b00_0101,
40+
TrappedLdcStc = 0b00_0110,
41+
TrappedFpu = 0b00_0111,
42+
TrappedVmrs = 0b00_1000,
43+
TrappedCp14McrrMrrc = 0b00_1100,
44+
IllegalAArch32Eret = 0b00_1110,
45+
Svc = 0b01_0001,
46+
Hvc = 0b01_0010,
47+
Smc = 0b01_0011,
48+
PrefetchAbortFromLower = 0b10_0000,
49+
PrefetchAbortFromCurrent = 0b10_0001,
50+
PcAlignment = 0b10_0010,
51+
DataAbortFromLower = 0b10_0100,
52+
DataAbortFromCurrent = 0b10_0101,
53+
}
54+
55+
#[bitbybit::bitenum(u1, exhaustive = true)]
56+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
57+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58+
#[derive(Debug, PartialEq, Eq)]
59+
pub enum InstructionLength {
60+
SixteenBit = 0b0,
61+
ThirtyTwoBit = 0b1,
62+
}
1063

1164
impl SysReg for Hsr {
1265
const CP: u32 = 15;
@@ -22,7 +75,7 @@ impl Hsr {
2275
#[inline]
2376
/// Reads HSR (*Hyp Syndrome Register*)
2477
pub fn read() -> Hsr {
25-
unsafe { Self(<Self as SysRegRead>::read_raw()) }
78+
unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
2679
}
2780
}
2881

@@ -37,7 +90,7 @@ impl Hsr {
3790
/// Ensure that this value is appropriate for this register
3891
pub unsafe fn write(value: Self) {
3992
unsafe {
40-
<Self as SysRegWrite>::write_raw(value.0);
93+
<Self as SysRegWrite>::write_raw(value.raw_value());
4194
}
4295
}
4396
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
x = 1, y = 2, z = 3.000
2-
In hvc_handler, with HSR=0x4a00abcd, frame=Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
2+
In hvc_handler, with Hsr { ec: Ok(Hvc), il: ThirtyTwoBit, iss: 0000abcd }, Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
33
Got 12345678
44
x = 1, y = 2, z = 3.000
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
x = 1, y = 2, z = 3.000
2-
In hvc_handler, with HSR=0x4a00abcd, frame=Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
2+
In hvc_handler, with Hsr { ec: Ok(Hvc), il: ThirtyTwoBit, iss: 0000abcd }, Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
33
Got 12345678
44
x = 1, y = 2, z = 3.000
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
x = 1, y = 2, z = 3.000
2-
In hvc_handler, with HSR=0x4a00abcd, frame=Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
2+
In hvc_handler, with Hsr { ec: Ok(Hvc), il: ThirtyTwoBit, iss: 0000abcd }, Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
33
Got 12345678
44
x = 1, y = 2, z = 3.000
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
x = 1, y = 2, z = 3.000
2-
In hvc_handler, with HSR=0x4a00abcd, frame=Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
2+
In hvc_handler, with Hsr { ec: Ok(Hvc), il: ThirtyTwoBit, iss: 0000abcd }, Frame { r0: 10000000, r1: 10000001, r2: 10000002, r3: 10000003, r4: 10000004, r5: 10000005 }
33
Got 12345678
44
x = 1, y = 2, z = 3.000

examples/mps3-an536/src/bin/hvc-a32.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ fn main() -> ! {
2424

2525
/// This is our HVC exception handler
2626
#[exception(HypervisorCall)]
27-
fn hvc_handler(arg: u32, frame: &aarch32_rt::Frame) -> u32 {
28-
println!(
29-
"In hvc_handler, with HSR=0x{:08x}, frame={:08x?}",
30-
arg, frame
31-
);
27+
fn hvc_handler(hsr: u32, frame: &aarch32_rt::Frame) -> u32 {
28+
let hsr = aarch32_cpu::register::Hsr::new_with_raw_value(hsr);
29+
println!("In hvc_handler, with {:08x?}, {:08x?}", hsr, frame);
3230
return 0x12345678;
3331
}
3432

examples/mps3-an536/src/bin/hvc-t32.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ fn main() -> ! {
2424

2525
/// This is our HVC exception handler
2626
#[exception(HypervisorCall)]
27-
fn hvc_handler(arg: u32, frame: &aarch32_rt::Frame) -> u32 {
28-
println!(
29-
"In hvc_handler, with HSR=0x{:08x}, frame={:08x?}",
30-
arg, frame
31-
);
27+
fn hvc_handler(hsr: u32, frame: &aarch32_rt::Frame) -> u32 {
28+
let hsr = aarch32_cpu::register::Hsr::new_with_raw_value(hsr);
29+
println!("In hvc_handler, with {:08x?}, {:08x?}", hsr, frame);
3230
return 0x12345678;
3331
}
3432

0 commit comments

Comments
 (0)