Skip to main content

aarch32_cpu/register/
mod.rs

1//! Defines various AArch32 system registers
2//!
3//! These are all ready using Co-Processor read/write instructions
4
5pub mod actlr;
6pub mod actlr2;
7pub mod adfsr;
8pub mod aidr;
9pub mod aifsr;
10pub mod amair0;
11pub mod amair1;
12pub mod bpiall;
13pub mod ccsidr;
14pub mod clidr;
15pub mod contextidr;
16pub mod cpacr;
17pub mod cpsr;
18pub mod csselr;
19pub mod ctr;
20pub mod dacr;
21pub mod dc_sw_ops;
22pub mod dccimvac;
23pub mod dccisw;
24pub mod dccmvac;
25pub mod dccmvau;
26pub mod dccsw;
27pub mod dcimvac;
28pub mod dcisw;
29pub mod dfar;
30#[cfg(all(target_arch = "arm", not(arm_architecture = "v4t")))]
31pub mod dfsr;
32pub mod dlr;
33pub mod dracr;
34pub mod drbar;
35pub mod drsr;
36pub mod dspsr;
37pub mod fcseidr;
38pub mod icc_pmr;
39pub mod iciallu;
40pub mod id_afr0;
41pub mod id_dfr0;
42pub mod id_isar0;
43pub mod id_isar1;
44pub mod id_isar2;
45pub mod id_isar3;
46pub mod id_isar4;
47pub mod id_isar5;
48pub mod id_mmfr0;
49pub mod id_mmfr1;
50pub mod id_mmfr2;
51pub mod id_mmfr3;
52pub mod id_mmfr4;
53pub mod id_pfr0;
54pub mod id_pfr1;
55pub mod ifar;
56#[cfg(all(target_arch = "arm", not(arm_architecture = "v4t")))]
57pub mod ifsr;
58pub mod imp;
59pub mod iracr;
60pub mod irbar;
61pub mod irsr;
62pub mod mair0;
63pub mod mair1;
64pub mod midr;
65pub mod mpidr;
66pub mod mpuir;
67pub mod nsacr;
68pub mod par;
69pub mod pmccfiltr;
70pub mod pmccntr;
71pub mod pmceid0;
72pub mod pmceid1;
73pub mod pmcntenclr;
74pub mod pmcntenset;
75pub mod pmcr;
76pub mod pmevcntr0;
77pub mod pmevcntr1;
78pub mod pmevcntr2;
79pub mod pmevcntr3;
80pub mod pmevtyper0;
81pub mod pmevtyper1;
82pub mod pmevtyper2;
83pub mod pmevtyper3;
84pub mod pmintenclr;
85pub mod pmintenset;
86pub mod pmovsr;
87pub mod pmovsset;
88pub mod pmselr;
89pub mod pmswinc;
90pub mod pmuserenr;
91pub mod pmxevcntr;
92pub mod pmxevtyper;
93pub mod revidr;
94pub mod rgnr;
95pub mod rvbar;
96pub mod sctlr;
97pub mod tcmtr;
98pub mod tlbiall;
99pub mod tlbtr;
100pub mod tpidrprw;
101pub mod tpidruro;
102pub mod tpidrurw;
103pub mod ttbr0;
104#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
105pub mod vbar;
106pub mod vmpidr;
107pub mod vpidr;
108pub mod vsctlr;
109
110pub use actlr::Actlr;
111pub use actlr2::Actlr2;
112pub use adfsr::Adfsr;
113pub use aidr::Aidr;
114pub use aifsr::Aifsr;
115pub use amair0::Amair0;
116pub use amair1::Amair1;
117pub use bpiall::BpIAll;
118pub use ccsidr::Ccsidr;
119pub use clidr::Clidr;
120pub use contextidr::Contextidr;
121pub use cpacr::Cpacr;
122pub use cpsr::Cpsr;
123pub use csselr::Csselr;
124pub use ctr::Ctr;
125pub use dacr::Dacr;
126pub use dccimvac::Dccimvac;
127pub use dccisw::Dccisw;
128pub use dccmvac::Dccmvac;
129pub use dccmvau::Dccmvau;
130pub use dccsw::Dccsw;
131pub use dcimvac::Dcimvac;
132pub use dcisw::Dcisw;
133pub use dfar::Dfar;
134#[cfg(all(target_arch = "arm", not(arm_architecture = "v4t")))]
135pub use dfsr::Dfsr;
136pub use dlr::Dlr;
137pub use dracr::Dracr;
138pub use drbar::Drbar;
139pub use drsr::Drsr;
140pub use dspsr::Dspsr;
141pub use fcseidr::Fcseidr;
142pub use icc_pmr::IccPmr;
143pub use iciallu::Iciallu;
144pub use id_afr0::IdAfr0;
145pub use id_dfr0::IdDfr0;
146pub use id_isar0::IdIsar0;
147pub use id_isar1::IdIsar1;
148pub use id_isar2::IdIsar2;
149pub use id_isar3::IdIsar3;
150pub use id_isar4::IdIsar4;
151pub use id_isar5::IdIsar5;
152pub use id_mmfr0::IdMmfr0;
153pub use id_mmfr1::IdMmfr1;
154pub use id_mmfr2::IdMmfr2;
155pub use id_mmfr3::IdMmfr3;
156pub use id_mmfr4::IdMmfr4;
157pub use id_pfr0::IdPfr0;
158pub use id_pfr1::IdPfr1;
159pub use ifar::Ifar;
160#[cfg(all(target_arch = "arm", not(arm_architecture = "v4t")))]
161pub use ifsr::Ifsr;
162pub use iracr::Iracr;
163pub use irbar::Irbar;
164pub use irsr::Irsr;
165pub use mair0::{Mair, Mair0};
166pub use mair1::Mair1;
167pub use midr::Midr;
168pub use mpidr::Mpidr;
169pub use mpuir::Mpuir;
170pub use nsacr::Nsacr;
171pub use par::Par;
172pub use pmccfiltr::Pmccfiltr;
173pub use pmccntr::Pmccntr;
174pub use pmceid0::Pmceid0;
175pub use pmceid1::Pmceid1;
176pub use pmcntenclr::Pmcntenclr;
177pub use pmcntenset::Pmcntenset;
178pub use pmcr::Pmcr;
179pub use pmevcntr0::Pmevcntr0;
180pub use pmevcntr1::Pmevcntr1;
181pub use pmevcntr2::Pmevcntr2;
182pub use pmevcntr3::Pmevcntr3;
183pub use pmevtyper0::Pmevtyper0;
184pub use pmevtyper1::Pmevtyper1;
185pub use pmevtyper2::Pmevtyper2;
186pub use pmevtyper3::Pmevtyper3;
187pub use pmintenclr::Pmintenclr;
188pub use pmintenset::Pmintenset;
189pub use pmovsr::Pmovsr;
190pub use pmovsset::Pmovsset;
191pub use pmselr::Pmselr;
192pub use pmswinc::Pmswinc;
193pub use pmuserenr::Pmuserenr;
194pub use pmxevcntr::Pmxevcntr;
195pub use pmxevtyper::Pmxevtyper;
196pub use revidr::Revidr;
197pub use rgnr::Rgnr;
198pub use rvbar::Rvbar;
199pub use sctlr::Sctlr;
200pub use tcmtr::Tcmtr;
201pub use tlbiall::TlbIAll;
202pub use tlbtr::Tlbtr;
203pub use tpidrprw::Tpidrprw;
204pub use tpidruro::Tpidruro;
205pub use tpidrurw::Tpidrurw;
206pub use ttbr0::Ttbr0;
207#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
208pub use vbar::Vbar;
209pub use vmpidr::Vmpidr;
210pub use vpidr::Vpidr;
211pub use vsctlr::Vsctlr;
212
213#[cfg(any(test, arm_architecture = "v8-r"))]
214mod armv8r;
215#[cfg(any(test, arm_architecture = "v8-r"))]
216#[doc(inline)]
217pub use armv8r::*;
218
219#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
220pub mod hyp;
221#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
222pub use hyp::*;
223
224#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
225pub mod generic_timer;
226#[cfg(any(test, doc, arm_architecture = "v7-a", arm_architecture = "v8-r"))]
227pub use generic_timer::*;
228
229pub use imp::*;
230
231/// Describes a 32-bit System Register
232pub trait SysReg {
233    /// Which Co-Processor (e.g. 15 for CP15) is this register in?
234    const CP: u32;
235    /// Which CRn argument (e.g. 0 for c0) accesses this register
236    const CRN: u32;
237    /// Which OP1 argument accesses this register
238    const OP1: u32;
239    /// Which CRm argument (e.g. 1 for c1) accesses this register
240    const CRM: u32;
241    /// Which OP2 argument accesses this register
242    const OP2: u32;
243}
244
245/// Readable 32-bit System Registers
246pub trait SysRegRead: SysReg {
247    /// Read a value from this 32-bit register
248    ///
249    /// Our working assumption is that no Arm system register read has
250    /// side-effects that can cause Undefined Behaviour, so this method
251    /// is safe.
252    #[cfg_attr(not(feature = "check-asm"), inline)]
253    #[cfg_attr(
254        any(
255            arm_architecture = "v4t",
256            arm_architecture = "v5te",
257            arm_architecture = "v6"
258        ),
259        instruction_set(arm::a32)
260    )]
261    fn read_raw() -> u32 {
262        let r: u32;
263        #[cfg(target_arch = "arm")]
264        unsafe {
265            core::arch::asm!(
266                "mrc p{cp}, {op1}, {reg}, c{crn}, c{crm}, {op2}",
267                cp = const Self::CP,
268                op1 = const Self::OP1,
269                reg = out(reg) r,
270                crn = const Self::CRN,
271                crm = const Self::CRM,
272                op2 = const Self::OP2,
273                options(nomem, nostack, preserves_flags)
274            );
275        }
276        #[cfg(not(target_arch = "arm"))]
277        {
278            r = 0;
279        }
280        r
281    }
282}
283
284/// Writable 32-bit System Registers
285pub trait SysRegWrite: SysReg {
286    /// Write a value to this 32-bit register
287    ///
288    /// # Safety
289    ///
290    /// You need to read the Architecture Reference Manual to verify that you are
291    /// writing valid data here.
292    #[cfg_attr(not(feature = "check-asm"), inline)]
293    #[cfg_attr(
294        any(
295            arm_architecture = "v4t",
296            arm_architecture = "v5te",
297            arm_architecture = "v6"
298        ),
299        instruction_set(arm::a32)
300    )]
301    unsafe fn write_raw(_value: u32) {
302        #[cfg(target_arch = "arm")]
303        unsafe {
304            core::arch::asm!(
305                "mcr p{cp}, {op1}, {reg}, c{crn}, c{crm}, {op2}",
306                cp = const Self::CP,
307                op1 = const Self::OP1,
308                reg = in(reg) _value,
309                crn = const Self::CRN,
310                crm = const Self::CRM,
311                op2 = const Self::OP2,
312                options(nomem, nostack, preserves_flags)
313            );
314        }
315    }
316}
317
318/// Describes a 64-bit System Register
319pub trait SysReg64 {
320    /// Which Co-Processor (e.g. 15 for CP15) is this register in?
321    const CP: u32;
322    /// Which OP1 argument accesses this register
323    const OP1: u32;
324    /// Which CRm argument (e.g. 1 for c1) accesses this register
325    const CRM: u32;
326}
327
328/// Readable 64-bit System Registers
329pub trait SysRegRead64: SysReg64 {
330    /// Read a value from this 64-bit register
331    ///
332    /// Our working assumption is that no Arm system register read has
333    /// side-effects that can cause Undefined Behaviour, so this method
334    /// is safe.
335    #[inline]
336    fn read_raw() -> u64 {
337        let r_lo: u32;
338        let r_hi: u32;
339        #[cfg(target_arch = "arm")]
340        unsafe {
341            core::arch::asm!(
342                "mrrc p{cp}, {op1}, {rt}, {rt2}, c{crm}",
343                cp = const Self::CP,
344                op1 = const Self::OP1,
345                rt = out(reg) r_lo,
346                rt2 = out(reg) r_hi,
347                crm = const Self::CRM,
348                options(nomem, nostack, preserves_flags)
349            );
350        }
351        #[cfg(not(target_arch = "arm"))]
352        {
353            r_lo = 0;
354            r_hi = 0;
355        }
356        ((r_hi as u64) << 32) | (r_lo as u64)
357    }
358}
359
360/// Writable 64-bit System Registers
361pub trait SysRegWrite64: SysReg64 {
362    /// Write a value to this 64-bit register
363    ///
364    /// # Safety
365    ///
366    /// You need to read the Architecture Reference Manual to verify that you are
367    /// writing valid data here.
368    #[inline]
369    unsafe fn write_raw(_value: u64) {
370        #[cfg(target_arch = "arm")]
371        unsafe {
372            let r_lo = _value as u32;
373            let r_hi = (_value >> 32) as u32;
374            core::arch::asm!(
375                "mcrr p{cp}, {op1}, {rt}, {rt2}, c{crm}",
376                cp = const Self::CP,
377                op1 = const Self::OP1,
378                rt = in(reg) r_lo,
379                rt2 = in(reg) r_hi,
380                crm = const Self::CRM,
381                options(nomem, nostack, preserves_flags)
382            );
383        }
384    }
385}