aarch32_cpu/register/
drsr.rs1use arbitrary_int::prelude::*;
4
5use crate::register::{SysReg, SysRegRead, SysRegWrite};
6
7#[derive(Debug, PartialEq, Eq)]
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[bitbybit::bitenum(u5, exhaustive = true)]
12pub enum RegionSize {
13 Invalid = 0,
15 _4B = 1,
17 _8B = 2,
19 _16B = 3,
21 _32B = 4,
23 _64B = 5,
25 _128B = 6,
27 _256B = 7,
29 _512b = 8,
31 _1K = 9,
33 _2K = 10,
35 _4K = 11,
37 _8K = 12,
39 _16K = 13,
41 _32K = 14,
43 _64K = 15,
45 _128K = 16,
47 _256K = 17,
49 _512K = 18,
51 _1M = 19,
53 _2M = 20,
55 _4M = 21,
57 _8M = 22,
59 _16M = 23,
61 _32M = 24,
63 _64M = 25,
65 _128M = 26,
67 _256M = 27,
69 _512M = 28,
71 _1G = 29,
73 _2G = 30,
75 _4G = 31,
77}
78
79impl RegionSize {
80 pub fn is_aligned(&self, addr: *const u8) -> bool {
81 let addr = addr as usize;
82 if *self == RegionSize::_4G {
83 addr == 0
85 } else {
86 let n = self.raw_value().as_u8();
87 let mask = (1 << (n + 1)) - 1;
88 (addr & mask) == 0
89 }
90 }
91}
92
93#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
95pub struct Drsr {
96 #[bits(8..=15, rw)]
105 subregion_mask: u8,
106 #[bits(1..=5, rw)]
108 region_size: RegionSize,
109 #[bits(0..=0, rw)]
111 enabled: bool,
112}
113
114impl SysReg for Drsr {
115 const CP: u32 = 15;
116 const CRN: u32 = 6;
117 const OP1: u32 = 0;
118 const CRM: u32 = 1;
119 const OP2: u32 = 2;
120}
121
122impl crate::register::SysRegRead for Drsr {}
123
124impl Drsr {
125 #[inline]
126 pub fn read() -> Drsr {
130 unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
131 }
132}
133
134impl crate::register::SysRegWrite for Drsr {}
135
136impl Drsr {
137 #[inline]
138 pub fn write(value: Drsr) {
142 unsafe { <Self as SysRegWrite>::write_raw(value.raw_value()) }
143 }
144}
145
146#[cfg(test)]
147mod test {
148 use super::*;
149 #[test]
150 fn aligned_4g() {
151 let addr: *const u8 = core::ptr::null();
152 assert!(RegionSize::_4G.is_aligned(addr));
153 }
154
155 #[test]
156 fn aligned_1g() {
157 let addr = 0x4000_0000 as *const u8;
158 assert!(RegionSize::_1G.is_aligned(addr));
159 let addr = 0x4000_0001 as *const u8;
160 assert!(!RegionSize::_1G.is_aligned(addr));
161 }
162
163 #[test]
164 fn aligned_256b() {
165 let addr = 0x100 as *const u8;
166 assert!(RegionSize::_256B.is_aligned(addr));
167 let addr = 0x80 as *const u8;
168 assert!(!RegionSize::_256B.is_aligned(addr));
169 }
170}