cortex_m/peripheral/cpuid.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
//! CPUID
use volatile_register::RO;
#[cfg(not(armv6m))]
use volatile_register::RW;
#[cfg(not(armv6m))]
use crate::peripheral::CPUID;
/// Register block
#[repr(C)]
pub struct RegisterBlock {
/// CPUID base
pub base: RO<u32>,
_reserved0: [u32; 15],
/// Processor Feature (not present on Cortex-M0 variants)
#[cfg(not(armv6m))]
pub pfr: [RO<u32>; 2],
#[cfg(armv6m)]
_reserved1: [u32; 2],
/// Debug Feature (not present on Cortex-M0 variants)
#[cfg(not(armv6m))]
pub dfr: RO<u32>,
#[cfg(armv6m)]
_reserved2: u32,
/// Auxiliary Feature (not present on Cortex-M0 variants)
#[cfg(not(armv6m))]
pub afr: RO<u32>,
#[cfg(armv6m)]
_reserved3: u32,
/// Memory Model Feature (not present on Cortex-M0 variants)
#[cfg(not(armv6m))]
pub mmfr: [RO<u32>; 4],
#[cfg(armv6m)]
_reserved4: [u32; 4],
/// Instruction Set Attribute (not present on Cortex-M0 variants)
#[cfg(not(armv6m))]
pub isar: [RO<u32>; 5],
#[cfg(armv6m)]
_reserved5: [u32; 5],
_reserved6: u32,
/// Cache Level ID (only present on Cortex-M7)
#[cfg(not(armv6m))]
pub clidr: RO<u32>,
/// Cache Type (only present on Cortex-M7)
#[cfg(not(armv6m))]
pub ctr: RO<u32>,
/// Cache Size ID (only present on Cortex-M7)
#[cfg(not(armv6m))]
pub ccsidr: RO<u32>,
/// Cache Size Selection (only present on Cortex-M7)
#[cfg(not(armv6m))]
pub csselr: RW<u32>,
}
/// Type of cache to select on CSSELR writes.
#[cfg(not(armv6m))]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum CsselrCacheType {
/// Select DCache or unified cache
DataOrUnified = 0,
/// Select ICache
Instruction = 1,
}
#[cfg(not(armv6m))]
impl CPUID {
/// Selects the current CCSIDR
///
/// * `level`: the required cache level minus 1, e.g. 0 for L1, 1 for L2
/// * `ind`: select instruction cache or data/unified cache
///
/// `level` is masked to be between 0 and 7.
#[inline]
pub fn select_cache(&mut self, level: u8, ind: CsselrCacheType) {
const CSSELR_IND_POS: u32 = 0;
const CSSELR_IND_MASK: u32 = 1 << CSSELR_IND_POS;
const CSSELR_LEVEL_POS: u32 = 1;
const CSSELR_LEVEL_MASK: u32 = 0x7 << CSSELR_LEVEL_POS;
unsafe {
self.csselr.write(
((u32::from(level) << CSSELR_LEVEL_POS) & CSSELR_LEVEL_MASK)
| (((ind as u32) << CSSELR_IND_POS) & CSSELR_IND_MASK),
)
}
}
/// Returns the number of sets and ways in the selected cache
#[inline]
pub fn cache_num_sets_ways(&mut self, level: u8, ind: CsselrCacheType) -> (u16, u16) {
const CCSIDR_NUMSETS_POS: u32 = 13;
const CCSIDR_NUMSETS_MASK: u32 = 0x7FFF << CCSIDR_NUMSETS_POS;
const CCSIDR_ASSOCIATIVITY_POS: u32 = 3;
const CCSIDR_ASSOCIATIVITY_MASK: u32 = 0x3FF << CCSIDR_ASSOCIATIVITY_POS;
self.select_cache(level, ind);
crate::asm::dsb();
let ccsidr = self.ccsidr.read();
(
(1 + ((ccsidr & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_POS)) as u16,
(1 + ((ccsidr & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_POS)) as u16,
)
}
/// Returns log2 of the number of words in the smallest cache line of all the data cache and
/// unified caches that are controlled by the processor.
///
/// This is the `DminLine` field of the CTR register.
#[inline(always)]
pub fn cache_dminline() -> u32 {
const CTR_DMINLINE_POS: u32 = 16;
const CTR_DMINLINE_MASK: u32 = 0xF << CTR_DMINLINE_POS;
let ctr = unsafe { (*Self::PTR).ctr.read() };
(ctr & CTR_DMINLINE_MASK) >> CTR_DMINLINE_POS
}
/// Returns log2 of the number of words in the smallest cache line of all the instruction
/// caches that are controlled by the processor.
///
/// This is the `IminLine` field of the CTR register.
#[inline(always)]
pub fn cache_iminline() -> u32 {
const CTR_IMINLINE_POS: u32 = 0;
const CTR_IMINLINE_MASK: u32 = 0xF << CTR_IMINLINE_POS;
let ctr = unsafe { (*Self::PTR).ctr.read() };
(ctr & CTR_IMINLINE_MASK) >> CTR_IMINLINE_POS
}
}