Rearrange `tp` register state in kernel privileged level
This commit is contained in:
parent
26e071a3cf
commit
c65af7471e
|
@ -1,5 +1,9 @@
|
|||
//! 和处理核相关的函数
|
||||
use core::ops::Add;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::memory::AddressSpaceId;
|
||||
|
||||
/// 写一个指针到上下文指针
|
||||
pub unsafe fn write_tp(value: usize) {
|
||||
|
@ -19,3 +23,54 @@ pub fn read_tp() -> usize {
|
|||
() => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
// 用户层将定义自己的tp寄存器意义
|
||||
// 在内核层中,tp指向一个结构体,说明当前的硬件线程编号,以及已经分配的地址空间
|
||||
pub struct KernelHartInfo {
|
||||
hart_id: usize,
|
||||
address_space_id: AddressSpaceId,
|
||||
}
|
||||
|
||||
impl KernelHartInfo {
|
||||
/// 准备一个新的核,以供调度器使用
|
||||
pub unsafe fn load_hart(hart_id: usize) {
|
||||
let hart_info = Box::new(KernelHartInfo {
|
||||
hart_id,
|
||||
address_space_id: AddressSpaceId::kernel(),
|
||||
});
|
||||
let tp = Box::into_raw(hart_info) as usize; // todo: 这里有内存泄漏,要在drop里处理
|
||||
write_tp(tp)
|
||||
}
|
||||
|
||||
/// 热加载/热卸载处理核,释放这个核占用的内存资源
|
||||
pub unsafe fn unload_hart() {
|
||||
let addr = read_tp();
|
||||
let bx: Box<KernelHartInfo> = Box::from_raw(addr as *mut _);
|
||||
drop(bx);
|
||||
}
|
||||
|
||||
/// 得到当前硬件线程的编号,必须在load_hart之后使用
|
||||
pub fn hart_id() -> usize {
|
||||
let addr = read_tp();
|
||||
let bx: Box<KernelHartInfo> = unsafe { Box::from_raw(addr as *mut _) };
|
||||
let ans = bx.hart_id;
|
||||
drop(Box::into_raw(bx));
|
||||
ans
|
||||
}
|
||||
|
||||
pub unsafe fn load_address_space_id(asid: AddressSpaceId) {
|
||||
let addr = read_tp();
|
||||
let mut bx: Box<KernelHartInfo> = Box::from_raw(addr as *mut _);
|
||||
bx.address_space_id = asid;
|
||||
drop(Box::into_raw(bx)); // 防止Box指向的内存被释放
|
||||
}
|
||||
|
||||
/// 得到当前的地址空间编号
|
||||
pub fn current_address_space_id() -> AddressSpaceId {
|
||||
let addr = read_tp();
|
||||
let bx: Box<KernelHartInfo> = unsafe { Box::from_raw(addr as *mut _) };
|
||||
let ans = bx.address_space_id;
|
||||
drop(Box::into_raw(bx));
|
||||
ans
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ mod hart;
|
|||
global_asm!(include_str!("entry.asm"));
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_main() -> ! {
|
||||
pub extern "C" fn rust_main(hart_id: usize) -> ! {
|
||||
println!("booted");
|
||||
|
||||
memory::init();
|
||||
|
@ -76,6 +76,10 @@ pub extern "C" fn rust_main() -> ! {
|
|||
|
||||
println!("Max asid = {:?}", memory::riscv_max_asid());
|
||||
|
||||
// 在启动程序之前,需要加载内核当前线程的信息到tp寄存器中
|
||||
unsafe { hart::KernelHartInfo::load_hart(hart_id) };
|
||||
println!("Current hart: {}", hart::KernelHartInfo::hart_id());
|
||||
|
||||
// todo: 这里要有个地方往tp里写东西,目前会出错
|
||||
let process = process::Process::new_kernel().expect("create process 1");
|
||||
// let stack_handle = process.alloc_stack().expect("alloc initial stack");
|
||||
|
@ -103,6 +107,10 @@ pub extern "C" fn rust_main() -> ! {
|
|||
process::shared_add_task(shared_scheduler, task_3.shared_task_handle());
|
||||
}
|
||||
process::Executor::block_on(|| unsafe { process::shared_pop_task(shared_scheduler)});
|
||||
|
||||
// 关机之前,卸载当前的核。虽然关机后内存已经清空,不是必要,预留未来热加载热卸载处理核的情况
|
||||
unsafe { hart::KernelHartInfo::unload_hart() };
|
||||
// 没有任务了,关机
|
||||
sbi::shutdown()
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use spin::Mutex;
|
|||
use core::ops::Range;
|
||||
use core::future::Future;
|
||||
use alloc::boxed::Box;
|
||||
use crate::{interrupt::TrapFrame, memory::VirtualAddress};
|
||||
use crate::{hart::KernelHartInfo, interrupt::TrapFrame, memory::VirtualAddress};
|
||||
use crate::process::{Process, SharedTaskHandle};
|
||||
use core::pin::Pin;
|
||||
use core::fmt;
|
||||
|
@ -60,12 +60,7 @@ impl KernelTask {
|
|||
future: impl Future<Output = ()> + 'static + Send + Sync,
|
||||
process: Arc<Process>,
|
||||
) -> Arc<KernelTask> {
|
||||
// 任务编号自增
|
||||
// let task_id = {
|
||||
// let counter = TASK_ID_COUNTER.lock();
|
||||
// let ans = counter.wrapping_add(1);
|
||||
// TaskId(ans)
|
||||
// };
|
||||
// 得到新的内核任务编号
|
||||
let task_id = TaskId::generate();
|
||||
// 打包为任务
|
||||
Arc::new(KernelTask {
|
||||
|
@ -86,6 +81,7 @@ impl KernelTask {
|
|||
/// note(unsafe): 创建了一个没有边界的生命周期
|
||||
pub unsafe fn shared_task_handle(self: Arc<Self>) -> SharedTaskHandle {
|
||||
SharedTaskHandle {
|
||||
hart_id: KernelHartInfo::hart_id(),
|
||||
address_space_id: self.process.address_space_id(),
|
||||
task_ptr: Arc::into_raw(self) as usize
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ pub use lock::Lock;
|
|||
pub use kernel_task::{KernelTask, TaskId};
|
||||
pub use process::{Process, ProcessId};
|
||||
pub use executor::Executor;
|
||||
pub use shared::{SharedTaskHandle, SharedAddressSpace, shared_scheduler, shared_add_task, shared_pop_task};
|
||||
pub use shared::{SharedTaskHandle, shared_scheduler, shared_add_task, shared_pop_task};
|
||||
|
||||
/// 共享调度器返回的结果
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use lazy_static::lazy_static;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use core::ops::Range;
|
||||
use spin::Mutex;
|
||||
use crate::process::SharedAddressSpace;
|
||||
use crate::memory::{AddressSpaceId, Flags, MemorySet, STACK_SIZE, VirtualAddress};
|
||||
|
||||
/// 进程的所有信息
|
||||
|
@ -31,18 +29,14 @@ impl Process {
|
|||
///
|
||||
/// 如果内存分配失败,返回None
|
||||
pub fn new_kernel() -> Option<Arc<Self>> {
|
||||
let shared_address_space = Box::new(SharedAddressSpace {
|
||||
address_space_id: AddressSpaceId::kernel()
|
||||
});
|
||||
let tp = Box::into_raw(shared_address_space) as usize; // todo: 这里有内存泄漏,要在drop里处理
|
||||
println!("Process::new_kernel, tp = {:x}", tp);
|
||||
unsafe { crate::hart::write_tp(tp) };
|
||||
let address_space_id = AddressSpaceId::kernel();
|
||||
unsafe { crate::hart::KernelHartInfo::load_address_space_id(address_space_id) };
|
||||
Some(Arc::new(Process {
|
||||
id: next_process_id(),
|
||||
is_user: false,
|
||||
inner: Mutex::new(ProcessInner {
|
||||
memory_set: MemorySet::new_kernel()?,
|
||||
address_space_id: AddressSpaceId::kernel(),
|
||||
address_space_id,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#[allow(unused_imports)]
|
||||
use crate::{algorithm::{Scheduler, ScheduledItem, RingFifoScheduler, SameAddrSpaceScheduler}, memory::AddressSpaceId};
|
||||
use crate::algorithm::{Scheduler, ScheduledItem, RingFifoScheduler, SameAddrSpaceScheduler};
|
||||
use crate::memory::AddressSpaceId;
|
||||
use crate::hart::KernelHartInfo;
|
||||
use core::ptr::NonNull;
|
||||
use super::TaskResult;
|
||||
|
||||
|
@ -19,7 +21,10 @@ pub fn shared_scheduler() -> NonNull<()> {
|
|||
|
||||
/// 共享的包含Future在用户空间的地址
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
pub struct SharedTaskHandle {
|
||||
/// 运行此任务的硬件线程编号
|
||||
pub(crate) hart_id: usize,
|
||||
/// 地址空间的编号
|
||||
pub(crate) address_space_id: AddressSpaceId,
|
||||
/// 对每个虚拟空间来说,task_ptr是Arc<Task>相应的虚拟地址
|
||||
|
@ -30,7 +35,7 @@ pub struct SharedTaskHandle {
|
|||
impl SharedTaskHandle {
|
||||
fn should_switch(&self) -> bool {
|
||||
// 如果当前和下一个任务间地址空间变化了,就说明应当切换上下文
|
||||
SharedAddressSpace::current_address_space_id() != self.address_space_id
|
||||
KernelHartInfo::current_address_space_id() != self.address_space_id
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,24 +73,3 @@ pub unsafe fn shared_pop_task(shared_scheduler: NonNull<()>) -> TaskResult {
|
|||
TaskResult::Finished
|
||||
}
|
||||
}
|
||||
|
||||
/// 共享的地址空间
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct SharedAddressSpace {
|
||||
/// 当前的地址空间编号;可能多个进程共享一个地址空间
|
||||
pub address_space_id: AddressSpaceId,
|
||||
}
|
||||
|
||||
impl SharedAddressSpace {
|
||||
fn current_address_space_id() -> AddressSpaceId {
|
||||
use alloc::boxed::Box;
|
||||
let addr = crate::hart::read_tp();
|
||||
let bx: Box<SharedAddressSpace> = unsafe { Box::from_raw(addr as *mut _) };
|
||||
let ans = bx.address_space_id;
|
||||
drop(Box::into_raw(bx));
|
||||
ans
|
||||
}
|
||||
// fn current_process() -> Process {
|
||||
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue