diff --git a/kernel/arch/riscv64/src/context.rs b/kernel/arch/riscv64/src/context.rs index 4dc2728f..5a5aacb8 100644 --- a/kernel/arch/riscv64/src/context.rs +++ b/kernel/arch/riscv64/src/context.rs @@ -51,7 +51,9 @@ impl ! { unsafe { self.load_state(); - mem::tlb_flush_full(); __rv64_enter_task(self.inner.get()) } } @@ -162,7 +163,6 @@ impl::block(base.add(j * L2::SIZE), PageAttributes::W); - // tlb_flush_va(DEVICE_MAPPING_OFFSET + (i + j) * L2::SIZE); } } - tlb_flush_full(); - return Ok(DEVICE_MAPPING_OFFSET + i * L2::SIZE); + let start = DEVICE_MAPPING_OFFSET + i * L2::SIZE; + tlb_flush_range_va(start, count * L2::SIZE); + return Ok(start); } Err(Error::OutOfMemory) @@ -221,9 +222,8 @@ pub(crate) unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping todo!(), _ => unimplemented!(), @@ -259,7 +259,7 @@ pub unsafe fn unmap_lower_half() { let mut tables = KERNEL_TABLES.lock(); let kernel_l1i_lower = page_index::(KERNEL_PHYS_BASE); tables.l1.data[kernel_l1i_lower] = 0; - tlb_flush_full(); + tlb_flush_range_va(0x0, L1::SIZE); } /// Sets up run-time kernel translation tables. @@ -301,22 +301,52 @@ pub unsafe fn setup_fixed_tables() { tlb_flush_full(); } +pub fn tlb_flush_global_full() { + tlb_flush_full(); + // TODO send TLB shootdown IPI to other harts +} + +pub fn tlb_flush_global_va(va: usize) { + tlb_flush_va(va); + // TODO send TLB shootdown IPI to other harts +} + +pub fn tlb_flush_range_va(start: usize, size: usize) { + let end = (start + size).page_align_up::(); + let start = start.page_align_down::(); + + for page in (start..end).step_by(L3::SIZE) { + tlb_flush_va(page); + } +} + +pub fn tlb_flush_range_va_asid(asid: usize, start: usize, size: usize) { + let end = (start + size).page_align_up::(); + let start = start.page_align_down::(); + + for page in (start..end).step_by(L3::SIZE) { + tlb_flush_va_asid(page, asid); + } +} + +#[inline] pub fn tlb_flush_full() { - unsafe { - core::arch::asm!("sfence.vma"); - } + unsafe { core::arch::asm!("sfence.vma") }; } +#[inline] pub fn tlb_flush_va(va: usize) { - unsafe { - core::arch::asm!("sfence.vma zero, {0}", in(reg) va); - } + unsafe { core::arch::asm!("sfence.vma {0}, zero", in(reg) va) }; } +#[inline] +pub fn tlb_flush_asid(asid: usize) { + unsafe { core::arch::asm!("sfence.vma zero, {0}", in(reg) asid) }; +} + +#[inline] pub fn tlb_flush_va_asid(va: usize, asid: usize) { - unsafe { - core::arch::asm!("sfence.vma {0}, {1}", in(reg) asid, in(reg) va); - } + unsafe { core::arch::asm!("sfence.vma {0}, {1}", in(reg) va, in(reg) asid) }; } pub fn clone_kernel_tables(dst: &mut PageTable) { diff --git a/kernel/arch/riscv64/src/mem/process.rs b/kernel/arch/riscv64/src/mem/process.rs index 463a8c90..6e89e18f 100644 --- a/kernel/arch/riscv64/src/mem/process.rs +++ b/kernel/arch/riscv64/src/mem/process.rs @@ -110,8 +110,6 @@ impl ProcessAddressSpaceImpl { l3[l3i] = entry; tlb_flush_va_asid(virt, self.asid as usize); - // dc_cvac((&raw const l3[l3i]).addr()); - // tlb_flush_vaae1(virt); Ok(()) } @@ -129,9 +127,6 @@ impl ProcessAddressSpaceImpl { l3[l3i] = PageEntry::INVALID; tlb_flush_va_asid(virt, self.asid as usize); - // ic_iallu(); - // dc_cvac((&raw const l3[l3i]).addr()); - // tlb_flush_vaae1(virt); Ok(page) } @@ -160,6 +155,7 @@ impl ProcessAddressSpaceImpl { impl Drop for ProcessAddressSpaceImpl { fn drop(&mut self) { + // TODO // // SAFETY: with safe usage of the ProcessAddressSpaceImpl, clearing and dropping // // is safe, no one refers to the memory // unsafe {