mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-22 19:33:26 +00:00
riscv
: 初始化irq (#560)
完成riscv的irqchip初始化的代码。 这是该功能的第一个PR。由于还需要实现timer驱动才能测试,因此该功能将会通过2~3个PR来完成。
This commit is contained in:
@ -1,9 +1,22 @@
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::{
|
||||
init::boot_params,
|
||||
kdebug,
|
||||
mm::percpu::{PerCpu, PerCpuVar},
|
||||
smp::cpu::{ProcessorId, SmpCpuManager},
|
||||
};
|
||||
|
||||
/// 获取当前cpu的id
|
||||
#[inline]
|
||||
pub fn current_cpu_id() -> ProcessorId {
|
||||
unimplemented!("RiscV64 current_cpu_id")
|
||||
let ptr: *const LocalContext = riscv::register::sscratch::read() as *const LocalContext;
|
||||
|
||||
if core::intrinsics::unlikely(ptr.is_null()) {
|
||||
return boot_params().read_irqsave().arch.boot_hartid;
|
||||
}
|
||||
|
||||
unsafe { (*ptr).current_cpu() }
|
||||
}
|
||||
|
||||
/// 重置cpu
|
||||
@ -11,3 +24,64 @@ pub unsafe fn cpu_reset() -> ! {
|
||||
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
|
||||
unimplemented!("RiscV64 reset failed, manual override expected ...")
|
||||
}
|
||||
|
||||
static mut LOCAL_CONTEXT: Option<PerCpuVar<LocalContext>> = None;
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn local_context() -> &'static PerCpuVar<LocalContext> {
|
||||
unsafe { LOCAL_CONTEXT.as_ref().unwrap() }
|
||||
}
|
||||
|
||||
/// Per cpu的上下文数据
|
||||
///
|
||||
/// 每个CPU的sscratch寄存器指向这个结构体
|
||||
#[derive(Debug)]
|
||||
pub(super) struct LocalContext {
|
||||
/// 当前cpu的id
|
||||
current_cpu: ProcessorId,
|
||||
}
|
||||
|
||||
impl LocalContext {
|
||||
fn new(cpu: ProcessorId) -> Self {
|
||||
Self { current_cpu: cpu }
|
||||
}
|
||||
pub fn current_cpu(&self) -> ProcessorId {
|
||||
self.current_cpu
|
||||
}
|
||||
|
||||
pub fn set_current_cpu(&mut self, cpu: ProcessorId) {
|
||||
self.current_cpu = cpu;
|
||||
}
|
||||
|
||||
fn sync_to_cpu(&self) {
|
||||
let ptr = self as *const Self as usize;
|
||||
riscv::register::sscratch::write(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/// 初始化本地上下文
|
||||
#[inline(never)]
|
||||
pub(super) fn init_local_context() {
|
||||
kdebug!("init_local_context");
|
||||
let mut data = Vec::new();
|
||||
|
||||
for i in 0..PerCpu::MAX_CPU_NUM {
|
||||
data.push(LocalContext::new(ProcessorId::new(i)));
|
||||
}
|
||||
let ctx = PerCpuVar::new(data).unwrap();
|
||||
|
||||
unsafe {
|
||||
LOCAL_CONTEXT = Some(ctx);
|
||||
}
|
||||
|
||||
let hartid = boot_params().read().arch.boot_hartid;
|
||||
|
||||
let ctx = unsafe { local_context().force_get(hartid) };
|
||||
ctx.sync_to_cpu();
|
||||
}
|
||||
|
||||
impl SmpCpuManager {
|
||||
pub fn arch_init(boot_cpu: ProcessorId) {
|
||||
// todo: 读取所有可用的CPU
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user