1use kernel::utilities::registers::interfaces::{ReadWriteable, Readable, Writeable};
10use kernel::utilities::registers::{register_bitfields, register_structs, ReadOnly, ReadWrite};
11use kernel::utilities::StaticRef;
12
13register_structs! {
14 ScbRegisters {
17 (0x00 => cpuid: ReadOnly<u32, CpuId::Register>),
19
20 (0x04 => icsr: ReadWrite<u32, InterruptControlAndState::Register>),
22
23 (0x08 => vtor: ReadWrite<u32, VectorTableOffset::Register>),
25
26 (0x0c => aircr: ReadWrite<u32, ApplicationInterruptAndReset::Register>),
28
29 (0x10 => scr: ReadWrite<u32, SystemControl::Register>),
31
32 (0x14 => ccr: ReadWrite<u32, ConfigurationAndControl::Register>),
34
35 (0x18 => shp: [ReadWrite<u32, SystemHandlerPriority::Register>; 3]),
37
38 (0x24 => shcsr: ReadWrite<u32, SystemHandlerControlAndState::Register>),
40
41 (0x28 => cfsr: ReadWrite<u32, ConfigurableFaultStatus::Register>),
43
44 (0x2c => hfsr: ReadWrite<u32, HardFaultStatus::Register>),
46
47 (0x30 => dfsr: ReadWrite<u32, DebugFaultStatus::Register>),
49
50 (0x34 => mmfar: ReadWrite<u32, FaultAddress::Register>),
52
53 (0x38 => bfar: ReadWrite<u32, FaultAddress::Register>),
55
56 (0x3c => afsr: ReadWrite<u32, FaultAddress::Register>),
58
59 (0x40 => _reserved0),
61
62 (0x80 => _reserved1),
64
65 (0x88 => cpacr: ReadWrite<u32, CoprocessorAccessControl::Register>),
67
68 (0x8c => _reserved2),
70
71 (0x90 => @END),
72 }
73}
74
75register_bitfields![u32,
76 CpuId [
77 IMPLEMENTER OFFSET(24) NUMBITS(8),
79
80 VARIANT OFFSET(20) NUMBITS(4),
82
83 ARCHITECTURE OFFSET(16) NUMBITS(4),
85
86 PARTNO OFFSET(4) NUMBITS(12),
88
89 REVISION OFFSET(0) NUMBITS(4)
91 ],
92
93 InterruptControlAndState [
94 NMIPENDSET OFFSET(31) NUMBITS(1),
98
99 PENDSVSET OFFSET(28) NUMBITS(1),
103
104 PENDSVCLR OFFSET(27) NUMBITS(1),
107
108 PENDSTSET OFFSET(26) NUMBITS(1),
112
113 PENDSTCLR OFFSET(25) NUMBITS(1),
116
117 ISRPREEMPT OFFSET(23) NUMBITS(1),
120
121 ISRPENDING OFFSET(22) NUMBITS(1),
124
125 VECTACTIVE OFFSET(0) NUMBITS(9)
128 ],
129
130 VectorTableOffset [
133 TBLOFF OFFSET(7) NUMBITS(25)
136 ],
137
138 ApplicationInterruptAndReset [
139 VECTKEY OFFSET(16) NUMBITS(16),
142
143 ENDIANNESS OFFSET(15) NUMBITS(1),
146
147 PRIGROUP OFFSET(8) NUMBITS(3),
150
151 SYSRESETREQ OFFSET(2) NUMBITS(1),
154
155 VECTCLRACTIVE OFFSET(1) NUMBITS(1),
159
160 VECTRESET OFFSET(0) NUMBITS(1)
165 ],
166
167 SystemControl [
168 SEVONPEND OFFSET(4) NUMBITS(1),
169 SLEEPDEEP OFFSET(2) NUMBITS(1),
170 SLEEPONEXIT OFFSET(1) NUMBITS(1)
171 ],
172
173 ConfigurationAndControl [
174 STKALIGN OFFSET(9) NUMBITS(1),
175 BFHFNMIGN OFFSET(8) NUMBITS(1),
176 DIV_0_TRAP OFFSET(4) NUMBITS(1),
177 UNALIGN_TRP OFFSET(3) NUMBITS(1),
178 USERSETMPEND OFFSET(1) NUMBITS(1),
179 NONBASETHRDENA OFFSET(0) NUMBITS(1)
180 ],
181
182 SystemHandlerPriority [
184 PRI_N3 OFFSET(24) NUMBITS(4),
185 PRI_N2 OFFSET(16) NUMBITS(4),
186 PRI_N1 OFFSET(8) NUMBITS(4),
187 PRI_N0 OFFSET(0) NUMBITS(4)
188 ],
189
190 SystemHandlerControlAndState [
191 USGFAULTENA OFFSET(18) NUMBITS(1),
192 BUSFAULTENA OFFSET(17) NUMBITS(1),
193 MEMFAULTENA OFFSET(16) NUMBITS(1),
194 SVCALLPENDED OFFSET(15) NUMBITS(1),
195 BUSFAULTPENDED OFFSET(14) NUMBITS(1),
196 MEMFAULTPENDED OFFSET(14) NUMBITS(1),
197 USGFAULTPENDED OFFSET(14) NUMBITS(1),
198 SYSTICKACT OFFSET(11) NUMBITS(1),
199 PENDSVACT OFFSET(10) NUMBITS(1),
200 MONITORACT OFFSET(8) NUMBITS(1),
201 SVCALLACT OFFSET(7) NUMBITS(1),
202 USGFAULTACT OFFSET(3) NUMBITS(1),
203 BUSFAULTACT OFFSET(1) NUMBITS(1),
204 MEMFAULTACT OFFSET(0) NUMBITS(1)
205 ],
206
207 ConfigurableFaultStatus [
208 UsageFault OFFSET(16) NUMBITS(16),
209 BusFault OFFSET(8) NUMBITS(8),
210 MemManage OFFSET(0) NUMBITS(8)
211 ],
212
213 MemManageStatus [
214 MMARVALID OFFSET(7) NUMBITS(1),
215 MLSPERR OFFSET(5) NUMBITS(1),
216 MSTKERR OFFSET(4) NUMBITS(1),
217 MUNSTKERR OFFSET(3) NUMBITS(1),
218 DACCVIOL OFFSET(1) NUMBITS(1),
219 IACCVIOL OFFSET(1) NUMBITS(1)
220 ],
221
222 BusFaultStatus [
223 BFARVALID OFFSET(7) NUMBITS(1),
224 LSPERR OFFSET(5) NUMBITS(1),
225 STKERR OFFSET(4) NUMBITS(1),
226 UNSTKERR OFFSET(3) NUMBITS(1),
227 IMPRECISERR OFFSET(2) NUMBITS(1),
228 PRECISERR OFFSET(1) NUMBITS(1),
229 IBUSERR OFFSET(0) NUMBITS(1)
230 ],
231
232 UsageFaultStatus [
233 DIVBYZERO OFFSET(9) NUMBITS(1),
234 UNALIGNED OFFSET(8) NUMBITS(1),
235 NOCP OFFSET(3) NUMBITS(1),
236 INVPC OFFSET(2) NUMBITS(1),
237 INVSTATE OFFSET(1) NUMBITS(1),
238 UNDEFINSTR OFFSET(0) NUMBITS(1)
239 ],
240
241 HardFaultStatus [
242 DEBUGEVT OFFSET(31) NUMBITS(1),
243 FORCED OFFSET(30) NUMBITS(1),
244 VECTTBL OFFSET(1) NUMBITS(1)
245 ],
246
247 DebugFaultStatus [
248 EXTERNAL OFFSET(4) NUMBITS(1),
249 VCATCH OFFSET(3) NUMBITS(1),
250 DWTTRAP OFFSET(2) NUMBITS(1),
251 BKPT OFFSET(1) NUMBITS(1),
252 HALTED OFFSET(0) NUMBITS(1)
253 ],
254
255 FaultAddress [
256 ADDRESS OFFSET(0) NUMBITS(32)
257 ],
258
259 CoprocessorAccessControl [
260 CP11 OFFSET(22) NUMBITS(2),
261 CP10 OFFSET(20) NUMBITS(2),
262 CP7 OFFSET(14) NUMBITS(2),
263 CP6 OFFSET(12) NUMBITS(2),
264 CP5 OFFSET(10) NUMBITS(2),
265 CP4 OFFSET(8) NUMBITS(2),
266 CP3 OFFSET(6) NUMBITS(2),
267 CP2 OFFSET(4) NUMBITS(2),
268 CP1 OFFSET(2) NUMBITS(2),
269 CP0 OFFSET(0) NUMBITS(2)
270 ]
271];
272
273const SCB: StaticRef<ScbRegisters> = unsafe { StaticRef::new(0xE000ED00 as *const ScbRegisters) };
274
275#[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
279pub unsafe fn set_sleepdeep() {
280 use core::arch::asm;
281
282 SCB.scr.modify(SystemControl::SLEEPDEEP::SET);
283
284 asm!("dsb", "isb", options(nomem, nostack, preserves_flags));
285}
286
287#[cfg(not(any(doc, all(target_arch = "arm", target_os = "none"))))]
289pub unsafe fn set_sleepdeep() {
290 SCB.scr.modify(SystemControl::SLEEPDEEP::SET);
293
294 unimplemented!()
295}
296
297pub unsafe fn unset_sleepdeep() {
301 SCB.scr.modify(SystemControl::SLEEPDEEP::CLEAR);
302}
303
304pub unsafe fn reset() {
306 SCB.aircr.modify(
307 ApplicationInterruptAndReset::VECTKEY.val(0x05FA)
308 + ApplicationInterruptAndReset::PRIGROUP.val(0b111)
309 + ApplicationInterruptAndReset::SYSRESETREQ::SET,
310 );
311}
312
313pub unsafe fn set_vector_table_offset(offset: *const ()) {
315 SCB.vtor.set(offset as u32);
316}
317
318#[cfg(any(doc, all(target_arch = "arm", target_os = "none")))]
320pub unsafe fn disable_fpca() {
321 use core::arch::asm;
322 SCB.cpacr
323 .modify(CoprocessorAccessControl::CP10::CLEAR + CoprocessorAccessControl::CP11::CLEAR);
324
325 asm!("dsb", "isb", options(nomem, nostack, preserves_flags));
326
327 if SCB.cpacr.read(CoprocessorAccessControl::CP10) != 0
328 || SCB.cpacr.read(CoprocessorAccessControl::CP11) != 0
329 {
330 panic!("Unable to disable FPU");
331 }
332}
333
334#[cfg(not(any(doc, all(target_arch = "arm", target_os = "none"))))]
336pub unsafe fn disable_fpca() {
337 let _ = SCB.cpacr.read(CoprocessorAccessControl::CP10);
340
341 unimplemented!()
342}