aarch32_cpu/register/armv8r/
cntkctl.rs

1//! Code for managing CNTKCTL (*Counter-timer Kernel Control Register*)
2
3use arbitrary_int::u4;
4
5use crate::register::{SysReg, SysRegRead, SysRegWrite};
6
7/// CNTKCTL (*Counter-timer Kernel Control Register*)
8#[bitbybit::bitfield(u32, defmt_bitfields(feature = "defmt"))]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Cntkctl {
11    /// Controls whether the physical timer registers are accessible from EL0
12    /// modes.
13    #[bits(9..=9, rw)]
14    el0pten: bool,
15    /// Controls whether the virtual timer registers are accessible from EL0
16    /// modes.
17    #[bits(8..=8, rw)]
18    el0vten: bool,
19    /// Selects which bit of CNTVCT is the trigger for the event stream
20    /// generated from the virtual counter, when that stream is enabled.
21    #[bits(4..=7, rw)]
22    evnti: u4,
23    /// Controls which transition of the CNTVCT trigger bit, defined by EVNTI,
24    /// generates an event, when the event stream is enabled.
25    ///
26    /// * true: a 1-0 transition
27    /// * false: a 0-1 transition
28    #[bits(3..=3, rw)]
29    evntdir: bool,
30    /// Enables the generation of an event stream from the virtual counter.
31    #[bits(2..=2, rw)]
32    evnten: bool,
33    /// Controls whether the virtual counter, CNTVCT, and the frequency register
34    /// CNTFRQ, are accessible from EL0 modes.
35    #[bits(1..=1, rw)]
36    el0vcten: bool,
37    /// Controls whether the physical counter, CNTPCT, and the frequency
38    /// register CNTFRQ, are accessible from EL0 modes.
39    #[bits(0..=0, rw)]
40    el0pcten: bool,
41}
42
43impl core::fmt::Debug for Cntkctl {
44    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
45        f.debug_struct("Cntkctl")
46            .field("el0pten", &self.el0pten())
47            .field("el0vten", &self.el0vten())
48            .field("evnti", &self.evnti())
49            .field("evntdir", &self.evntdir())
50            .field("evnten", &self.evnten())
51            .field("el0vcten", &self.el0vcten())
52            .field("el0pcten", &self.el0pcten())
53            .finish()
54    }
55}
56
57impl SysReg for Cntkctl {
58    const CP: u32 = 15;
59    const CRN: u32 = 14;
60    const OP1: u32 = 0;
61    const CRM: u32 = 1;
62    const OP2: u32 = 0;
63}
64
65impl SysRegRead for Cntkctl {}
66
67impl Cntkctl {
68    #[inline]
69    /// Reads CNTKCTL (*Counter-timer Kernel Control Register*)
70    pub fn read() -> Cntkctl {
71        unsafe { Self::new_with_raw_value(<Self as SysRegRead>::read_raw()) }
72    }
73}
74
75impl SysRegWrite for Cntkctl {}
76
77impl Cntkctl {
78    #[inline]
79    /// Writes CNTKCTL (*Counter-timer Kernel Control Register*)
80    pub fn write(value: Self) {
81        unsafe {
82            <Self as SysRegWrite>::write_raw(value.raw_value());
83        }
84    }
85
86    #[inline]
87    /// Modifies CNTKCTL (*Counter-timer Kernel Control Register*)
88    pub fn modify<F>(f: F)
89    where
90        F: FnOnce(&mut Self),
91    {
92        let mut value = Self::read();
93        f(&mut value);
94        Self::write(value);
95    }
96}