ax_cpu/arch/aarch64/cache.rs
1//! Local cache operations.
2
3pub use super::asm::{dcache_line_size_from_ctr, flush_icache_all, icache_line_size_from_ctr};
4
5/// Data-cache maintenance performed to the point of coherency.
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum DataCacheOperation {
8 /// Writes dirty data back while retaining valid cache lines.
9 Clean,
10 /// Discards cached contents without writing them back.
11 Invalidate,
12 /// Writes dirty contents back and discards the cache lines.
13 CleanInvalidate,
14}
15
16/// Maintains every cache line intersecting a checked virtual byte range.
17/// Completion includes a system DSB and instruction synchronization.
18///
19/// # Safety
20/// Every intersected cache line must be mapped and owned for the operation.
21/// Invalidation must not discard live dirty data or race CPU/device accesses.
22/// The caller owns DMA transfer direction, aliases and platform coherency.
23pub unsafe fn maintain_dcache_to_poc(
24 operation: DataCacheOperation,
25 range: crate::cache::CacheRange,
26) {
27 if range.is_empty() {
28 return;
29 }
30 range.for_each_line(dcache_line_size_from_ctr(), |line| {
31 // SAFETY: the caller retains every complete intersected line and the
32 // checked range iterator cannot wrap into an unrelated address region.
33 unsafe {
34 match operation {
35 DataCacheOperation::Clean => core::arch::asm!("dc cvac, {}", in(reg) line),
36 DataCacheOperation::Invalidate => core::arch::asm!("dc ivac, {}", in(reg) line),
37 DataCacheOperation::CleanInvalidate => {
38 core::arch::asm!("dc civac, {}", in(reg) line)
39 }
40 }
41 }
42 });
43 // SAFETY: complete the cache operations before returning ownership.
44 unsafe { core::arch::asm!("dsb sy; isb", options(nostack)) };
45}
46
47/// Cleans the checked range to the point of unification and completes the writes.
48/// Call `flush_icache_all` before executing the modified instructions.
49///
50/// # Safety
51/// Every intersected cache line must remain mapped and accessible until completion.
52/// The caller must coordinate concurrent modifications and instruction execution.
53pub unsafe fn clean_dcache_range_to_pou(range: crate::cache::CacheRange) {
54 if range.is_empty() {
55 return;
56 }
57 range.for_each_line(dcache_line_size_from_ctr(), |line| {
58 // SAFETY: the caller retains the mapped lines; the checked iterator
59 // visits the final line without rounding the endpoint past usize::MAX.
60 unsafe { core::arch::asm!("dc cvau, {}", in(reg) line, options(nostack)) };
61 });
62 // SAFETY: complete the data-side publication before instruction invalidation.
63 unsafe { core::arch::asm!("dsb ish", options(nostack)) };
64}