Skip to content

Commit 6c13a59

Browse files
committed
address review comments
1 parent c25f74d commit 6c13a59

File tree

4 files changed

+77
-83
lines changed

4 files changed

+77
-83
lines changed

Cargo.lock

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ categories = ["embedded", "no-std"]
1313
aarch64-paging = { version = "0.11", default-features = false }
1414
aarch64-rt = { version = "0.3", features = ["el2", "exceptions", "initial-pagetable", "psci"], default-features = false }
1515
arm-pl011-uart = "0.4"
16+
arm-sysregs = { version = "0.2", features = ["el1", "el2"] }
1617
buddy_system_allocator = { version = "0.11", default-features = false, features = ["alloc", "use_spin"] }
1718
embedded-io = "0.7"
1819
log = "0.4"

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn handle_payload() {
6767
#[allow(clippy::unreadable_literal)]
6868
pub const PAYLOAD_SIZE: usize = {payload_size};
6969
#[allow(clippy::unreadable_literal)]
70-
pub const PAYLOAD_DATA: &[u8; {payload_size}] = include_bytes!(env!("RITM_PAYLOAD_PATH"));
70+
pub const PAYLOAD_DATA: &[u8; PAYLOAD_SIZE] = include_bytes!(env!("RITM_PAYLOAD_PATH"));
7171
"#
7272
),
7373
)

src/arch.rs

Lines changed: 30 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
//! Architecture-specific code.
1010
11+
use arm_sysregs::{
12+
CacheLevel, CacheType, CsselrEl1, SctlrEl2, read_ccsidr_el1, read_clidr_el1, read_sctlr_el2,
13+
write_csselr_el1,
14+
};
1115
use core::arch::{asm, naked_asm};
1216

1317
/// Data Synchronization Barrier.
@@ -34,64 +38,6 @@ pub fn isb() {
3438
}
3539
}
3640

37-
macro_rules! sys_reg {
38-
($name:ident, {$($const_name:ident: $const_val:expr),*}) => {
39-
pub mod $name {
40-
use core::arch::asm;
41-
$(pub const $const_name: u64 = $const_val;)*
42-
43-
#[doc = concat!("Read the `", stringify!($name), "` system register.")]
44-
#[allow(unused)]
45-
pub fn read() -> u64 {
46-
let val: u64;
47-
// SAFETY: Reading a register is always safe.
48-
unsafe {
49-
asm!(concat!("mrs {}, ", stringify!($name)), out(reg) val, options(nostack, preserves_flags));
50-
}
51-
val
52-
}
53-
54-
#[doc = concat!("Write the `", stringify!($name), "` system register.")]
55-
///
56-
/// # Safety
57-
///
58-
/// This function allows fundamental changes to the CPU state. To avoid Undefined
59-
/// Behavior, the caller must guarantee:
60-
///
61-
/// * The register is writable at the current Exception Level.
62-
/// * The write must not invalidate the stack, the heap, or any active Rust references
63-
/// (e.g., by disabling the MMU).
64-
/// * This function emits a raw `MSR`. The caller is responsible for issuing context
65-
/// synchronization (e.g., `ISB`) or memory barriers (`DSB`) if required.
66-
#[allow(unused)]
67-
pub unsafe fn write(val: u64) {
68-
// SAFETY: The caller must ensure that the register is safely writeable.
69-
unsafe {
70-
asm!(concat!("msr ", stringify!($name), ", {}"), in(reg) val, options(nostack, preserves_flags));
71-
}
72-
}
73-
}
74-
};
75-
($name:ident) => {
76-
sys_reg!($name, {});
77-
};
78-
}
79-
80-
sys_reg!(sctlr_el2, {
81-
M: 1 << 0,
82-
C: 1 << 2,
83-
I: 1 << 12
84-
});
85-
sys_reg!(clidr_el1);
86-
sys_reg!(csselr_el1);
87-
sys_reg!(ccsidr_el1);
88-
sys_reg!(hcr_el2);
89-
sys_reg!(cntvoff_el2);
90-
sys_reg!(cnthctl_el2);
91-
sys_reg!(spsr_el2);
92-
sys_reg!(elr_el2);
93-
sys_reg!(sp_el1);
94-
9541
/// Disables MMU and caches.
9642
///
9743
/// # Safety
@@ -105,7 +51,7 @@ sys_reg!(sp_el1);
10551
///
10652
/// # Registers
10753
///
108-
/// This function clobbers x27 and x28.
54+
/// In addition to the regular caller-saved registers, this function clobbers x27 and x28.
10955
#[unsafe(naked)]
11056
pub(super) unsafe extern "C" fn disable_mmu_and_caches() {
11157
naked_asm!(
@@ -137,53 +83,55 @@ extern "C" fn disable_mmu_and_caches_impl() -> u64 {
13783
invalidate_dcache();
13884

13985
// Disable MMU and caches
140-
let mut sctlr = sctlr_el2::read();
141-
sctlr &= !sctlr_el2::M; // MMU Enable
142-
sctlr &= !sctlr_el2::C; // Data Cache Enable
143-
sctlr &= !sctlr_el2::I; // Instruction Cache Enable
144-
sctlr
86+
let mut sctlr = read_sctlr_el2();
87+
sctlr.remove(SctlrEl2::M); // MMU Enable
88+
sctlr.remove(SctlrEl2::C); // Data Cache Enable
89+
sctlr.remove(SctlrEl2::I); // Instruction Cache Enable
90+
sctlr.bits()
14591
}
14692

14793
/// Invalidate D-cache by set/way to the point of coherency.
14894
pub fn invalidate_dcache() {
14995
dmb();
15096

15197
// Cache Level ID Register
152-
let clidr = clidr_el1::read();
98+
let clidr = read_clidr_el1();
15399

154-
// Level of Coherence (LoC) - Bits [26:24]
155-
let loc = (clidr >> 24) & 0x7;
100+
// Level of Coherence (LoC)
101+
let loc = clidr.loc();
156102

157-
for level in 0..loc {
158-
let cache_type = (clidr >> (level * 3)) & 0x7;
159-
160-
// Cache Types: 0=None, 1=Instruction, 2=Data, 3=Split, 4=Unified
103+
for level in 1..=loc {
161104
// We don't care about No cache or Instruction cache
162-
if cache_type < 2 {
163-
continue;
105+
let level = CacheLevel::new(level);
106+
match clidr.cache_type(level) {
107+
CacheType::NoCache | CacheType::InstructionOnly => {
108+
continue;
109+
}
110+
CacheType::DataOnly | CacheType::SeparateInstructionAndData | CacheType::Unified => {}
164111
}
165112

166113
// Select the Cache Level in CSSELR (Cache Size Selection Register)
167-
// SAFETY: Writing to `csselr_el1` is always safe, assuming the cache level exists.
168-
unsafe {
169-
csselr_el1::write(level << 1);
170-
}
114+
write_csselr_el1(CsselrEl1::new(false, level, false));
171115

172116
// Barrier to ensure CSSELR write finishes before reading CCSIDR
173117
isb();
174118

175119
// Cache Size ID Register (CCSIDR)
176-
let ccsidr = ccsidr_el1::read();
120+
let ccsidr = read_ccsidr_el1();
177121

178-
let line_power = (ccsidr & 0x7) + 4;
179-
let ways = (ccsidr >> 3) & 0x3FF;
180-
let sets = (ccsidr >> 13) & 0x7FFF;
122+
let line_size = ccsidr.linesize();
123+
let ways = (ccsidr.bits() >> 3) & 0x3FF;
124+
let sets = (ccsidr.bits() >> 13) & 0x7FFF;
181125

182126
let way_shift = (ways as u32).leading_zeros();
183127

184128
for set in 0..=sets {
185129
for way in 0..=ways {
186-
let dc_val = (way << way_shift) | (set << line_power) | (level << 1);
130+
const LEVEL_SHIFT: u8 = 1;
131+
const SET_WAY_SHIFT: u8 = 4;
132+
let dc_val = (way << way_shift)
133+
| (set << (line_size + SET_WAY_SHIFT))
134+
| (u64::from(level.level()) << LEVEL_SHIFT);
187135

188136
// SAFETY: `dc cisw` is always safe, assuming the cache line exists.
189137
unsafe {

0 commit comments

Comments
 (0)