cortex_m/peripheral/
cpuid.rs1use volatile_register::RO;
4#[cfg(not(armv6m))]
5use volatile_register::RW;
6
7#[cfg(not(armv6m))]
8use crate::peripheral::CPUID;
9
10#[repr(C)]
12pub struct RegisterBlock {
13    pub base: RO<u32>,
15
16    _reserved0: [u32; 15],
17
18    #[cfg(not(armv6m))]
20    pub pfr: [RO<u32>; 2],
21    #[cfg(armv6m)]
22    _reserved1: [u32; 2],
23
24    #[cfg(not(armv6m))]
26    pub dfr: RO<u32>,
27    #[cfg(armv6m)]
28    _reserved2: u32,
29
30    #[cfg(not(armv6m))]
32    pub afr: RO<u32>,
33    #[cfg(armv6m)]
34    _reserved3: u32,
35
36    #[cfg(not(armv6m))]
38    pub mmfr: [RO<u32>; 4],
39    #[cfg(armv6m)]
40    _reserved4: [u32; 4],
41
42    #[cfg(not(armv6m))]
44    pub isar: [RO<u32>; 5],
45    #[cfg(armv6m)]
46    _reserved5: [u32; 5],
47
48    _reserved6: u32,
49
50    #[cfg(not(armv6m))]
52    pub clidr: RO<u32>,
53
54    #[cfg(not(armv6m))]
56    pub ctr: RO<u32>,
57
58    #[cfg(not(armv6m))]
60    pub ccsidr: RO<u32>,
61
62    #[cfg(not(armv6m))]
64    pub csselr: RW<u32>,
65}
66
67#[cfg(not(armv6m))]
69#[derive(Copy, Clone, Debug, PartialEq, Eq)]
70pub enum CsselrCacheType {
71    DataOrUnified = 0,
73    Instruction = 1,
75}
76
77#[cfg(not(armv6m))]
78impl CPUID {
79    #[inline]
86    pub fn select_cache(&mut self, level: u8, ind: CsselrCacheType) {
87        const CSSELR_IND_POS: u32 = 0;
88        const CSSELR_IND_MASK: u32 = 1 << CSSELR_IND_POS;
89        const CSSELR_LEVEL_POS: u32 = 1;
90        const CSSELR_LEVEL_MASK: u32 = 0x7 << CSSELR_LEVEL_POS;
91
92        unsafe {
93            self.csselr.write(
94                ((u32::from(level) << CSSELR_LEVEL_POS) & CSSELR_LEVEL_MASK)
95                    | (((ind as u32) << CSSELR_IND_POS) & CSSELR_IND_MASK),
96            )
97        }
98    }
99
100    #[inline]
102    pub fn cache_num_sets_ways(&mut self, level: u8, ind: CsselrCacheType) -> (u16, u16) {
103        const CCSIDR_NUMSETS_POS: u32 = 13;
104        const CCSIDR_NUMSETS_MASK: u32 = 0x7FFF << CCSIDR_NUMSETS_POS;
105        const CCSIDR_ASSOCIATIVITY_POS: u32 = 3;
106        const CCSIDR_ASSOCIATIVITY_MASK: u32 = 0x3FF << CCSIDR_ASSOCIATIVITY_POS;
107
108        self.select_cache(level, ind);
109        crate::asm::dsb();
110        let ccsidr = self.ccsidr.read();
111        (
112            (1 + ((ccsidr & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_POS)) as u16,
113            (1 + ((ccsidr & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_POS)) as u16,
114        )
115    }
116
117    #[inline(always)]
122    pub fn cache_dminline() -> u32 {
123        const CTR_DMINLINE_POS: u32 = 16;
124        const CTR_DMINLINE_MASK: u32 = 0xF << CTR_DMINLINE_POS;
125        let ctr = unsafe { (*Self::PTR).ctr.read() };
126        (ctr & CTR_DMINLINE_MASK) >> CTR_DMINLINE_POS
127    }
128
129    #[inline(always)]
134    pub fn cache_iminline() -> u32 {
135        const CTR_IMINLINE_POS: u32 = 0;
136        const CTR_IMINLINE_MASK: u32 = 0xF << CTR_IMINLINE_POS;
137        let ctr = unsafe { (*Self::PTR).ctr.read() };
138        (ctr & CTR_IMINLINE_MASK) >> CTR_IMINLINE_POS
139    }
140}