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 {
84 let addr = addr as usize;
85 if *self == RegionSize::_4G {
86 addr == 0
88 } else {
89 let n = self.raw_value().as_u8();
90 let mask = (1 << (n + 1)) - 1;
91 (addr & mask) == 0
92 }
93 }
94}
95
96#[bitbybit::bitfield(u32, debug, defmt_fields(feature = "defmt"))]
98pub struct Drsr {
99 #[bits(8..=15, rw)]
108 subregion_mask: u8,
109 #[bits(1..=5, rw)]
111 region_size: RegionSize,
112 #[bits(0..=0, rw)]
114 enabled: bool,
115}
116
117impl SysReg for Drsr {
118 const CP: u32 = 15;
119 const CRN: u32 = 6;
120 const OP1: u32 = 0;
121 const CRM: u32 = 1;
122 const OP2: u32 = 2;
123}
124
125impl crate::register::SysRegRead for Drsr {}
126
127impl Drsr {
128 #[inline]
129 pub fn read() -> Drsr {
133 Self::new_with_raw_value(<Self as SysRegRead>::read_raw())
134 }
135}
136
137impl crate::register::SysRegWrite for Drsr {}
138
139impl Drsr {
140 #[inline]
141 pub fn write(value: Drsr) {
145 unsafe { <Self as SysRegWrite>::write_raw(value.raw_value()) }
146 }
147}
148
149#[cfg(test)]
150mod test {
151 use super::*;
152 #[test]
153 fn aligned_4g() {
154 let addr: *const u8 = core::ptr::null();
155 assert!(RegionSize::_4G.is_aligned(addr));
156 }
157
158 #[test]
159 fn aligned_1g() {
160 let addr = 0x4000_0000 as *const u8;
161 assert!(RegionSize::_1G.is_aligned(addr));
162 let addr = 0x4000_0001 as *const u8;
163 assert!(!RegionSize::_1G.is_aligned(addr));
164 }
165
166 #[test]
167 fn aligned_256b() {
168 let addr = 0x100 as *const u8;
169 assert!(RegionSize::_256B.is_aligned(addr));
170 let addr = 0x80 as *const u8;
171 assert!(!RegionSize::_256B.is_aligned(addr));
172 }
173}