aarch32_cpu/cache.rs
1//! Helper functions for cache operations
2
3use arbitrary_int::u3;
4
5use crate::register::{Dccimvac, Dccisw, Dccmvac, Dccsw, Dcimvac, Dcisw, SysRegWrite};
6
7/// Invalidate the full L1 data cache.
8///
9/// ## Generics
10///
11/// - A: log2(ASSOCIATIVITY) rounded up to the next integer if necessary. For example, a 4-way
12/// associative cache will have a value of 2 and a 8-way associative cache will have a value of
13/// 3.
14/// - N: log2(LINE LENGTH). For example, a 32-byte line length (4 words) will have a value of
15/// 5.
16/// - S: log2(NUM OF SETS). For systems with a fixed cache size, the number of sets can be
17/// calculated using `CACHE SIZE / (LINE LENGTH * ASSOCIATIVITY)`.
18/// For example, a 4-way associative 32kB L1 cache with a 32-byte line length (4 words) will
19/// have 32768 / (32 * 4) == 256 sets and S will have a value of 8.
20#[inline]
21pub fn invalidate_l1_data_cache<const A: usize, const N: usize, const S: usize>() {
22 let ways = 1 << A;
23 let sets = 1 << S;
24
25 for set in 0..sets {
26 for way in 0..ways {
27 unsafe { Dcisw::write(Dcisw::new::<A, N>(way, set, u3::new(0))) };
28 }
29 }
30}
31
32/// Clean the full L1 data cache.
33///
34/// ## Generics
35///
36/// - A: log2(ASSOCIATIVITY) rounded up to the next integer if necessary. For example, a 4-way
37/// associative cache will have a value of 2 and a 8-way associative cache will have a value of
38/// 3.
39/// - N: log2(LINE LENGTH). For example, a 32-byte line length (4 words) will have a value of
40/// 5.
41/// - S: log2(NUM OF SETS). For systems with a fixed cache size, the number of sets can be
42/// calculated using `CACHE SIZE / (LINE LENGTH * ASSOCIATIVITY)`.
43/// For example, a 4-way associative 32kB L1 cache with a 32-byte line length (4 words) will
44/// have 32768 / (32 * 4) == 256 sets and S will have a value of 8.
45#[inline]
46pub fn clean_l1_data_cache<const A: usize, const N: usize, const S: usize>() {
47 let ways = 1 << A;
48 let sets = 1 << S;
49
50 for set in 0..sets {
51 for way in 0..ways {
52 unsafe { Dccsw::write(Dccsw::new::<A, N>(way, set, u3::new(0))) };
53 }
54 }
55}
56
57/// Clean and Invalidate the full L1 data cache.
58///
59/// ## Generics
60///
61/// - A: log2(ASSOCIATIVITY) rounded up to the next integer if necessary. For example, a 4-way
62/// associative cache will have a value of 2 and a 8-way associative cache will have a value of
63/// 3.
64/// - N: log2(LINE LENGTH). For example, a 32-byte line length (4 words) will have a value of
65/// 5.
66/// - S: log2(NUM OF SETS). For systems with a fixed cache size, the number of sets can be
67/// calculated using `CACHE SIZE / (LINE LENGTH * ASSOCIATIVITY)`.
68/// For example, a 4-way associative 32kB L1 cache with a 32-byte line length (4 words) will
69/// have 32768 / (32 * 4) == 256 sets and S will have a value of 8.
70#[inline]
71pub fn clean_and_invalidate_l1_data_cache<const A: usize, const N: usize, const S: usize>() {
72 let ways = 1 << A;
73 let sets = 1 << S;
74
75 for set in 0..sets {
76 for way in 0..ways {
77 unsafe { Dccisw::write(Dccisw::new::<A, N>(way, set, u3::new(0))) };
78 }
79 }
80}
81
82/// Invalidates a data cache line to the point of coherence.
83///
84/// See p.1735 of the ARMv7-A Architecture Reference Manual for more information.
85#[inline]
86pub fn invalidate_data_cache_line_to_poc(addr: u32) {
87 unsafe {
88 Dcimvac::write_raw(addr);
89 }
90}
91
92/// Cleans a data cache line to the point of coherence.
93///
94/// See p.1735 of the ARMv7-A Architecture Reference Manual for more information.
95#[inline]
96pub fn clean_data_cache_line_to_poc(addr: u32) {
97 unsafe {
98 Dccmvac::write_raw(addr);
99 }
100}
101
102/// Cleans and invalidates a data cache line to the point of coherence.
103///
104/// See p.1735 of the ARMv7-A Architecture Reference Manual for more information.
105#[inline]
106pub fn clean_and_invalidate_data_cache_line_to_poc(addr: u32) {
107 unsafe {
108 Dccimvac::write_raw(addr);
109 }
110}