-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #65 - japaric:singletons, r=japaric
turn peripherals into scoped singletons See this RFC for details: rust-embedded/svd2rust#157
- Loading branch information
Showing
16 changed files
with
1,359 additions
and
981 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
*.org | ||
*.rs.bk | ||
.#* | ||
Cargo.lock | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
//! Cache and branch predictor maintenance operations | ||
use volatile_register::WO; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
/// I-cache invalidate all to PoU | ||
pub iciallu: WO<u32>, | ||
reserved0: u32, | ||
/// I-cache invalidate by MVA to PoU | ||
pub icimvau: WO<u32>, | ||
/// D-cache invalidate by MVA to PoC | ||
pub dcimvac: WO<u32>, | ||
/// D-cache invalidate by set-way | ||
pub dcisw: WO<u32>, | ||
/// D-cache clean by MVA to PoU | ||
pub dccmvau: WO<u32>, | ||
/// D-cache clean by MVA to PoC | ||
pub dccmvac: WO<u32>, | ||
/// D-cache clean by set-way | ||
pub dccsw: WO<u32>, | ||
/// D-cache clean and invalidate by MVA to PoC | ||
pub dccimvac: WO<u32>, | ||
/// D-cache clean and invalidate by set-way | ||
pub dccisw: WO<u32>, | ||
/// Branch predictor invalidate all | ||
pub bpiall: WO<u32>, | ||
} | ||
|
||
const CBP_SW_WAY_POS: u32 = 30; | ||
const CBP_SW_WAY_MASK: u32 = 0x3 << CBP_SW_WAY_POS; | ||
const CBP_SW_SET_POS: u32 = 5; | ||
const CBP_SW_SET_MASK: u32 = 0x1FF << CBP_SW_SET_POS; | ||
|
||
impl RegisterBlock { | ||
/// I-cache invalidate all to PoU | ||
#[inline(always)] | ||
pub fn iciallu(&self) { | ||
unsafe { | ||
self.iciallu.write(0); | ||
} | ||
} | ||
|
||
/// I-cache invalidate by MVA to PoU | ||
#[inline(always)] | ||
pub fn icimvau(&self, mva: u32) { | ||
unsafe { | ||
self.icimvau.write(mva); | ||
} | ||
} | ||
|
||
/// D-cache invalidate by MVA to PoC | ||
#[inline(always)] | ||
pub fn dcimvac(&self, mva: u32) { | ||
unsafe { | ||
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(always)] | ||
pub fn dcisw(&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 | ||
// offsets 32-log2(ASSOCIATIVITY) and log2(LINELEN) respectively. | ||
// | ||
// However, in Cortex-M7 devices, these offsets are fixed at 30 and 5, as per the Cortex-M7 | ||
// 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( | ||
(((way as u32) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS) | ||
| (((set as u32) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS), | ||
); | ||
} | ||
} | ||
|
||
/// D-cache clean by MVA to PoU | ||
#[inline(always)] | ||
pub fn dccmvau(&self, mva: u32) { | ||
unsafe { | ||
self.dccmvau.write(mva); | ||
} | ||
} | ||
|
||
/// D-cache clean by MVA to PoC | ||
#[inline(always)] | ||
pub fn dccmvac(&self, mva: u32) { | ||
unsafe { | ||
self.dccmvac.write(mva); | ||
} | ||
} | ||
|
||
/// D-cache clean by set-way | ||
/// | ||
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511. | ||
#[inline(always)] | ||
pub fn dccsw(&self, set: u16, way: u16) { | ||
// See comment for dcisw() about the format here | ||
unsafe { | ||
self.dccsw.write( | ||
(((way as u32) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS) | ||
| (((set as u32) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS), | ||
); | ||
} | ||
} | ||
|
||
/// D-cache clean and invalidate by MVA to PoC | ||
#[inline(always)] | ||
pub fn dccimvac(&self, mva: u32) { | ||
unsafe { | ||
self.dccimvac.write(mva); | ||
} | ||
} | ||
|
||
/// D-cache clean and invalidate by set-way | ||
/// | ||
/// `set` is masked to be between 0 and 3, and `way` between 0 and 511. | ||
#[inline(always)] | ||
pub fn dccisw(&self, set: u16, way: u16) { | ||
// See comment for dcisw() about the format here | ||
unsafe { | ||
self.dccisw.write( | ||
(((way as u32) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS) | ||
| (((set as u32) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS), | ||
); | ||
} | ||
} | ||
|
||
/// Branch predictor invalidate all | ||
#[inline(always)] | ||
pub fn bpiall(&self) { | ||
unsafe { | ||
self.bpiall.write(0); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//! CPUID | ||
use volatile_register::RO; | ||
#[cfg(any(armv7m, test))] | ||
use volatile_register::RW; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
/// CPUID base | ||
pub base: RO<u32>, | ||
reserved0: [u32; 15], | ||
/// Processor Feature | ||
pub pfr: [RO<u32>; 2], | ||
/// Debug Feature | ||
pub dfr: RO<u32>, | ||
/// Auxiliary Feature | ||
pub afr: RO<u32>, | ||
/// Memory Model Feature | ||
pub mmfr: [RO<u32>; 4], | ||
/// Instruction Set Attribute | ||
pub isar: [RO<u32>; 5], | ||
reserved1: u32, | ||
/// Cache Level ID | ||
#[cfg(any(armv7m, test))] | ||
pub clidr: RO<u32>, | ||
/// Cache Type | ||
#[cfg(any(armv7m, test))] | ||
pub ctr: RO<u32>, | ||
/// Cache Size ID | ||
#[cfg(any(armv7m, test))] | ||
pub ccsidr: RO<u32>, | ||
/// Cache Size Selection | ||
#[cfg(any(armv7m, test))] | ||
pub csselr: RW<u32>, | ||
} | ||
|
||
/// Type of cache to select on CSSELR writes. | ||
#[cfg(armv7m)] | ||
pub enum CsselrCacheType { | ||
/// Select DCache or unified cache | ||
DataOrUnified = 0, | ||
/// Select ICache | ||
Instruction = 1, | ||
} | ||
|
||
#[cfg(armv7m)] | ||
impl RegisterBlock { | ||
/// 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. | ||
pub fn select_cache(&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( | ||
(((level as u32) << 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 | ||
pub fn cache_num_sets_ways(&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); | ||
::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, | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//! Debug Control Block | ||
use volatile_register::{RW, WO}; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
/// Debug Halting Control and Status | ||
pub dhcsr: RW<u32>, | ||
/// Debug Core Register Selector | ||
pub dcrsr: WO<u32>, | ||
/// Debug Core Register Data | ||
pub dcrdr: RW<u32>, | ||
/// Debug Exception and Monitor Control | ||
pub demcr: RW<u32>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
//! Data Watchpoint and Trace unit | ||
use volatile_register::{RO, RW, WO}; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
/// Control | ||
pub ctrl: RW<u32>, | ||
/// Cycle Count | ||
pub cyccnt: RW<u32>, | ||
/// CPI Count | ||
pub cpicnt: RW<u32>, | ||
/// Exception Overhead Count | ||
pub exccnt: RW<u32>, | ||
/// Sleep Count | ||
pub sleepcnt: RW<u32>, | ||
/// LSU Count | ||
pub lsucnt: RW<u32>, | ||
/// Folded-instruction Count | ||
pub foldcnt: RW<u32>, | ||
/// Program Counter Sample | ||
pub pcsr: RO<u32>, | ||
/// Comparators | ||
pub c: [Comparator; 16], | ||
reserved: [u32; 932], | ||
/// Lock Access | ||
pub lar: WO<u32>, | ||
/// Lock Status | ||
pub lsr: RO<u32>, | ||
} | ||
|
||
impl RegisterBlock { | ||
/// Enables the cycle counter | ||
pub fn enable_cycle_counter(&self) { | ||
unsafe { self.ctrl.modify(|r| r | 1) } | ||
} | ||
} | ||
|
||
/// Comparator | ||
#[repr(C)] | ||
pub struct Comparator { | ||
/// Comparator | ||
pub comp: RW<u32>, | ||
/// Comparator Mask | ||
pub mask: RW<u32>, | ||
/// Comparator Function | ||
pub function: RW<u32>, | ||
reserved: u32, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//! Flash Patch and Breakpoint unit | ||
use volatile_register::{RO, RW, WO}; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
/// Control | ||
pub ctrl: RW<u32>, | ||
/// Remap | ||
pub remap: RW<u32>, | ||
/// Comparator | ||
pub comp: [RW<u32>; 127], | ||
reserved: [u32; 875], | ||
/// Lock Access | ||
pub lar: WO<u32>, | ||
/// Lock Status | ||
pub lsr: RO<u32>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//! Floating Point Unit | ||
#[cfg(any(has_fpu, test))] | ||
use volatile_register::{RO, RW}; | ||
|
||
/// Register block | ||
#[repr(C)] | ||
pub struct RegisterBlock { | ||
reserved: u32, | ||
/// Floating Point Context Control | ||
#[cfg(any(has_fpu, test))] | ||
pub fpccr: RW<u32>, | ||
/// Floating Point Context Address | ||
#[cfg(any(has_fpu, test))] | ||
pub fpcar: RW<u32>, | ||
/// Floating Point Default Status Control | ||
#[cfg(any(has_fpu, test))] | ||
pub fpdscr: RW<u32>, | ||
/// Media and FP Feature | ||
#[cfg(any(has_fpu, test))] | ||
pub mvfr: [RO<u32>; 3], | ||
} |
Oops, something went wrong.