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(armv5te_or_higher)]
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(armv5te_or_higher)]
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(armv5te_or_higher)]
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(armv5te_or_higher)]
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(armv6_or_lower, instruction_set(arm::a32))]
254    fn read_raw() -> u32 {
255        let r: u32;
256        #[cfg(target_arch = "arm")]
257        unsafe {
258            core::arch::asm!(
259                "mrc p{cp}, {op1}, {reg}, c{crn}, c{crm}, {op2}",
260                cp = const Self::CP,
261                op1 = const Self::OP1,
262                reg = out(reg) r,
263                crn = const Self::CRN,
264                crm = const Self::CRM,
265                op2 = const Self::OP2,
266                options(nomem, nostack, preserves_flags)
267            );
268        }
269        #[cfg(not(target_arch = "arm"))]
270        {
271            r = 0;
272        }
273        r
274    }
275}
276
277/// Writable 32-bit System Registers
278pub trait SysRegWrite: SysReg {
279    /// Write a value to this 32-bit register
280    ///
281    /// # Safety
282    ///
283    /// You need to read the Architecture Reference Manual to verify that you are
284    /// writing valid data here.
285    #[cfg_attr(not(feature = "check-asm"), inline)]
286    #[cfg_attr(armv6_or_lower, instruction_set(arm::a32))]
287    unsafe fn write_raw(_value: u32) {
288        #[cfg(target_arch = "arm")]
289        unsafe {
290            core::arch::asm!(
291                "mcr p{cp}, {op1}, {reg}, c{crn}, c{crm}, {op2}",
292                cp = const Self::CP,
293                op1 = const Self::OP1,
294                reg = in(reg) _value,
295                crn = const Self::CRN,
296                crm = const Self::CRM,
297                op2 = const Self::OP2,
298                options(nomem, nostack, preserves_flags)
299            );
300        }
301    }
302}
303
304/// Describes a 64-bit System Register
305pub trait SysReg64 {
306    /// Which Co-Processor (e.g. 15 for CP15) is this register in?
307    const CP: u32;
308    /// Which OP1 argument accesses this register
309    const OP1: u32;
310    /// Which CRm argument (e.g. 1 for c1) accesses this register
311    const CRM: u32;
312}
313
314/// Readable 64-bit System Registers
315pub trait SysRegRead64: SysReg64 {
316    /// Read a value from this 64-bit register
317    ///
318    /// Our working assumption is that no Arm system register read has
319    /// side-effects that can cause Undefined Behaviour, so this method
320    /// is safe.
321    #[inline]
322    fn read_raw() -> u64 {
323        let r_lo: u32;
324        let r_hi: u32;
325        #[cfg(target_arch = "arm")]
326        unsafe {
327            core::arch::asm!(
328                "mrrc p{cp}, {op1}, {rt}, {rt2}, c{crm}",
329                cp = const Self::CP,
330                op1 = const Self::OP1,
331                rt = out(reg) r_lo,
332                rt2 = out(reg) r_hi,
333                crm = const Self::CRM,
334                options(nomem, nostack, preserves_flags)
335            );
336        }
337        #[cfg(not(target_arch = "arm"))]
338        {
339            r_lo = 0;
340            r_hi = 0;
341        }
342        ((r_hi as u64) << 32) | (r_lo as u64)
343    }
344}
345
346/// Writable 64-bit System Registers
347pub trait SysRegWrite64: SysReg64 {
348    /// Write a value to this 64-bit register
349    ///
350    /// # Safety
351    ///
352    /// You need to read the Architecture Reference Manual to verify that you are
353    /// writing valid data here.
354    #[inline]
355    unsafe fn write_raw(_value: u64) {
356        #[cfg(target_arch = "arm")]
357        unsafe {
358            let r_lo = _value as u32;
359            let r_hi = (_value >> 32) as u32;
360            core::arch::asm!(
361                "mcrr p{cp}, {op1}, {rt}, {rt2}, c{crm}",
362                cp = const Self::CP,
363                op1 = const Self::OP1,
364                rt = in(reg) r_lo,
365                rt2 = in(reg) r_hi,
366                crm = const Self::CRM,
367                options(nomem, nostack, preserves_flags)
368            );
369        }
370    }
371}