Rearrange `tp` register state in kernel privileged level

This commit is contained in:
luojia65 2021-03-07 15:38:07 +08:00
parent 26e071a3cf
commit c65af7471e
6 changed files with 78 additions and 41 deletions

View File

@ -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
}
}

View File

@ -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()
}

View File

@ -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
}

View File

@ -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)]

View File

@ -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,
})
}))
}

View File

@ -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 {
// }
}