Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update and improve cache operations. #192

Merged
merged 4 commits into from
Feb 5, 2020
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 19 additions & 27 deletions src/peripheral/cbp.rs
Original file line number Diff line number Diff line change
@@ -39,34 +39,28 @@ const CBP_SW_SET_MASK: u32 = 0x1FF << CBP_SW_SET_POS;

impl CBP {
/// I-cache invalidate all to PoU
#[inline]
#[inline(always)]
pub fn iciallu(&mut self) {
unsafe {
self.iciallu.write(0);
}
unsafe { self.iciallu.write(0) };
}

/// I-cache invalidate by MVA to PoU
#[inline]
#[inline(always)]
pub fn icimvau(&mut self, mva: u32) {
unsafe {
self.icimvau.write(mva);
}
unsafe { self.icimvau.write(mva) };
}

/// D-cache invalidate by MVA to PoC
#[inline]
pub fn dcimvac(&mut self, mva: u32) {
unsafe {
self.dcimvac.write(mva);
}
#[inline(always)]
pub unsafe fn dcimvac(&mut self, mva: u32) {
self.dcimvac.write(mva);
}

/// D-cache invalidate by set-way
///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline]
pub fn dcisw(&mut self, set: u16, way: u16) {
#[inline(always)]
pub unsafe fn dcisw(&mut self, set: u16, way: u16) {
// The ARMv7-M Architecture Reference Manual, as of Revision E.b, says these set/way
// operations have a register data format which depends on the implementation's
// associativity and number of sets. Specifically the 'way' and 'set' fields have
@@ -76,24 +70,22 @@ impl CBP {
// Generic User Guide section 4.8.3. Since no other ARMv7-M implementations except the
// Cortex-M7 have a DCACHE or ICACHE at all, it seems safe to do the same thing as the
// CMSIS-Core implementation and use fixed values.
unsafe {
self.dcisw.write(
((u32::from(way) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS)
| ((u32::from(set) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS),
);
}
self.dcisw.write(
((u32::from(way) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS)
| ((u32::from(set) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS),
);
}

/// D-cache clean by MVA to PoU
#[inline]
#[inline(always)]
pub fn dccmvau(&mut self, mva: u32) {
unsafe {
self.dccmvau.write(mva);
}
}

/// D-cache clean by MVA to PoC
#[inline]
#[inline(always)]
pub fn dccmvac(&mut self, mva: u32) {
unsafe {
self.dccmvac.write(mva);
@@ -103,7 +95,7 @@ impl CBP {
/// D-cache clean by set-way
///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline]
#[inline(always)]
pub fn dccsw(&mut self, set: u16, way: u16) {
// See comment for dcisw() about the format here
unsafe {
@@ -115,7 +107,7 @@ impl CBP {
}

/// D-cache clean and invalidate by MVA to PoC
#[inline]
#[inline(always)]
pub fn dccimvac(&mut self, mva: u32) {
unsafe {
self.dccimvac.write(mva);
@@ -125,7 +117,7 @@ impl CBP {
/// D-cache clean and invalidate by set-way
///
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
#[inline]
#[inline(always)]
pub fn dccisw(&mut self, set: u16, way: u16) {
// See comment for dcisw() about the format here
unsafe {
@@ -137,7 +129,7 @@ impl CBP {
}

/// Branch predictor invalidate all
#[inline]
#[inline(always)]
pub fn bpiall(&mut self) {
unsafe {
self.bpiall.write(0);
23 changes: 23 additions & 0 deletions src/peripheral/cpuid.rs
Original file line number Diff line number Diff line change
@@ -114,4 +114,27 @@ impl CPUID {
(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.
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
}
}
Loading