rv64: add jh7110/starfive visionfive2 support
This commit is contained in:
@@ -14,6 +14,13 @@ tock-registers.workspace = true
|
||||
bitflags.workspace = true
|
||||
static_assertions.workspace = true
|
||||
log.workspace = true
|
||||
cfg-if.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
riscv64_board_virt = []
|
||||
riscv64_board_jh7110 = []
|
||||
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
@@ -150,6 +150,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
unsafe fn enter(&self) -> ! {
|
||||
unsafe {
|
||||
self.load_state();
|
||||
mem::tlb_flush_full();
|
||||
__rv64_enter_task(self.inner.get())
|
||||
}
|
||||
}
|
||||
@@ -162,6 +163,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
unsafe {
|
||||
from.store_state();
|
||||
self.load_state();
|
||||
mem::tlb_flush_full();
|
||||
__rv64_switch_task(self.inner.get(), from.inner.get())
|
||||
}
|
||||
}
|
||||
@@ -169,6 +171,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
unsafe fn switch_and_drop(&self, thread: *const ()) {
|
||||
unsafe {
|
||||
self.load_state();
|
||||
mem::tlb_flush_full();
|
||||
__rv64_switch_task_and_drop(self.inner.get(), thread)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use cfg_if::cfg_if;
|
||||
use kernel_arch_interface::{
|
||||
mem::{DeviceMemoryAttributes, KernelTableManager, RawDeviceMemoryMapping},
|
||||
split_spinlock,
|
||||
};
|
||||
use libk_mm_interface::{
|
||||
address::PhysicalAddress,
|
||||
table::{page_align_down, page_index, EntryLevel, EntryLevelExt},
|
||||
table::{page_index, EntryLevel, EntryLevelExt},
|
||||
};
|
||||
use memtables::riscv64::PageAttributes;
|
||||
use static_assertions::{const_assert, const_assert_eq};
|
||||
@@ -30,14 +31,22 @@ split_spinlock! {
|
||||
unsafe { KernelImageObject::new(FixedTables::zeroed()) };
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "riscv64_board_virt")] {
|
||||
pub const KERNEL_PHYS_BASE: usize = 0x80200000;
|
||||
} else if #[cfg(feature = "riscv64_board_jh7110")] {
|
||||
pub const KERNEL_PHYS_BASE: usize = 0x40200000;
|
||||
} else if #[cfg(rust_analyzer)] {
|
||||
pub const KERNEL_PHYS_BASE: usize = 0x80200000;
|
||||
}
|
||||
}
|
||||
|
||||
pub const KERNEL_VIRT_OFFSET: usize = kernel_arch_interface::KERNEL_VIRT_OFFSET;
|
||||
pub const KERNEL_PHYS_BASE: usize = 0x80000000;
|
||||
pub const SIGN_EXTEND_MASK: usize = 0xFFFFFF80_00000000;
|
||||
|
||||
pub const KERNEL_START_L1I: usize = page_index::<L1>(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE);
|
||||
pub const KERNEL_L2I: usize = page_index::<L2>(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE);
|
||||
const_assert_eq!(KERNEL_START_L1I, 450);
|
||||
const_assert_eq!(KERNEL_L2I, 0);
|
||||
const_assert_eq!(KERNEL_L2I, 1);
|
||||
|
||||
// Runtime mappings
|
||||
// 1GiB of device memory space
|
||||
@@ -120,8 +129,8 @@ unsafe fn map_device_memory_l3(
|
||||
DEVICE_MAPPING_L3S[l2i][l3i] =
|
||||
PageEntry::page(base.add(j * L3::SIZE), PageAttributes::W);
|
||||
}
|
||||
tlb_flush_va(DEVICE_MAPPING_OFFSET + l2i * L2::SIZE + l3i * L3::SIZE);
|
||||
}
|
||||
tlb_flush_full();
|
||||
|
||||
return Ok(DEVICE_MAPPING_OFFSET + i * L3::SIZE);
|
||||
}
|
||||
@@ -148,9 +157,10 @@ unsafe fn map_device_memory_l2(
|
||||
for j in 0..count {
|
||||
DEVICE_MAPPING_L2[i + j] =
|
||||
PageEntry::<L2>::block(base.add(j * L2::SIZE), PageAttributes::W);
|
||||
// tlb_flush_vaae1(DEVICE_MAPPING_OFFSET + (i + j) * L2::SIZE);
|
||||
// tlb_flush_va(DEVICE_MAPPING_OFFSET + (i + j) * L2::SIZE);
|
||||
}
|
||||
}
|
||||
tlb_flush_full();
|
||||
|
||||
return Ok(DEVICE_MAPPING_OFFSET + i * L2::SIZE);
|
||||
}
|
||||
@@ -212,7 +222,7 @@ pub(crate) unsafe fn unmap_device_memory(map: &RawDeviceMemoryMapping<KernelTabl
|
||||
DEVICE_MAPPING_L3S[l2i][l3i] = PageEntry::INVALID;
|
||||
}
|
||||
|
||||
// tlb_flush_vaae1(page);
|
||||
tlb_flush_va(page);
|
||||
}
|
||||
}
|
||||
L2::SIZE => todo!(),
|
||||
@@ -236,7 +246,7 @@ pub fn auto_address<T>(x: *const T) -> usize {
|
||||
/// Only meant to be called once per each HART during their early init.
|
||||
pub unsafe fn enable_mmu() {
|
||||
let l1_phys = auto_address(&raw const KERNEL_TABLES) as u64;
|
||||
|
||||
tlb_flush_full();
|
||||
SATP.write(SATP::PPN.val(l1_phys >> 12) + SATP::MODE::Sv39);
|
||||
}
|
||||
|
||||
@@ -249,7 +259,7 @@ pub unsafe fn unmap_lower_half() {
|
||||
let mut tables = KERNEL_TABLES.lock();
|
||||
let kernel_l1i_lower = page_index::<L1>(KERNEL_PHYS_BASE);
|
||||
tables.l1.data[kernel_l1i_lower] = 0;
|
||||
tlb_flush_va(page_align_down::<L1>(KERNEL_PHYS_BASE));
|
||||
tlb_flush_full();
|
||||
}
|
||||
|
||||
/// Sets up run-time kernel translation tables.
|
||||
@@ -276,15 +286,25 @@ pub unsafe fn setup_fixed_tables() {
|
||||
assert_eq!(tables.l1.data[DEVICE_MAPPING_L1I], 0);
|
||||
tables.l1.data[DEVICE_MAPPING_L1I] =
|
||||
((device_mapping_l2_phys as u64) >> 2) | PageAttributes::V.bits();
|
||||
// tlb_flush_vaae1(DEVICE_MAPPING_OFFSET);
|
||||
|
||||
for l1i in 0..RAM_MAPPING_L1_COUNT {
|
||||
let physical = (l1i as u64) << L1::SHIFT;
|
||||
tables.l1.data[l1i + RAM_MAPPING_START_L1I] =
|
||||
(physical >> 2) | (PageAttributes::R | PageAttributes::W | PageAttributes::V).bits();
|
||||
tables.l1.data[l1i + RAM_MAPPING_START_L1I] = (physical >> 2)
|
||||
| (PageAttributes::R
|
||||
| PageAttributes::W
|
||||
| PageAttributes::A
|
||||
| PageAttributes::D
|
||||
| PageAttributes::V)
|
||||
.bits();
|
||||
}
|
||||
|
||||
// tlb_flush_all()
|
||||
tlb_flush_full();
|
||||
}
|
||||
|
||||
pub fn tlb_flush_full() {
|
||||
unsafe {
|
||||
core::arch::asm!("sfence.vma");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tlb_flush_va(va: usize) {
|
||||
|
||||
@@ -130,7 +130,13 @@ impl<L: NonTerminalEntryLevel> PageEntry<L> {
|
||||
pub fn block(address: PhysicalAddress, attrs: PageAttributes) -> Self {
|
||||
// TODO validate address alignment
|
||||
Self(
|
||||
(address.into_u64() >> 2) | (PageAttributes::R | PageAttributes::V | attrs).bits(),
|
||||
(address.into_u64() >> 2)
|
||||
| (PageAttributes::R
|
||||
| PageAttributes::A
|
||||
| PageAttributes::D
|
||||
| PageAttributes::V
|
||||
| attrs)
|
||||
.bits(),
|
||||
PhantomData,
|
||||
)
|
||||
}
|
||||
@@ -156,7 +162,13 @@ impl<L: NonTerminalEntryLevel> PageEntry<L> {
|
||||
impl PageEntry<L3> {
|
||||
pub fn page(address: PhysicalAddress, attrs: PageAttributes) -> Self {
|
||||
Self(
|
||||
(address.into_u64() >> 2) | (PageAttributes::R | PageAttributes::V | attrs).bits(),
|
||||
(address.into_u64() >> 2)
|
||||
| (PageAttributes::R
|
||||
| PageAttributes::A
|
||||
| PageAttributes::D
|
||||
| PageAttributes::V
|
||||
| attrs)
|
||||
.bits(),
|
||||
PhantomData,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user