rv64: add jh7110/starfive visionfive2 support

This commit is contained in:
2025-01-21 16:34:03 +02:00
parent 16f580e7af
commit 909980f4eb
24 changed files with 532 additions and 65 deletions
+7
View File
@@ -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
+3
View File
@@ -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)
}
}
+33 -13
View File
@@ -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) {
+14 -2
View File
@@ -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,
)
}