From 64d6e9ee274366bb2af20aaf63b0a5a04648059a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E7=9D=BF?= Date: Mon, 9 Dec 2024 09:27:04 +0800 Subject: [PATCH] Add aarch64 and riscv dcache manage --- modules/axhal/src/arch/aarch64/cache.rs | 53 +++++++++++++++++++++++++ modules/axhal/src/arch/aarch64/mod.rs | 2 + modules/axhal/src/arch/riscv/mod.rs | 16 ++++++++ modules/axhal/src/arch/x86_64/mod.rs | 14 ++++++- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 modules/axhal/src/arch/aarch64/cache.rs diff --git a/modules/axhal/src/arch/aarch64/cache.rs b/modules/axhal/src/arch/aarch64/cache.rs new file mode 100644 index 0000000000..d2636f096e --- /dev/null +++ b/modules/axhal/src/arch/aarch64/cache.rs @@ -0,0 +1,53 @@ +use core::{arch::asm, ptr::NonNull}; + +#[naked] +unsafe extern "C" fn _dcache_invalidate_range(_addr: usize, _end: usize) { + asm!( + "mrs x3, ctr_el0", + "ubfx x3, x3, #16, #4", + "mov x2, #4", + "lsl x2, x2, x3", /* cache line size */ + /* x2 <- minimal cache line size in cache system */ + "sub x3, x2, #1", + "bic x0, x0, x3", + "1: dc ivac, x0", /* invalidate data or unified cache */ + "add x0, x0, x2", + "cmp x0, x1", + "b.lo 1b", + "dsb sy", + "ret", + options(noreturn) + ); +} + +#[naked] +unsafe extern "C" fn _dcache_flush_range(_addr: usize, _end: usize) { + asm!( + "mrs x3, ctr_el0", + "ubfx x3, x3, #16, #4", + "mov x2, #4", + "lsl x2, x2, x3", /* cache line size */ + /* x2 <- minimal cache line size in cache system */ + "sub x3, x2, #1", + "bic x0, x0, x3", + "1: dc civac, x0", /* clean & invalidate data or unified cache */ + "add x0, x0, x2", + "cmp x0, x1", + "b.lo 1b", + "dsb sy", + "ret", + options(noreturn), + ); +} + +/// Invalidate data cache +#[inline] +pub fn dcache_invalidate_range(addr: NonNull, size: usize) { + unsafe { _dcache_invalidate_range(addr.as_ptr() as usize, addr.as_ptr() as usize + size) } +} + +/// Flush data cache +#[inline] +pub fn dcache_flush_range(addr: NonNull, size: usize) { + unsafe { _dcache_flush_range(addr.as_ptr() as usize, addr.as_ptr() as usize + size) } +} diff --git a/modules/axhal/src/arch/aarch64/mod.rs b/modules/axhal/src/arch/aarch64/mod.rs index 160dabdd12..13d456ec97 100644 --- a/modules/axhal/src/arch/aarch64/mod.rs +++ b/modules/axhal/src/arch/aarch64/mod.rs @@ -1,3 +1,4 @@ +mod cache; mod context; pub(crate) mod trap; @@ -8,6 +9,7 @@ use memory_addr::{PhysAddr, VirtAddr}; use tock_registers::interfaces::{Readable, Writeable}; pub use self::context::{FpState, TaskContext, TrapFrame}; +pub use cache::{dcache_flush_range, dcache_invalidate_range}; /// Allows the current CPU to respond to interrupts. #[inline] diff --git a/modules/axhal/src/arch/riscv/mod.rs b/modules/axhal/src/arch/riscv/mod.rs index df6927dddc..8304cf7cbd 100644 --- a/modules/axhal/src/arch/riscv/mod.rs +++ b/modules/axhal/src/arch/riscv/mod.rs @@ -4,6 +4,8 @@ mod macros; mod context; mod trap; +use core::ptr::NonNull; + use memory_addr::{PhysAddr, VirtAddr}; use riscv::asm; use riscv::register::{satp, sstatus, stvec}; @@ -107,3 +109,17 @@ pub fn read_thread_pointer() -> usize { pub unsafe fn write_thread_pointer(tp: usize) { core::arch::asm!("mv tp, {}", in(reg) tp) } + +/// Invalidate data cache +#[inline] +pub fn dcache_invalidate_range(_addr: NonNull, _size: usize) { + // generic no cache and no need op + // TODO: some cpu specific +} + +/// Flush data cache +#[inline] +pub fn dcache_flush_range(_addr: NonNull, _size: usize) { + // generic no cache and no need op + // TODO: some cpu specific +} diff --git a/modules/axhal/src/arch/x86_64/mod.rs b/modules/axhal/src/arch/x86_64/mod.rs index c9002a58d3..7dc889feef 100644 --- a/modules/axhal/src/arch/x86_64/mod.rs +++ b/modules/axhal/src/arch/x86_64/mod.rs @@ -5,7 +5,7 @@ mod idt; #[cfg(target_os = "none")] mod trap; -use core::arch::asm; +use core::{arch::asm, ptr::NonNull}; use memory_addr::{MemoryAddr, PhysAddr, VirtAddr}; use x86::{controlregs, msr, tlb}; @@ -116,3 +116,15 @@ pub fn read_thread_pointer() -> usize { pub unsafe fn write_thread_pointer(fs_base: usize) { unsafe { msr::wrmsr(msr::IA32_FS_BASE, fs_base as u64) } } + +/// Invalidate data cache +#[inline] +pub fn dcache_invalidate_range(addr: NonNull, size: usize) { + unimplemented!() +} + +/// Flush data cache +#[inline] +pub fn dcache_flush_range(addr: NonNull, size: usize) { + unimplemented!() +}