cortex_m/peripheral/cbp.rs
1//! Cache and branch predictor maintenance operations
2//!
3//! *NOTE* Not available on Armv6-M.
4
5use volatile_register::WO;
6
7use crate::peripheral::CBP;
8
9/// Register block
10#[repr(C)]
11pub struct RegisterBlock {
12 /// I-cache invalidate all to PoU
13 pub iciallu: WO<u32>,
14 reserved0: u32,
15 /// I-cache invalidate by MVA to PoU
16 pub icimvau: WO<u32>,
17 /// D-cache invalidate by MVA to PoC
18 pub dcimvac: WO<u32>,
19 /// D-cache invalidate by set-way
20 pub dcisw: WO<u32>,
21 /// D-cache clean by MVA to PoU
22 pub dccmvau: WO<u32>,
23 /// D-cache clean by MVA to PoC
24 pub dccmvac: WO<u32>,
25 /// D-cache clean by set-way
26 pub dccsw: WO<u32>,
27 /// D-cache clean and invalidate by MVA to PoC
28 pub dccimvac: WO<u32>,
29 /// D-cache clean and invalidate by set-way
30 pub dccisw: WO<u32>,
31 /// Branch predictor invalidate all
32 pub bpiall: WO<u32>,
33}
34
35const CBP_SW_WAY_POS: u32 = 30;
36const CBP_SW_WAY_MASK: u32 = 0x3 << CBP_SW_WAY_POS;
37const CBP_SW_SET_POS: u32 = 5;
38const CBP_SW_SET_MASK: u32 = 0x1FF << CBP_SW_SET_POS;
39
40impl CBP {
41 /// I-cache invalidate all to PoU
42 #[inline(always)]
43 pub fn iciallu(&mut self) {
44 unsafe { self.iciallu.write(0) };
45 }
46
47 /// I-cache invalidate by MVA to PoU
48 #[inline(always)]
49 pub fn icimvau(&mut self, mva: u32) {
50 unsafe { self.icimvau.write(mva) };
51 }
52
53 /// D-cache invalidate by MVA to PoC
54 #[inline(always)]
55 pub unsafe fn dcimvac(&mut self, mva: u32) {
56 self.dcimvac.write(mva);
57 }
58
59 /// D-cache invalidate by set-way
60 ///
61 /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
62 #[inline(always)]
63 pub unsafe fn dcisw(&mut self, set: u16, way: u16) {
64 // The ARMv7-M Architecture Reference Manual, as of Revision E.b, says these set/way
65 // operations have a register data format which depends on the implementation's
66 // associativity and number of sets. Specifically the 'way' and 'set' fields have
67 // offsets 32-log2(ASSOCIATIVITY) and log2(LINELEN) respectively.
68 //
69 // However, in Cortex-M7 devices, these offsets are fixed at 30 and 5, as per the Cortex-M7
70 // Generic User Guide section 4.8.3. Since no other ARMv7-M implementations except the
71 // Cortex-M7 have a DCACHE or ICACHE at all, it seems safe to do the same thing as the
72 // CMSIS-Core implementation and use fixed values.
73 self.dcisw.write(
74 ((u32::from(way) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS)
75 | ((u32::from(set) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS),
76 );
77 }
78
79 /// D-cache clean by MVA to PoU
80 #[inline(always)]
81 pub fn dccmvau(&mut self, mva: u32) {
82 unsafe {
83 self.dccmvau.write(mva);
84 }
85 }
86
87 /// D-cache clean by MVA to PoC
88 #[inline(always)]
89 pub fn dccmvac(&mut self, mva: u32) {
90 unsafe {
91 self.dccmvac.write(mva);
92 }
93 }
94
95 /// D-cache clean by set-way
96 ///
97 /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
98 #[inline(always)]
99 pub fn dccsw(&mut self, set: u16, way: u16) {
100 // See comment for dcisw() about the format here
101 unsafe {
102 self.dccsw.write(
103 ((u32::from(way) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS)
104 | ((u32::from(set) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS),
105 );
106 }
107 }
108
109 /// D-cache clean and invalidate by MVA to PoC
110 #[inline(always)]
111 pub fn dccimvac(&mut self, mva: u32) {
112 unsafe {
113 self.dccimvac.write(mva);
114 }
115 }
116
117 /// D-cache clean and invalidate by set-way
118 ///
119 /// `set` is masked to be between 0 and 3, and `way` between 0 and 511.
120 #[inline(always)]
121 pub fn dccisw(&mut self, set: u16, way: u16) {
122 // See comment for dcisw() about the format here
123 unsafe {
124 self.dccisw.write(
125 ((u32::from(way) & (CBP_SW_WAY_MASK >> CBP_SW_WAY_POS)) << CBP_SW_WAY_POS)
126 | ((u32::from(set) & (CBP_SW_SET_MASK >> CBP_SW_SET_POS)) << CBP_SW_SET_POS),
127 );
128 }
129 }
130
131 /// Branch predictor invalidate all
132 #[inline(always)]
133 pub fn bpiall(&mut self) {
134 unsafe {
135 self.bpiall.write(0);
136 }
137 }
138}