Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num
smoltcp = { version = "=0.11.0", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
system_error = { path = "crates/system_error" }
unified-init = { path = "crates/unified-init" }
virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers", rev = "448a781" }
fdt = "=0.1.5"
virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers", rev = "f91c807965" }
fdt = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/fdt", rev = "9862813020" }
uefi = { version = "=0.26.0", features = ["alloc"] }
uefi-raw = "=0.5.0"
paste = "=1.0.14"
Expand Down
18 changes: 16 additions & 2 deletions kernel/crates/bitmap/src/alloc_bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ impl AllocBitmap {
core: BitMapCore::new(),
}
}

pub fn bitand_assign(&mut self, rhs: &Self) {
for i in 0..rhs.data.len() {
self.data[i] &= rhs.data[i];
}
}
}

impl BitMapOps<usize> for AllocBitmap {
Expand Down Expand Up @@ -111,8 +117,8 @@ impl BitMapOps<usize> for AllocBitmap {
}
}

impl BitAnd for AllocBitmap {
type Output = Self;
impl BitAnd for &AllocBitmap {
type Output = AllocBitmap;

fn bitand(self, rhs: Self) -> Self::Output {
let mut result = AllocBitmap::new(self.elements);
Expand All @@ -122,3 +128,11 @@ impl BitAnd for AllocBitmap {
result
}
}

impl BitAnd for AllocBitmap {
type Output = AllocBitmap;

fn bitand(self, rhs: Self) -> Self::Output {
&self & &rhs
}
}
20 changes: 20 additions & 0 deletions kernel/crates/bitmap/tests/alloc-bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,23 @@ fn test_alloc_bitmap_bitand_128() {
assert_eq!(bitmap3.first_false_index(), Some(2));
assert_eq!(bitmap3.last_index(), Some(67));
}

#[test]
fn test_alloc_bitmap_bitand_assign_128() {
let mut bitmap = AllocBitmap::new(128);
bitmap.set_all(true);

let mut bitmap2 = AllocBitmap::new(128);

bitmap2.set(0, true);
bitmap2.set(1, true);
bitmap2.set(67, true);

bitmap.bitand_assign(&bitmap2);

assert_eq!(bitmap.len(), 128);
assert_eq!(bitmap.size(), 16);
assert_eq!(bitmap.first_index(), Some(0));
assert_eq!(bitmap.first_false_index(), Some(2));
assert_eq!(bitmap.last_index(), Some(67));
}
1 change: 1 addition & 0 deletions kernel/src/arch/riscv64/asm/bitops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/// @param x 目标u64
/// @return i32 bit-number(0..63) of the first (least significant) zero bit.
#[inline]
#[allow(dead_code)]
pub fn ffz(x: u64) -> i32 {
(!x).trailing_zeros() as i32
}
1 change: 0 additions & 1 deletion kernel/src/arch/riscv64/driver/of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use system_error::SystemError;
use crate::{
driver::open_firmware::fdt::OpenFirmwareFdtDriver,
init::boot_params,
kdebug,
libs::align::page_align_up,
mm::{mmio_buddy::mmio_pool, MemoryManagementArch, PhysAddr},
};
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/arch/riscv64/interrupt/entry.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::arch::{
asm::csr::{
CSR_SCAUSE, CSR_SEPC, CSR_SSCRATCH, CSR_SSTATUS, CSR_STVAL, SR_FS_VS, SR_SPP, SR_SUM,
},
asm::csr::{CSR_SCAUSE, CSR_SEPC, CSR_SSCRATCH, CSR_SSTATUS, CSR_STVAL, SR_SPP},
cpu::LocalContext,
interrupt::TrapFrame,
};
Expand Down
4 changes: 1 addition & 3 deletions kernel/src/arch/riscv64/interrupt/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use core::hint::spin_loop;

use system_error::SystemError;

use crate::{
arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq, kdebug, kerror,
};
use crate::{arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq, kerror};

use super::TrapFrame;

Expand Down
5 changes: 4 additions & 1 deletion kernel/src/arch/riscv64/interrupt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use riscv::register::{scause::Scause, sstatus::Sstatus};
use system_error::SystemError;

use crate::{
driver::irqchip::riscv_intc::riscv_intc_init,
driver::irqchip::{riscv_intc::riscv_intc_init, riscv_sifive_plic::riscv_sifive_plic_init},
exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
libs::align::align_up,
};
Expand All @@ -17,6 +17,9 @@ pub struct RiscV64InterruptArch;

impl InterruptArch for RiscV64InterruptArch {
unsafe fn arch_irq_init() -> Result<(), SystemError> {
Self::interrupt_disable();
riscv_sifive_plic_init()?;
// 注意,intc的初始化必须在plic之后,不然会导致plic无法关联上中断
riscv_intc_init()?;

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/arch/riscv64/mm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct RiscV64MMArch;

impl RiscV64MMArch {
/// 使远程cpu的TLB中,指定地址范围的页失效
#[allow(dead_code)]
pub fn remote_invalidate_page(
cpu: ProcessorId,
address: VirtAddr,
Expand All @@ -57,6 +58,7 @@ impl RiscV64MMArch {
}

/// 使指定远程cpu的TLB中,所有范围的页失效
#[allow(dead_code)]
pub fn remote_invalidate_all(cpu: ProcessorId) -> Result<(), SbiRet> {
let r = Self::remote_invalidate_page(
cpu,
Expand Down
9 changes: 8 additions & 1 deletion kernel/src/arch/x86_64/driver/apic/lapic_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,16 +227,23 @@ pub fn x86_vector_domain() -> &'static Arc<IrqDomain> {

#[inline(never)]
pub fn arch_early_irq_init() -> Result<(), SystemError> {
const IRQ_SIZE: u32 = 223;
let vec_domain = irq_domain_manager()
.create_and_add(
"VECTOR".to_string(),
&X86VectorDomainOps,
IrqNumber::new(32),
HardwareIrqNumber::new(32),
223,
IRQ_SIZE,
)
.ok_or(SystemError::ENOMEM)?;
irq_domain_manager().set_default_domain(vec_domain.clone());
irq_domain_manager().domain_associate_many(
&vec_domain,
IrqNumber::new(0),
HardwareIrqNumber::new(0),
IRQ_SIZE,
);
unsafe { X86_VECTOR_DOMAIN = Some(vec_domain) };

let apic_chip = Arc::new(LocalApicChip::new());
Expand Down
18 changes: 13 additions & 5 deletions kernel/src/driver/block/virtio_blk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use crate::{
VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
},
},
exception::{irqdesc::IrqReturn, IrqNumber},
filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable},
init::initcall::INITCALL_POSTCORE,
libs::{
Expand Down Expand Up @@ -85,15 +86,15 @@ unsafe impl Sync for VirtIOBlkDevice {}

impl VirtIOBlkDevice {
pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
let irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
if let Err(e) = device_inner {
kerror!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e);
return None;
}
// !!!! 在这里临时测试virtio-blk的读写功能,后续需要删除 !!!!
// 目前read会报错 `NotReady`
let device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = device_inner.unwrap();

let mut device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = device_inner.unwrap();
device_inner.enable_interrupts();
let dev = Arc::new_cyclic(|self_ref| Self {
self_ref: self_ref.clone(),
dev_id,
Expand All @@ -104,6 +105,7 @@ impl VirtIOBlkDevice {
virtio_index: None,
device_common: DeviceCommonData::default(),
kobject_common: KObjectCommonData::default(),
irq,
}),
});

Expand Down Expand Up @@ -190,6 +192,7 @@ struct InnerVirtIOBlkDevice {
virtio_index: Option<VirtIODeviceIndex>,
device_common: DeviceCommonData,
kobject_common: KObjectCommonData,
irq: Option<IrqNumber>,
}

impl Debug for InnerVirtIOBlkDevice {
Expand All @@ -199,11 +202,16 @@ impl Debug for InnerVirtIOBlkDevice {
}

impl VirtIODevice for VirtIOBlkDevice {
fn irq(&self) -> Option<IrqNumber> {
self.inner().irq
}

fn handle_irq(
&self,
_irq: crate::exception::IrqNumber,
) -> Result<crate::exception::irqdesc::IrqReturn, system_error::SystemError> {
todo!("VirtIOBlkDevice::handle_irq")
) -> Result<IrqReturn, system_error::SystemError> {
// todo: handle virtio blk irq
Ok(crate::exception::irqdesc::IrqReturn::Handled)
}

fn dev_id(&self) -> &Arc<DeviceId> {
Expand Down
14 changes: 9 additions & 5 deletions kernel/src/driver/clocksource/timer_riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ use system_error::SystemError;

use crate::{
arch::{interrupt::TrapFrame, time::riscv_time_base_freq, CurrentIrqArch, CurrentTimeArch},
driver::base::device::DeviceId,
driver::{
base::device::DeviceId,
irqchip::riscv_intc::{riscv_intc_assicate_irq, riscv_intc_hwirq_to_virq},
},
exception::{
irqdata::{IrqHandlerData, IrqLineStatus},
irqdesc::{
irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandleFlags, IrqHandler, IrqReturn,
},
manage::irq_manager,
InterruptArch, IrqNumber,
HardwareIrqNumber, InterruptArch, IrqNumber,
},
libs::spinlock::SpinLock,
mm::percpu::PerCpu,
Expand Down Expand Up @@ -42,7 +45,7 @@ static mut HART0_NSEC_PASSED: usize = 0;
static mut HART0_LAST_UPDATED: u64 = 0;

impl RiscVSbiTimer {
pub const TIMER_IRQ: IrqNumber = IrqNumber::from(5);
pub const TIMER_IRQ: HardwareIrqNumber = HardwareIrqNumber::new(5);

fn handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
// 更新下一次中断时间
Expand Down Expand Up @@ -117,7 +120,7 @@ pub fn riscv_sbi_timer_init_local() {

irq_manager()
.request_irq(
RiscVSbiTimer::TIMER_IRQ,
riscv_intc_hwirq_to_virq(RiscVSbiTimer::TIMER_IRQ).unwrap(),
"riscv_clocksource".to_string(),
&RiscvSbiTimerHandler,
IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU,
Expand All @@ -136,7 +139,8 @@ pub fn riscv_sbi_timer_init_local() {

#[inline(never)]
pub fn riscv_sbi_timer_irq_desc_init() {
let desc = irq_desc_manager().lookup(RiscVSbiTimer::TIMER_IRQ).unwrap();
let virq = riscv_intc_assicate_irq(RiscVSbiTimer::TIMER_IRQ).unwrap();
let desc = irq_desc_manager().lookup(virq).unwrap();

desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
desc.set_handler(&RiscvSbiTimerIrqFlowHandler);
Expand Down
2 changes: 2 additions & 0 deletions kernel/src/driver/irqchip/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
#[cfg(target_arch = "riscv64")]
pub mod riscv_intc;
#[cfg(target_arch = "riscv64")]
pub mod riscv_sifive_plic;
64 changes: 60 additions & 4 deletions kernel/src/driver/irqchip/riscv_intc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use crate::{
sched::{SchedMode, __schedule},
};

use super::riscv_sifive_plic::do_plic_irq;

static mut RISCV_INTC_DOMAIN: Option<Arc<IrqDomain>> = None;
static mut RISCV_INTC_CHIP: Option<Arc<RiscvIntcChip>> = None;

Expand All @@ -30,6 +32,9 @@ fn riscv_intc_chip() -> Option<&'static Arc<RiscvIntcChip>> {
unsafe { RISCV_INTC_CHIP.as_ref() }
}

/// RISC-V INTC虚拟中断号的起始值(192映射物理的0)
pub const RISCV_INTC_VIRQ_START: u32 = 192;

#[derive(Debug)]
struct RiscvIntcChip {
inner: SpinLock<InnerIrqChip>,
Expand Down Expand Up @@ -87,6 +92,7 @@ impl IrqChip for RiscvIntcChip {
}

impl RiscvIntcChip {
const IRQ_SIZE: u32 = 64;
fn new() -> Self {
Self {
inner: SpinLock::new(InnerIrqChip {
Expand Down Expand Up @@ -143,7 +149,11 @@ pub unsafe fn riscv_intc_init() -> Result<(), SystemError> {
}

let intc_domain = irq_domain_manager()
.create_and_add_linear("riscv-intc".to_string(), &RiscvIntcDomainOps, 64)
.create_and_add_linear(
"riscv-intc".to_string(),
&RiscvIntcDomainOps,
RiscvIntcChip::IRQ_SIZE,
)
.ok_or_else(|| {
kerror!("Failed to create riscv-intc domain");
SystemError::ENXIO
Expand All @@ -152,20 +162,66 @@ pub unsafe fn riscv_intc_init() -> Result<(), SystemError> {
irq_domain_manager().set_default_domain(intc_domain.clone());

unsafe {
RISCV_INTC_DOMAIN = Some(intc_domain);
RISCV_INTC_DOMAIN = Some(intc_domain.clone());
}

riscv_sbi_timer_irq_desc_init();

return Ok(());
}

/// 把硬件中断号转换为riscv intc芯片的中断域的虚拟中断号
pub const fn riscv_intc_hwirq_to_virq(hwirq: HardwareIrqNumber) -> Option<IrqNumber> {
if hwirq.data() < RiscvIntcChip::IRQ_SIZE {
Some(IrqNumber::new(hwirq.data() + RISCV_INTC_VIRQ_START))
} else {
None
}
}

/// 把riscv intc芯片的的中断域的虚拟中断号转换为硬件中断号
#[allow(dead_code)]
pub const fn riscv_intc_virq_to_hwirq(virq: IrqNumber) -> Option<HardwareIrqNumber> {
if virq.data() >= RISCV_INTC_VIRQ_START
&& virq.data() < RISCV_INTC_VIRQ_START + RiscvIntcChip::IRQ_SIZE
{
Some(HardwareIrqNumber::new(virq.data() - RISCV_INTC_VIRQ_START))
} else {
None
}
}

/// 将硬件中断号与riscv intc芯片的虚拟中断号关联
pub fn riscv_intc_assicate_irq(hwirq: HardwareIrqNumber) -> Option<IrqNumber> {
let virq = riscv_intc_hwirq_to_virq(hwirq)?;
irq_domain_manager()
.domain_associate(
riscv_intc_domain().as_ref().or_else(|| {
kerror!("riscv_intc_domain is None");
None
})?,
virq,
hwirq,
)
.ok();

Some(virq)
}

/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/irqchip/irq-riscv-intc.c#23
pub fn riscv_intc_irq(trap_frame: &mut TrapFrame) {
let hwirq = HardwareIrqNumber::new(trap_frame.cause.code() as u32);
// kdebug!("riscv64_do_irq: interrupt {hwirq:?}");
GenericIrqHandler::handle_domain_irq(riscv_intc_domain().clone().unwrap(), hwirq, trap_frame)
if hwirq.data() == 9 {
// external interrupt
do_plic_irq(trap_frame);
} else {
GenericIrqHandler::handle_domain_irq(
riscv_intc_domain().clone().unwrap(),
hwirq,
trap_frame,
)
.ok();
}
do_softirq();
if hwirq.data() == RiscVSbiTimer::TIMER_IRQ.data() {
__schedule(SchedMode::SM_PREEMPT);
Expand Down
Loading