Skip to content

Commit f6b292d

Browse files
committed
Comment updates.
* Turned on deny(missing_docs), and added missing docs * Turned on deny(clippy::missing_safety_doc) and added missing safety docs * Turned on some more useful lints * Clippy fixes * Rationalised/renamed the various CachePolicy types
1 parent 3ba794a commit f6b292d

68 files changed

Lines changed: 494 additions & 207 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

aarch32-cpu/Cargo.toml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,25 @@ serde = ["dep:serde", "arbitrary-int/serde"]
5151
check-asm = []
5252

5353
[package.metadata.docs.rs]
54-
# This is a list of supported Tier 2 targets, as of latest stable
5554
targets = [
56-
"armv7r-none-eabihf",
57-
"armv7r-none-eabi",
58-
"armv7a-none-eabihf",
55+
"armebv7r-none-eabi",
56+
"armebv7r-none-eabihf",
57+
"armv4t-none-eabi",
58+
"armv5te-none-eabi",
59+
"armv6-none-eabi",
60+
"armv6-none-eabihf",
5961
"armv7a-none-eabi",
60-
"armv8r-none-eabihf"
62+
"armv7a-none-eabihf",
63+
"armv7r-none-eabi",
64+
"armv7r-none-eabihf",
65+
"armv8r-none-eabihf",
66+
"thumbv4t-none-eabi",
67+
"thumbv5te-none-eabi",
68+
"thumbv6-none-eabi",
69+
"thumbv7a-none-eabi",
70+
"thumbv7a-none-eabihf",
71+
"thumbv7r-none-eabi",
72+
"thumbv7r-none-eabihf",
73+
"thumbv8r-none-eabihf",
6174
]
75+
cargo-args = ["-Z", "build-std"]

aarch32-cpu/src/asmv4.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub fn core_id() -> u32 {
6666
r & 0x00FF_FFFF
6767
}
6868

69+
/// LLVM intrinsic for memory barriers
6970
#[no_mangle]
7071
pub extern "C" fn __sync_synchronize() {
7172
// we don't have a barrier instruction - the linux kernel just uses an empty inline asm block

aarch32-cpu/src/cache.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Helper functions for dealing with CPU cache
2+
13
use arbitrary_int::u3;
24

35
use crate::register::{Dccimvac, Dccisw, Dccmvac, Dccsw, Dcimvac, Dcisw, SysRegWrite};

aarch32-cpu/src/generic_timer/el0.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::register;
44

5-
/// Represents our Generic Timer when we are running at EL0.
5+
/// Represents our Generic Physical Timer when we are running at EL0.
66
///
77
/// Note that for most of these APIs to work, EL0 needs to have been granted
88
/// access using methods like
@@ -75,6 +75,11 @@ impl super::GenericTimer for El0PhysicalTimer {
7575
}
7676
}
7777

78+
/// Represents our Generic Virtual Timer when we are running at EL0.
79+
///
80+
/// Note that for most of these APIs to work, EL0 needs to have been granted
81+
/// access using methods like
82+
/// [El1VirtualTimer::el0_access_virtual_counter](crate::generic_timer::El1VirtualTimer::el0_access_virtual_counter).
7883
pub struct El0VirtualTimer();
7984

8085
impl El0VirtualTimer {

aarch32-cpu/src/lib.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
//! CPU/peripheral support for Arm AArch32
22
#![no_std]
3+
#![deny(missing_docs)]
4+
#![deny(unsafe_op_in_unsafe_fn)]
5+
#![deny(clippy::missing_safety_doc)]
6+
#![deny(clippy::unnecessary_safety_comment)]
7+
#![deny(clippy::unnecessary_safety_doc)]
38

49
mod critical_section;
510

@@ -23,18 +28,20 @@ pub mod asm;
2328

2429
pub mod cache;
2530
pub mod interrupt;
26-
pub mod mmu;
2731
pub mod register;
2832
#[cfg(target_arch = "arm")]
2933
pub mod stacks;
3034

31-
#[cfg(any(test, doc, arm_architecture = "v7-r"))]
35+
#[cfg(any(test, arm_profile = "a", arm_profile = "legacy"))]
36+
pub mod mmu;
37+
38+
#[cfg(any(test, arm_architecture = "v7-r"))]
3239
pub mod pmsav7;
3340

34-
#[cfg(any(test, doc, arm_architecture = "v8-r"))]
41+
#[cfg(any(test, arm_architecture = "v8-r"))]
3542
pub mod generic_timer;
3643

37-
#[cfg(any(test, doc, arm_architecture = "v8-r"))]
44+
#[cfg(any(test, arm_architecture = "v8-r"))]
3845
pub mod pmsav8;
3946

4047
/// Generate an SVC call with no parameters.

aarch32-cpu/src/mmu.rs

Lines changed: 94 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ pub const NUM_L1_PAGE_TABLE_ENTRIES: usize = 4096;
99
///
1010
/// You should create a static variable of this type, to represent your page table.
1111
#[repr(C, align(1048576))]
12+
#[derive(Debug)]
1213
pub struct L1Table {
14+
/// Our mutable list of MMU table entries
15+
///
16+
/// This table is read by the hardware.
1317
pub entries: core::cell::UnsafeCell<[L1Section; NUM_L1_PAGE_TABLE_ENTRIES]>,
1418
}
1519

@@ -24,25 +28,39 @@ unsafe impl Sync for L1Table {}
2428
pub struct InvalidL1EntryType(pub L1EntryType);
2529

2630
/// Access permissions for a region of memory
27-
#[bitbybit::bitenum(u3, exhaustive = true)]
31+
#[bitbybit::bitenum(u3)]
2832
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2933
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3034
#[derive(Debug, PartialEq, Eq)]
3135
pub enum AccessPermissions {
36+
/// All accesses generate Permission faults
3237
PermissionFault = 0b000,
38+
/// Privileged access only
3339
PrivilegedOnly = 0b001,
40+
/// Writes in User mode generate Permission faults
3441
NoUserWrite = 0b010,
42+
/// Full access
3543
FullAccess = 0b011,
36-
_Reserved1 = 0b100,
44+
/// Privileged read-only
3745
PrivilegedReadOnly = 0b101,
38-
ReadOnly = 0b110,
39-
_Reserved2 = 0b111,
46+
/// Privileged and User read-only (deprecated in VMSAv7)
47+
ReadOnlyv6 = 0b110,
48+
/// Privileged and User read-only
49+
ReadOnly = 0b111,
4050
}
4151

4252
impl AccessPermissions {
53+
/// Create a new [`AccessPermissions`] value from the APX bit at the AP bit
54+
/// pair
55+
///
56+
/// Will panic if you select an invalid value.
4357
#[inline]
4458
pub const fn new(apx: bool, ap: u2) -> Self {
45-
Self::new_with_raw_value(u3::new(((apx as u8) << 2) | ap.value()))
59+
let x = u3::new(((apx as u8) << 2) | ap.value());
60+
let Ok(ap) = Self::new_with_raw_value(x) else {
61+
panic!("Invalid access permissions");
62+
};
63+
ap
4664
}
4765

4866
/// AP bit for the given access permission.
@@ -65,21 +83,25 @@ impl AccessPermissions {
6583
#[derive(Debug, PartialEq, Eq)]
6684
#[repr(u8)]
6785
pub enum L1EntryType {
68-
/// Access generates an abort exception. Indicates an unmapped virtual address.
86+
/// Access generates an abort exception. Indicates an unmapped virtual
87+
/// address.
6988
Fault = 0b00,
70-
/// Entry points to a L2 translation table, allowing 1 MB of memory to be further divided
89+
/// Entry points to a L2 translation table, allowing 1 MB of memory to be
90+
/// further divided
7191
PageTable = 0b01,
7292
/// Maps a 1 MB region to a physical address.
7393
Section = 0b10,
74-
/// Special 1MB section entry which requires 16 entries in the translation table.
94+
/// Special 1MB section entry which requires 16 entries in the translation
95+
/// table.
7596
Supersection = 0b11,
7697
}
7798

78-
/// The ARM Cortex-A architecture reference manual p.1363 specifies these attributes in more detail.
99+
/// The ARM Cortex-A architecture reference manual p.1363 specifies these
100+
/// attributes in more detail.
79101
///
80-
/// The B (Bufferable), C (Cacheable), and TEX (Type extension) bit names are inherited from
81-
/// earlier versions of the architecture. These names no longer adequately describe the function
82-
/// of the B, C, and TEX bits.
102+
/// The B (Bufferable), C (Cacheable), and TEX (Type extension) bit names are
103+
/// inherited from earlier versions of the architecture. These names no longer
104+
/// adequately describe the function of the B, C, and TEX bits.
83105
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
84106
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85107
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -91,6 +113,7 @@ pub struct MemoryRegionAttributesRaw {
91113
}
92114

93115
impl MemoryRegionAttributesRaw {
116+
/// Create a new [`MemoryRegionAttributesRaw`] from constituent parts
94117
#[inline]
95118
pub const fn new(type_extensions: u3, c: bool, b: bool) -> Self {
96119
Self {
@@ -105,11 +128,15 @@ impl MemoryRegionAttributesRaw {
105128
#[bitbybit::bitenum(u2, exhaustive = true)]
106129
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
107130
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108-
#[derive(Debug)]
109-
pub enum CacheableMemoryAttribute {
131+
#[derive(Debug, PartialEq, Eq)]
132+
pub enum CachePolicy {
133+
/// Non-cacheable
110134
NonCacheable = 0b00,
135+
/// Write-Back Cacheable, Write-Allocate
111136
WriteBackWriteAlloc = 0b01,
137+
/// Write-Through Cacheable
112138
WriteThroughNoWriteAlloc = 0b10,
139+
/// Write-Back Cacheable, no Write-Allocate
113140
WriteBackNoWriteAlloc = 0b11,
114141
}
115142

@@ -118,20 +145,43 @@ pub enum CacheableMemoryAttribute {
118145
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
119146
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
120147
pub enum MemoryRegionAttributes {
148+
/// Strongly- ordered
149+
///
150+
/// All memory accesses to Strongly-ordered memory occur in program order.
151+
/// All Strongly-ordered regions are assumed to be Shareable.
121152
StronglyOrdered,
153+
/// Device Shareable
154+
///
155+
/// Intended to handle memory-mapped peripherals that are shared by several
156+
/// processors.
122157
ShareableDevice,
158+
/// Normal Memory, Write-Through Cacheable for both Inner and Outer Cache
123159
OuterAndInnerWriteThroughNoWriteAlloc,
160+
/// Normal Memory, Write-Back no Write-Allocate Cacheable for both Inner and
161+
/// Outer Cache
124162
OuterAndInnerWriteBackNoWriteAlloc,
163+
/// Normal Memory, Non-cacheable for both Inner and Outer Cache
125164
OuterAndInnerNonCacheable,
165+
/// Normal Memory, Write-Back Write-Allocate Cacheable for both Inner and
166+
/// Outer Cache
126167
OuterAndInnerWriteBackWriteAlloc,
168+
/// Device Non-Shareable
169+
///
170+
/// Intended to handle memory-mapped peripherals that are used only by a
171+
/// single processor.
127172
NonShareableDevice,
173+
/// Normal Memory, where Inner and Outer cache have different settings
128174
CacheableMemory {
129-
inner: CacheableMemoryAttribute,
130-
outer: CacheableMemoryAttribute,
175+
/// Settings for the Inner Cache
176+
inner: CachePolicy,
177+
/// Settings for the Outer Cache
178+
outer: CachePolicy,
131179
},
132180
}
133181

134182
impl MemoryRegionAttributes {
183+
/// Convert the Rust enum type [`MemoryRegionAttributes`] into a raw
184+
/// [`MemoryRegionAttributesRaw`] value for the hardware
135185
pub const fn as_raw(&self) -> MemoryRegionAttributesRaw {
136186
match self {
137187
MemoryRegionAttributes::StronglyOrdered => {
@@ -175,10 +225,13 @@ pub struct SectionAttributes {
175225
pub non_global: bool,
176226
/// Implementation defined bit.
177227
pub p_bit: bool,
228+
/// Is memory shareable across multiple CPUs
178229
pub shareable: bool,
179-
/// AP bits
230+
/// Access permissions
180231
pub access: AccessPermissions,
232+
/// Raw memory attributes
181233
pub memory_attrs: MemoryRegionAttributesRaw,
234+
/// Domain value for this section
182235
pub domain: u4,
183236
/// xN bit.
184237
pub execute_never: bool,
@@ -195,7 +248,8 @@ impl SectionAttributes {
195248
Ok(Self::from_raw_unchecked(raw))
196249
}
197250

198-
/// Retrieves the corresponding L1 section part without the section base address being set.
251+
/// Retrieves the corresponding L1 section part without the section base
252+
/// address being set.
199253
const fn l1_section_part(&self) -> L1Section {
200254
L1Section::builder()
201255
.with_base_addr_upper_bits(u12::new(0))
@@ -231,8 +285,9 @@ impl SectionAttributes {
231285

232286
/// 1 MB section translation entry, mapping a 1 MB region to a physical address.
233287
///
234-
/// The ARM Cortex-A architecture programmers manual chapter 9.4 (p.163) or the ARMv7-A and ArmV7-R
235-
/// architecture reference manual p.1323 specify these attributes in more detail.
288+
/// The ARM Cortex-A architecture programmers manual chapter 9.4 (p.163) or the
289+
/// ARMv7-A and ArmV7-R architecture reference manual p.1323 specify these
290+
/// attributes in more detail.
236291
#[bitbybit::bitfield(u32, default = 0, defmt_fields(feature = "defmt"))]
237292
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
238293
#[derive(PartialEq, Eq)]
@@ -246,23 +301,31 @@ pub struct L1Section {
246301
/// Shareable bit.
247302
#[bit(16, rw)]
248303
s: bool,
304+
/// Part of the access permissions field
249305
#[bit(15, rw)]
250306
apx: bool,
251-
/// Type extension bits.
307+
/// Memory Region Attribute bit
252308
#[bits(12..=14, rw)]
253309
tex: u3,
310+
/// Part of the access permissions field
254311
#[bits(10..=11, rw)]
255312
ap: u2,
313+
/// Implementation defined bit
256314
#[bit(9, rw)]
257315
p_bit: bool,
316+
/// Domain field
258317
#[bits(5..=8, rw)]
259318
domain: u4,
319+
/// Execute-never bit
260320
#[bit(4, rw)]
261321
xn: bool,
322+
/// Memory Region Attribute bit
262323
#[bit(3, rw)]
263324
c: bool,
325+
/// Memory Region Attribute bit
264326
#[bit(2, rw)]
265327
b: bool,
328+
/// Entry Type
266329
#[bits(0..=1, rw)]
267330
entry_type: L1EntryType,
268331
}
@@ -287,11 +350,12 @@ impl core::fmt::Debug for L1Section {
287350
}
288351

289352
impl L1Section {
290-
/// Generates a new L1 section from a physical address and section attributes.
353+
/// Generates a new L1 section from a physical address and section
354+
/// attributes.
291355
///
292-
/// The uppermost 12 bits of the physical address define which 1 MB of virtual address space
293-
/// are being accessed. They will be stored in the L1 section table. This address MUST be
294-
/// aligned to 1 MB.
356+
/// The uppermost 12 bits of the physical address define which 1 MB of
357+
/// virtual address space are being accessed. They will be stored in the L1
358+
/// section table. This address MUST be aligned to 1 MB.
295359
///
296360
/// # Panics
297361
///
@@ -316,7 +380,8 @@ impl L1Section {
316380
*self = Self::new_with_addr_upper_bits_and_attrs(self.base_addr_upper_bits(), section_attrs)
317381
}
318382

319-
/// Create a new L1 section with the given upper 12 bits of the address and section attributes.
383+
/// Create a new L1 section with the given upper 12 bits of the address and
384+
/// section attributes.
320385
#[inline]
321386
pub const fn new_with_addr_upper_bits_and_attrs(
322387
addr_upper_twelve_bits: u12,
@@ -368,8 +433,8 @@ mod tests {
368433
access: AccessPermissions::FullAccess,
369434
// TEX 0b101, c false, b true
370435
memory_attrs: MemoryRegionAttributes::CacheableMemory {
371-
inner: CacheableMemoryAttribute::WriteBackWriteAlloc,
372-
outer: CacheableMemoryAttribute::WriteBackWriteAlloc,
436+
inner: CachePolicy::WriteBackWriteAlloc,
437+
outer: CachePolicy::WriteBackWriteAlloc,
373438
}
374439
.as_raw(),
375440
domain: u4::new(0b1010),
@@ -431,7 +496,7 @@ mod tests {
431496
p_bit: true,
432497
shareable: false,
433498
// APX true, AP 0b10
434-
access: AccessPermissions::ReadOnly,
499+
access: AccessPermissions::ReadOnlyv6,
435500
// TEX 0b000, c false, b false
436501
memory_attrs: MemoryRegionAttributes::StronglyOrdered.as_raw(),
437502
domain: u4::new(0b1001),

0 commit comments

Comments
 (0)