mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 05:56:32 +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
|
||||
}
|
||||
}
|
||||
|
@ -3,26 +3,33 @@ use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
|
||||
driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
|
||||
driver::{
|
||||
firmware::efi::init::efi_init, irqchip::riscv_intc::riscv_intc_init,
|
||||
open_firmware::fdt::open_firmware_fdt_driver,
|
||||
},
|
||||
init::{boot_params, init::start_kernel},
|
||||
kdebug, kinfo,
|
||||
mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
|
||||
print, println,
|
||||
smp::cpu::ProcessorId,
|
||||
};
|
||||
|
||||
use super::driver::sbi::console_putstr;
|
||||
use super::{cpu::init_local_context, driver::sbi::console_putstr};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ArchBootParams {
|
||||
/// 启动时的fdt物理地址
|
||||
pub fdt_paddr: PhysAddr,
|
||||
pub fdt_vaddr: Option<VirtAddr>,
|
||||
|
||||
pub boot_hartid: ProcessorId,
|
||||
}
|
||||
|
||||
impl ArchBootParams {
|
||||
pub const DEFAULT: Self = ArchBootParams {
|
||||
fdt_paddr: PhysAddr::new(0),
|
||||
fdt_vaddr: None,
|
||||
boot_hartid: ProcessorId::new(0),
|
||||
};
|
||||
|
||||
pub fn arch_fdt(&self) -> VirtAddr {
|
||||
@ -34,7 +41,7 @@ impl ArchBootParams {
|
||||
}
|
||||
}
|
||||
|
||||
static mut BOOT_HARTID: usize = 0;
|
||||
static mut BOOT_HARTID: u32 = 0;
|
||||
static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
|
||||
|
||||
#[no_mangle]
|
||||
@ -42,7 +49,7 @@ unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
|
||||
let fdt_paddr = PhysAddr::new(fdt_paddr);
|
||||
|
||||
unsafe {
|
||||
BOOT_HARTID = hartid;
|
||||
BOOT_HARTID = hartid as u32;
|
||||
BOOT_FDT_PADDR = fdt_paddr;
|
||||
}
|
||||
|
||||
@ -79,9 +86,14 @@ unsafe fn parse_dtb() {
|
||||
#[inline(never)]
|
||||
pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
SbiDriver::early_init();
|
||||
let hartid: usize = unsafe { BOOT_HARTID };
|
||||
let hartid = unsafe { BOOT_HARTID };
|
||||
let fdt_paddr = unsafe { BOOT_FDT_PADDR };
|
||||
boot_params().write().arch.fdt_paddr = fdt_paddr;
|
||||
|
||||
let mut arch_boot_params_guard = boot_params().write();
|
||||
arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
|
||||
arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
|
||||
|
||||
drop(arch_boot_params_guard);
|
||||
|
||||
kinfo!(
|
||||
"DragonOS kernel is running on hart {}, fdt address:{:?}",
|
||||
@ -109,7 +121,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
|
||||
#[inline(never)]
|
||||
pub fn setup_arch() -> Result<(), SystemError> {
|
||||
// todo
|
||||
init_local_context();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber};
|
||||
use crate::{
|
||||
driver::irqchip::riscv_intc::riscv_intc_init,
|
||||
exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
|
||||
};
|
||||
|
||||
pub mod ipi;
|
||||
|
||||
@ -8,7 +11,9 @@ pub struct RiscV64InterruptArch;
|
||||
|
||||
impl InterruptArch for RiscV64InterruptArch {
|
||||
unsafe fn arch_irq_init() -> Result<(), SystemError> {
|
||||
todo!("RiscV64InterruptArch::arch_irq_init")
|
||||
riscv_intc_init()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
unsafe fn interrupt_enable() {
|
||||
riscv::interrupt::enable();
|
||||
|
@ -1,6 +1,6 @@
|
||||
use x86::cpuid::{cpuid, CpuIdResult};
|
||||
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
use crate::smp::cpu::{ProcessorId, SmpCpuManager};
|
||||
|
||||
/// 获取当前cpu的apic id
|
||||
#[inline]
|
||||
@ -16,3 +16,7 @@ pub unsafe fn cpu_reset() -> ! {
|
||||
unsafe { x86::io::outb(0x64, 0xfe) };
|
||||
loop {}
|
||||
}
|
||||
|
||||
impl SmpCpuManager {
|
||||
pub fn arch_init(_boot_cpu: ProcessorId) {}
|
||||
}
|
||||
|
Reference in New Issue
Block a user