mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
riscv64: 添加flush tlb的ipi (#636)
* riscv64: 添加flush tlb的ipi * update triagebot
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use alloc::vec::Vec;
|
||||
use sbi_rt::HartMask;
|
||||
|
||||
use crate::{
|
||||
init::boot_params,
|
||||
@ -10,6 +11,9 @@ use crate::{
|
||||
/// 栈对齐
|
||||
pub(super) const STACK_ALIGN: usize = 16;
|
||||
|
||||
/// RISC-V的XLEN,也就是寄存器的位宽
|
||||
pub const RISCV_XLEN: usize = core::mem::size_of::<usize>() * 8;
|
||||
|
||||
/// 获取当前cpu的id
|
||||
#[inline]
|
||||
pub fn current_cpu_id() -> ProcessorId {
|
||||
@ -21,7 +25,13 @@ pub fn current_cpu_id() -> ProcessorId {
|
||||
|
||||
unsafe { (*ptr).current_cpu() }
|
||||
}
|
||||
|
||||
impl Into<HartMask> for ProcessorId {
|
||||
fn into(self) -> HartMask {
|
||||
let base = self.data() as usize / RISCV_XLEN;
|
||||
let offset = self.data() as usize & (RISCV_XLEN - 1);
|
||||
HartMask::from_mask_base(offset, base)
|
||||
}
|
||||
}
|
||||
/// 重置cpu
|
||||
pub unsafe fn cpu_reset() -> ! {
|
||||
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
|
||||
|
@ -1,6 +1,38 @@
|
||||
use crate::exception::ipi::{IpiKind, IpiTarget};
|
||||
use sbi_rt::HartMask;
|
||||
|
||||
use crate::{
|
||||
arch::mm::RiscV64MMArch,
|
||||
exception::ipi::{IpiKind, IpiTarget},
|
||||
smp::core::smp_get_processor_id,
|
||||
};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
|
||||
unimplemented!("RiscV64 send_ipi")
|
||||
let mask = Into::into(target);
|
||||
match kind {
|
||||
IpiKind::KickCpu => todo!(),
|
||||
IpiKind::FlushTLB => RiscV64MMArch::remote_invalidate_all_with_mask(mask).ok(),
|
||||
IpiKind::SpecVector(_) => todo!(),
|
||||
};
|
||||
}
|
||||
|
||||
impl Into<HartMask> for IpiTarget {
|
||||
fn into(self) -> HartMask {
|
||||
match self {
|
||||
IpiTarget::All => HartMask::from_mask_base(usize::MAX, 0),
|
||||
IpiTarget::Other => {
|
||||
let data = usize::MAX & (!(1 << smp_get_processor_id().data()));
|
||||
let mask = HartMask::from_mask_base(data, 0);
|
||||
mask
|
||||
}
|
||||
IpiTarget::Specified(cpu_id) => {
|
||||
let mask = Into::into(cpu_id);
|
||||
mask
|
||||
}
|
||||
IpiTarget::Current => {
|
||||
let mask = Into::into(smp_get_processor_id());
|
||||
mask
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,23 @@
|
||||
use acpi::address;
|
||||
use riscv::register::satp;
|
||||
use sbi_rt::{HartMask, SbiRet};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
kdebug,
|
||||
libs::spinlock::SpinLock,
|
||||
mm::{
|
||||
allocator::{
|
||||
buddy::BuddyAllocator,
|
||||
page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
|
||||
},
|
||||
page::PageFlags,
|
||||
kernel_mapper::KernelMapper,
|
||||
page::{PageEntry, PageFlags},
|
||||
ucontext::UserMapper,
|
||||
MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
|
||||
},
|
||||
smp::cpu::ProcessorId,
|
||||
};
|
||||
|
||||
use self::init::riscv_mm_init;
|
||||
@ -38,7 +44,47 @@ pub struct RiscV64MMArch;
|
||||
|
||||
impl RiscV64MMArch {
|
||||
pub const ENTRY_FLAG_GLOBAL: usize = 1 << 5;
|
||||
|
||||
/// 使远程cpu的TLB中,指定地址范围的页失效
|
||||
pub fn remote_invalidate_page(
|
||||
cpu: ProcessorId,
|
||||
address: VirtAddr,
|
||||
size: usize,
|
||||
) -> Result<(), SbiRet> {
|
||||
let r = sbi_rt::remote_sfence_vma(Into::into(cpu), address.data(), size);
|
||||
if r.is_ok() {
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err(r);
|
||||
}
|
||||
}
|
||||
|
||||
/// 使指定远程cpu的TLB中,所有范围的页失效
|
||||
pub fn remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet> {
|
||||
let r = Self::remote_invalidate_page(
|
||||
cpu,
|
||||
VirtAddr::new(0),
|
||||
1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT,
|
||||
);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
pub fn remote_invalidate_all_with_mask(mask: HartMask) -> Result<(), SbiRet> {
|
||||
let r = sbi_rt::remote_sfence_vma(mask, 0, 1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT);
|
||||
if r.is_ok() {
|
||||
return Ok(());
|
||||
} else {
|
||||
return Err(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 内核空间起始地址在顶层页表中的索引
|
||||
const KERNEL_TOP_PAGE_ENTRY_NO: usize = (RiscV64MMArch::PHYS_OFFSET
|
||||
& ((1 << RiscV64MMArch::ENTRY_ADDRESS_SHIFT) - 1))
|
||||
>> (RiscV64MMArch::ENTRY_ADDRESS_SHIFT - RiscV64MMArch::PAGE_ENTRY_SHIFT);
|
||||
|
||||
impl MemoryManagementArch for RiscV64MMArch {
|
||||
const PAGE_SHIFT: usize = 12;
|
||||
|
||||
@ -117,16 +163,35 @@ impl MemoryManagementArch for RiscV64MMArch {
|
||||
satp::set(satp::Mode::Sv39, 0, ppn);
|
||||
}
|
||||
|
||||
fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool {
|
||||
fn virt_is_valid(virt: VirtAddr) -> bool {
|
||||
virt.is_canonical()
|
||||
}
|
||||
|
||||
fn initial_page_table() -> crate::mm::PhysAddr {
|
||||
fn initial_page_table() -> PhysAddr {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn setup_new_usermapper() -> Result<crate::mm::ucontext::UserMapper, SystemError> {
|
||||
todo!()
|
||||
fn setup_new_usermapper() -> Result<UserMapper, SystemError> {
|
||||
let new_umapper: crate::mm::page::PageMapper<MMArch, LockedFrameAllocator> = unsafe {
|
||||
PageMapper::create(PageTableKind::User, LockedFrameAllocator)
|
||||
.ok_or(SystemError::ENOMEM)?
|
||||
};
|
||||
|
||||
let current_ktable: KernelMapper = KernelMapper::lock();
|
||||
let copy_mapping = |pml4_entry_no| unsafe {
|
||||
let entry: PageEntry<RiscV64MMArch> = current_ktable
|
||||
.table()
|
||||
.entry(pml4_entry_no)
|
||||
.unwrap_or_else(|| panic!("entry {} not found", pml4_entry_no));
|
||||
new_umapper.table().set_entry(pml4_entry_no, entry)
|
||||
};
|
||||
|
||||
// 复制内核的映射
|
||||
for pml4_entry_no in KERNEL_TOP_PAGE_ENTRY_NO..512 {
|
||||
copy_mapping(pml4_entry_no);
|
||||
}
|
||||
|
||||
return Ok(crate::mm::ucontext::UserMapper::new(new_umapper));
|
||||
}
|
||||
|
||||
unsafe fn phys_2_virt(phys: PhysAddr) -> Option<VirtAddr> {
|
||||
|
@ -20,7 +20,11 @@ const CPU_NUM: AtomicU32 = AtomicU32::new(PerCpu::MAX_CPU_NUM);
|
||||
pub struct PerCpu;
|
||||
|
||||
impl PerCpu {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub const MAX_CPU_NUM: u32 = 128;
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
pub const MAX_CPU_NUM: u32 = 64;
|
||||
|
||||
/// # 初始化PerCpu
|
||||
///
|
||||
/// 该函数应该在内核初始化时调用一次。
|
||||
|
@ -6,7 +6,6 @@ use core::{
|
||||
|
||||
use crate::{
|
||||
arch::{ipc::signal::SigSet, syscall::nr::*},
|
||||
driver::base::device::device_number::DeviceNumber,
|
||||
filesystem::vfs::syscall::PosixStatx,
|
||||
libs::{futex::constant::FutexFlag, rand::GRandFlags},
|
||||
mm::syscall::MremapFlags,
|
||||
@ -21,7 +20,6 @@ use crate::{
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
use system_error::SystemError;
|
||||
use uefi::proto::debug;
|
||||
|
||||
use crate::{
|
||||
arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch},
|
||||
@ -99,6 +97,7 @@ impl Syscall {
|
||||
Self::open(path, flags, mode, true)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_RENAME => {
|
||||
let oldname: *const u8 = args[0] as *const u8;
|
||||
let newname: *const u8 = args[1] as *const u8;
|
||||
@ -111,6 +110,7 @@ impl Syscall {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_RENAMEAT => {
|
||||
let oldfd = args[0] as i32;
|
||||
let oldname: *const u8 = args[1] as *const u8;
|
||||
@ -637,6 +637,8 @@ impl Syscall {
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_MKNOD => {
|
||||
use crate::driver::base::device::device_number::DeviceNumber;
|
||||
|
||||
let path = args[0];
|
||||
let flags = args[1];
|
||||
let dev_t = args[2];
|
||||
@ -715,6 +717,7 @@ impl Syscall {
|
||||
Self::do_statx(fd, path, flags, mask, kstat)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_EPOLL_CREATE => Self::epoll_create(args[0] as i32),
|
||||
SYS_EPOLL_CREATE1 => Self::epoll_create1(args[0]),
|
||||
|
||||
@ -725,6 +728,7 @@ impl Syscall {
|
||||
VirtAddr::new(args[3]),
|
||||
),
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
SYS_EPOLL_WAIT => Self::epoll_wait(
|
||||
args[0] as i32,
|
||||
VirtAddr::new(args[1]),
|
||||
|
Reference in New Issue
Block a user