Rename IrqAllocateHandle and move alloc functions

This commit is contained in:
Yuke Peng
2023-09-03 01:12:45 +08:00
committed by Tate, Hongliang Tian
parent 7d5e67e368
commit dbf5a423b1
12 changed files with 162 additions and 160 deletions

View File

@ -55,7 +55,7 @@ const COMMON_ARGS: &[&str] = &[
"-device", "-device",
"isa-debug-exit,iobase=0xf4,iosize=0x04", "isa-debug-exit,iobase=0xf4,iosize=0x04",
"-netdev", "-netdev",
"user,id=net01,hostfwd=tcp::30033-:22,hostfwd=tcp::30088-:8080", "user,id=net01,hostfwd=tcp::30133-:22,hostfwd=tcp::31088-:8080",
"-object", "-object",
"filter-dump,id=filter0,netdev=net01,file=virtio-net.pcap", "filter-dump,id=filter0,netdev=net01,file=virtio-net.pcap",
]; ];

View File

@ -2,7 +2,7 @@
use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess}; use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
use crate::sync::SpinLock; use crate::sync::SpinLock;
use crate::trap::IrqAllocateHandle; use crate::trap::IrqLine;
use alloc::{sync::Arc, vec::Vec}; use alloc::{sync::Arc, vec::Vec};
use log::debug; use log::debug;
use spin::Once; use spin::Once;
@ -25,7 +25,7 @@ static SERIAL_MODEM_CTRL: IoPort<u8, WriteOnlyAccess> =
unsafe { IoPort::new(SERIAL_DATA_PORT + 4) }; unsafe { IoPort::new(SERIAL_DATA_PORT + 4) };
static SERIAL_LINE_STS: IoPort<u8, ReadWriteAccess> = unsafe { IoPort::new(SERIAL_DATA_PORT + 5) }; static SERIAL_LINE_STS: IoPort<u8, ReadWriteAccess> = unsafe { IoPort::new(SERIAL_DATA_PORT + 5) };
static CONSOLE_IRQ_CALLBACK: Once<SpinLock<IrqAllocateHandle>> = Once::new(); static CONSOLE_IRQ_CALLBACK: Once<SpinLock<IrqLine>> = Once::new();
static SERIAL_INPUT_CALLBACKS: SpinLock<Vec<Arc<dyn Fn(u8) + Send + Sync + 'static>>> = static SERIAL_INPUT_CALLBACKS: SpinLock<Vec<Arc<dyn Fn(u8) + Send + Sync + 'static>>> =
SpinLock::new(Vec::new()); SpinLock::new(Vec::new());

View File

@ -7,7 +7,7 @@ use spin::Once;
use trapframe::TrapFrame; use trapframe::TrapFrame;
use volatile::{access::ReadWrite, Volatile}; use volatile::{access::ReadWrite, Volatile};
use crate::{trap::IrqAllocateHandle, vm::Vaddr}; use crate::{trap::IrqLine, vm::Vaddr};
use super::remapping::Capability; use super::remapping::Capability;
@ -21,7 +21,7 @@ pub struct FaultEventRegisters {
upper_address: Volatile<&'static mut u32, ReadWrite>, upper_address: Volatile<&'static mut u32, ReadWrite>,
recordings: Vec<Volatile<&'static mut u128, ReadWrite>>, recordings: Vec<Volatile<&'static mut u128, ReadWrite>>,
fault_irq: IrqAllocateHandle, fault_irq: IrqLine,
} }
impl FaultEventRegisters { impl FaultEventRegisters {
@ -47,7 +47,7 @@ impl FaultEventRegisters {
let mut data = Volatile::new(&mut *((base_register_vaddr + 0x3c) as *mut u32)); let mut data = Volatile::new(&mut *((base_register_vaddr + 0x3c) as *mut u32));
let mut address = Volatile::new(&mut *((base_register_vaddr + 0x40) as *mut u32)); let mut address = Volatile::new(&mut *((base_register_vaddr + 0x40) as *mut u32));
let upper_address = Volatile::new(&mut *((base_register_vaddr + 0x44) as *mut u32)); let upper_address = Volatile::new(&mut *((base_register_vaddr + 0x44) as *mut u32));
let mut fault_irq = crate::trap::allocate_irq().unwrap(); let mut fault_irq = crate::trap::IrqLine::alloc().unwrap();
// Set page fault interrupt vector and address // Set page fault interrupt vector and address
data.write(fault_irq.num() as u32); data.write(fault_irq.num() as u32);

View File

@ -1,12 +1,16 @@
use crate::sync::Mutex; use crate::sync::Mutex;
use alloc::vec::Vec; use alloc::{boxed::Box, fmt::Debug, sync::Arc, vec::Vec};
use spin::Once; use spin::Once;
use trapframe::TrapFrame;
use crate::{trap::IrqLine, util::recycle_allocator::RecycleAllocator}; use crate::{
sync::{SpinLock, SpinLockGuard},
util::recycle_allocator::RecycleAllocator,
};
/// The IRQ numbers which are not using /// The IRQ numbers which are not using
pub(crate) static NOT_USING_IRQ: Mutex<RecycleAllocator> = pub(crate) static NOT_USING_IRQ: SpinLock<RecycleAllocator> =
Mutex::new(RecycleAllocator::with_start_max(32, 256)); SpinLock::new(RecycleAllocator::with_start_max(32, 256));
pub(crate) static IRQ_LIST: Once<Vec<IrqLine>> = Once::new(); pub(crate) static IRQ_LIST: Once<Vec<IrqLine>> = Once::new();
@ -15,7 +19,7 @@ pub(crate) fn init() {
for i in 0..256 { for i in 0..256 {
list.push(IrqLine { list.push(IrqLine {
irq_num: i as u8, irq_num: i as u8,
callback_list: Mutex::new(Vec::new()), callback_list: SpinLock::new(Vec::new()),
}); });
} }
IRQ_LIST.call_once(|| list); IRQ_LIST.call_once(|| list);
@ -32,3 +36,97 @@ pub(crate) fn disable_local() {
pub(crate) fn is_local_enabled() -> bool { pub(crate) fn is_local_enabled() -> bool {
x86_64::instructions::interrupts::are_enabled() x86_64::instructions::interrupts::are_enabled()
} }
static ID_ALLOCATOR: Mutex<RecycleAllocator> = Mutex::new(RecycleAllocator::new());
pub struct CallbackElement {
function: Box<dyn Fn(&TrapFrame) + Send + Sync + 'static>,
id: usize,
}
impl CallbackElement {
pub fn call(&self, element: &TrapFrame) {
self.function.call((element,));
}
}
impl Debug for CallbackElement {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("CallbackElement")
.field("id", &self.id)
.finish()
}
}
/// An interrupt request (IRQ) line.
#[derive(Debug)]
pub(crate) struct IrqLine {
pub(crate) irq_num: u8,
pub(crate) callback_list: SpinLock<Vec<CallbackElement>>,
}
impl IrqLine {
/// Acquire an interrupt request line.
///
/// # Safety
///
/// This function is marked unsafe as manipulating interrupt lines is
/// considered a dangerous operation.
pub unsafe fn acquire(irq_num: u8) -> Arc<&'static Self> {
Arc::new(IRQ_LIST.get().unwrap().get(irq_num as usize).unwrap())
}
/// Get the IRQ number.
pub fn num(&self) -> u8 {
self.irq_num
}
pub fn callback_list(&self) -> SpinLockGuard<'_, alloc::vec::Vec<CallbackElement>> {
self.callback_list.lock()
}
/// Register a callback that will be invoked when the IRQ is active.
///
/// A handle to the callback is returned. Dropping the handle
/// automatically unregisters the callback.
///
/// For each IRQ line, multiple callbacks may be registered.
pub fn on_active<F>(&self, callback: F) -> IrqCallbackHandle
where
F: Fn(&TrapFrame) + Sync + Send + 'static,
{
let allocate_id = ID_ALLOCATOR.lock().alloc();
self.callback_list.lock().push(CallbackElement {
function: Box::new(callback),
id: allocate_id,
});
IrqCallbackHandle {
irq_num: self.irq_num,
id: allocate_id,
}
}
}
/// The handle to a registered callback for a IRQ line.
///
/// When the handle is dropped, the callback will be unregistered automatically.
#[must_use]
#[derive(Debug)]
pub struct IrqCallbackHandle {
irq_num: u8,
id: usize,
}
impl Drop for IrqCallbackHandle {
fn drop(&mut self) {
let mut a = IRQ_LIST
.get()
.unwrap()
.get(self.irq_num as usize)
.unwrap()
.callback_list
.lock();
a.retain(|item| if (*item).id == self.id { false } else { true });
ID_ALLOCATOR.lock().dealloc(self.id);
}
}

View File

@ -1,6 +1,5 @@
use crate::arch::x86::device::io_port::{IoPort, WriteOnlyAccess}; use crate::arch::x86::device::io_port::{IoPort, WriteOnlyAccess};
use crate::trap::allocate_target_irq; use crate::trap::IrqLine;
use crate::trap::IrqAllocateHandle;
use core::sync::atomic::Ordering::Relaxed; use core::sync::atomic::Ordering::Relaxed;
use core::sync::atomic::{AtomicBool, AtomicU8}; use core::sync::atomic::{AtomicBool, AtomicU8};
@ -22,7 +21,7 @@ use log::info;
lazy_static! { lazy_static! {
/// store the irq, although we have APIC for manage interrupts /// store the irq, although we have APIC for manage interrupts
/// but something like serial still need pic for register interrupts /// but something like serial still need pic for register interrupts
static ref IRQ_LOCK : Mutex<Vec<IrqAllocateHandle>> = Mutex::new(Vec::new()); static ref IRQ_LOCK : Mutex<Vec<IrqLine>> = Mutex::new(Vec::new());
} }
static MASK_MASTER: AtomicU8 = AtomicU8::new(0x00); static MASK_MASTER: AtomicU8 = AtomicU8::new(0x00);
@ -46,11 +45,11 @@ pub fn init() {
} }
/// allocate irq, for example, if timer need IRQ0, it will return IrqAllocateHandle with irq num: IRQ_OFFSET+0 /// allocate irq, for example, if timer need IRQ0, it will return IrqAllocateHandle with irq num: IRQ_OFFSET+0
pub fn allocate_irq(index: u8) -> Option<IrqAllocateHandle> { pub fn allocate_irq(index: u8) -> Option<IrqLine> {
if index >= 16 { if index >= 16 {
return None; return None;
} }
if let Ok(irq) = allocate_target_irq(IRQ_OFFSET + index) { if let Ok(irq) = IrqLine::alloc_specific(IRQ_OFFSET + index) {
if index >= 8 { if index >= 8 {
MASK_SLAVE.fetch_or(1 << (index - 8), Relaxed); MASK_SLAVE.fetch_or(1 << (index - 8), Relaxed);
} else { } else {

View File

@ -9,6 +9,7 @@ use trapframe::TrapFrame;
use x86::cpuid::cpuid; use x86::cpuid::cpuid;
use x86::msr::{wrmsr, IA32_TSC_DEADLINE}; use x86::msr::{wrmsr, IA32_TSC_DEADLINE};
use crate::arch::irq::IrqLine;
use crate::{ use crate::{
arch::x86::kernel::{ arch::x86::kernel::{
apic::{DivideConfig, APIC_INSTANCE}, apic::{DivideConfig, APIC_INSTANCE},
@ -63,7 +64,7 @@ fn tsc_mode_init() {
fn periodic_mode_init() { fn periodic_mode_init() {
let mut apic_lock = APIC_INSTANCE.get().unwrap().lock(); let mut apic_lock = APIC_INSTANCE.get().unwrap().lock();
let handle = unsafe { crate::trap::IrqLine::acquire(super::TIMER_IRQ_NUM) }; let handle = unsafe { IrqLine::acquire(super::TIMER_IRQ_NUM) };
let a = handle.on_active(init_function); let a = handle.on_active(init_function);
// divide by 64 // divide by 64
apic_lock.set_timer_div_config(DivideConfig::Divide64); apic_lock.set_timer_div_config(DivideConfig::Divide64);

View File

@ -12,14 +12,14 @@ use trapframe::TrapFrame;
use crate::arch::x86::kernel; use crate::arch::x86::kernel;
use crate::config::TIMER_FREQ; use crate::config::TIMER_FREQ;
use crate::sync::SpinLock; use crate::sync::SpinLock;
use crate::trap::IrqAllocateHandle; use crate::trap::IrqLine;
use self::apic::APIC_TIMER_CALLBACK; use self::apic::APIC_TIMER_CALLBACK;
pub const TIMER_IRQ_NUM: u8 = 32; pub const TIMER_IRQ_NUM: u8 = 32;
pub static TICK: AtomicU64 = AtomicU64::new(0); pub static TICK: AtomicU64 = AtomicU64::new(0);
static TIMER_IRQ: Once<IrqAllocateHandle> = Once::new(); static TIMER_IRQ: Once<IrqLine> = Once::new();
pub fn init() { pub fn init() {
TIMEOUT_LIST.call_once(|| SpinLock::new(BinaryHeap::new())); TIMEOUT_LIST.call_once(|| SpinLock::new(BinaryHeap::new()));
@ -29,7 +29,7 @@ pub fn init() {
pit::init(); pit::init();
} }
let mut timer_irq = let mut timer_irq =
crate::trap::allocate_target_irq(TIMER_IRQ_NUM).expect("Timer irq Allocate error"); crate::trap::IrqLine::alloc_specific(TIMER_IRQ_NUM).expect("Timer irq Allocate error");
timer_irq.on_active(timer_callback); timer_irq.on_active(timer_callback);
TIMER_IRQ.call_once(|| timer_irq); TIMER_IRQ.call_once(|| timer_irq);
} }

View File

@ -6,7 +6,7 @@ use crate::{
common_device::PciCommonDevice, common_device::PciCommonDevice,
device_info::PciDeviceLocation, device_info::PciDeviceLocation,
}, },
trap::IrqAllocateHandle, trap::IrqLine,
vm::VmIo, vm::VmIo,
}; };
@ -24,7 +24,7 @@ pub struct CapabilityMsixData {
pending_table_bar: Arc<MemoryBar>, pending_table_bar: Arc<MemoryBar>,
table_offset: usize, table_offset: usize,
pending_table_offset: usize, pending_table_offset: usize,
irqs: Vec<Option<IrqAllocateHandle>>, irqs: Vec<Option<IrqLine>>,
} }
impl Clone for CapabilityMsixData { impl Clone for CapabilityMsixData {
@ -109,9 +109,9 @@ impl CapabilityMsixData {
// disable INTx, enable Bus master. // disable INTx, enable Bus master.
dev.set_command(dev.command() | Command::INTERRUPT_DISABLE | Command::BUS_MASTER); dev.set_command(dev.command() | Command::INTERRUPT_DISABLE | Command::BUS_MASTER);
let mut irq_allocate_handles = Vec::with_capacity(table_size as usize); let mut irqs = Vec::with_capacity(table_size as usize);
for i in 0..table_size { for i in 0..table_size {
irq_allocate_handles.push(None); irqs.push(None);
} }
Self { Self {
@ -120,7 +120,7 @@ impl CapabilityMsixData {
table_size: (dev.location().read16(cap_ptr + 2) & 0b11_1111_1111) + 1, table_size: (dev.location().read16(cap_ptr + 2) & 0b11_1111_1111) + 1,
table_bar, table_bar,
pending_table_bar: pba_bar, pending_table_bar: pba_bar,
irqs: irq_allocate_handles, irqs,
table_offset: table_offset, table_offset: table_offset,
pending_table_offset: pba_offset, pending_table_offset: pba_offset,
} }
@ -131,7 +131,7 @@ impl CapabilityMsixData {
(self.loc.read16(self.ptr + 2) & 0b11_1111_1111) + 1 (self.loc.read16(self.ptr + 2) & 0b11_1111_1111) + 1
} }
pub fn set_interrupt_vector(&mut self, handle: IrqAllocateHandle, index: u16) { pub fn set_interrupt_vector(&mut self, handle: IrqLine, index: u16) {
if index >= self.table_size { if index >= self.table_size {
return; return;
} }
@ -150,7 +150,7 @@ impl CapabilityMsixData {
.unwrap(); .unwrap();
} }
pub fn irq_mut(&mut self, index: usize) -> Option<&mut IrqAllocateHandle> { pub fn irq_mut(&mut self, index: usize) -> Option<&mut IrqLine> {
self.irqs[index].as_mut() self.irqs[index].as_mut()
} }
} }

View File

@ -38,8 +38,8 @@ pub use self::cpu::CpuLocal;
pub use self::error::Error; pub use self::error::Error;
pub use self::prelude::Result; pub use self::prelude::Result;
use alloc::vec::Vec; use alloc::vec::Vec;
use arch::irq::{IrqCallbackHandle, IrqLine};
use core::{mem, panic::PanicInfo}; use core::{mem, panic::PanicInfo};
use trap::{IrqCallbackHandle, IrqLine};
use trapframe::TrapFrame; use trapframe::TrapFrame;
static mut IRQ_CALLBACK_LIST: Vec<IrqCallbackHandle> = Vec::new(); static mut IRQ_CALLBACK_LIST: Vec<IrqCallbackHandle> = Vec::new();

View File

@ -1,46 +1,46 @@
use crate::arch::irq; use crate::arch::irq::{self, IrqCallbackHandle, NOT_USING_IRQ};
use crate::arch::irq::{IRQ_LIST, NOT_USING_IRQ};
use crate::sync::{Mutex, MutexGuard};
use crate::task::{disable_preempt, DisablePreemptGuard}; use crate::task::{disable_preempt, DisablePreemptGuard};
use crate::util::recycle_allocator::RecycleAllocator;
use crate::{prelude::*, Error}; use crate::{prelude::*, Error};
use core::fmt::Debug; use core::fmt::Debug;
use trapframe::TrapFrame; use trapframe::TrapFrame;
pub fn allocate_irq() -> Result<IrqAllocateHandle> { /// An Interrupt ReQuest(IRQ) line. User can use `alloc` or `alloc_specific` to get specific IRQ line.
///
/// The IRQ number is guaranteed to be external IRQ number and user can register callback functions to this IRQ resource.
/// When this resrouce is dropped, all the callback in this will be unregistered automatically.
#[derive(Debug)]
#[must_use]
pub struct IrqLine {
irq_num: u8,
irq: Arc<&'static irq::IrqLine>,
callbacks: Vec<IrqCallbackHandle>,
}
impl IrqLine {
pub fn alloc_specific(irq: u8) -> Result<Self> {
if NOT_USING_IRQ.lock().get_target(irq as usize) {
Ok(Self::new(irq))
} else {
Err(Error::NotEnoughResources)
}
}
pub fn alloc() -> Result<Self> {
let irq_num = NOT_USING_IRQ.lock().alloc(); let irq_num = NOT_USING_IRQ.lock().alloc();
if irq_num == usize::MAX { if irq_num == usize::MAX {
Err(Error::NotEnoughResources) Err(Error::NotEnoughResources)
} else { } else {
Ok(IrqAllocateHandle::new(irq_num as u8)) Ok(Self::new(irq_num as u8))
} }
} }
pub(crate) fn allocate_target_irq(target_irq: u8) -> Result<IrqAllocateHandle> {
if NOT_USING_IRQ.lock().get_target(target_irq as usize) {
Ok(IrqAllocateHandle::new(target_irq))
} else {
Err(Error::NotEnoughResources)
}
}
/// The handle to a allocate irq number between [32,256), used in std and other parts in jinux
///
/// When the handle is dropped, all the callback in this will be unregistered automatically.
#[derive(Debug)]
#[must_use]
pub struct IrqAllocateHandle {
irq_num: u8,
irq: Arc<&'static IrqLine>,
callbacks: Vec<IrqCallbackHandle>,
}
impl IrqAllocateHandle {
fn new(irq_num: u8) -> Self { fn new(irq_num: u8) -> Self {
// Safety: The IRQ number is allocated through `RecycleAllocator`, and it is guaranteed that the
// IRQ is not one of the important IRQ like cpu exception IRQ.
Self { Self {
irq_num, irq_num,
irq: unsafe { IrqLine::acquire(irq_num) }, irq: unsafe { irq::IrqLine::acquire(irq_num) },
callbacks: Vec::new(), callbacks: Vec::new(),
} }
} }
@ -65,7 +65,7 @@ impl IrqAllocateHandle {
} }
} }
impl Clone for IrqAllocateHandle { impl Clone for IrqLine {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
irq_num: self.irq_num.clone(), irq_num: self.irq_num.clone(),
@ -75,7 +75,7 @@ impl Clone for IrqAllocateHandle {
} }
} }
impl Drop for IrqAllocateHandle { impl Drop for IrqLine {
fn drop(&mut self) { fn drop(&mut self) {
if Arc::strong_count(&self.irq) == 1 { if Arc::strong_count(&self.irq) == 1 {
NOT_USING_IRQ.lock().dealloc(self.irq_num as usize); NOT_USING_IRQ.lock().dealloc(self.irq_num as usize);
@ -83,101 +83,6 @@ impl Drop for IrqAllocateHandle {
} }
} }
static ID_ALLOCATOR: Mutex<RecycleAllocator> = Mutex::new(RecycleAllocator::new());
pub struct CallbackElement {
function: Box<dyn Fn(&TrapFrame) + Send + Sync + 'static>,
id: usize,
}
impl CallbackElement {
pub fn call(&self, element: &TrapFrame) {
self.function.call((element,));
}
}
impl Debug for CallbackElement {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("CallbackElement")
.field("id", &self.id)
.finish()
}
}
/// An interrupt request (IRQ) line.
#[derive(Debug)]
pub(crate) struct IrqLine {
pub(crate) irq_num: u8,
pub(crate) callback_list: Mutex<Vec<CallbackElement>>,
}
impl IrqLine {
/// Acquire an interrupt request line.
///
/// # Safety
///
/// This function is marked unsafe as manipulating interrupt lines is
/// considered a dangerous operation.
pub unsafe fn acquire(irq_num: u8) -> Arc<&'static Self> {
Arc::new(IRQ_LIST.get().unwrap().get(irq_num as usize).unwrap())
}
/// Get the IRQ number.
pub fn num(&self) -> u8 {
self.irq_num
}
pub fn callback_list(&self) -> MutexGuard<'_, alloc::vec::Vec<CallbackElement>> {
self.callback_list.lock()
}
/// Register a callback that will be invoked when the IRQ is active.
///
/// A handle to the callback is returned. Dropping the handle
/// automatically unregisters the callback.
///
/// For each IRQ line, multiple callbacks may be registered.
pub fn on_active<F>(&self, callback: F) -> IrqCallbackHandle
where
F: Fn(&TrapFrame) + Sync + Send + 'static,
{
let allocate_id = ID_ALLOCATOR.lock().alloc();
self.callback_list.lock().push(CallbackElement {
function: Box::new(callback),
id: allocate_id,
});
IrqCallbackHandle {
irq_num: self.irq_num,
id: allocate_id,
}
}
}
/// The handle to a registered callback for a IRQ line.
///
/// When the handle is dropped, the callback will be unregistered automatically.
#[must_use]
#[derive(Debug)]
pub struct IrqCallbackHandle {
irq_num: u8,
id: usize,
// cursor: CursorMut<'a, Box<dyn Fn(&IrqLine)+Sync+Send+'static>>
}
impl Drop for IrqCallbackHandle {
fn drop(&mut self) {
let mut a = IRQ_LIST
.get()
.unwrap()
.get(self.irq_num as usize)
.unwrap()
.callback_list
.lock();
a.retain(|item| if (*item).id == self.id { false } else { true });
ID_ALLOCATOR.lock().dealloc(self.id);
}
}
/// Disable all IRQs on the current CPU (i.e., locally). /// Disable all IRQs on the current CPU (i.e., locally).
/// ///
/// This function returns a guard object, which will automatically enable local IRQs again when /// This function returns a guard object, which will automatically enable local IRQs again when

View File

@ -2,8 +2,7 @@ mod handler;
mod irq; mod irq;
pub(crate) use self::handler::call_irq_callback_functions; pub(crate) use self::handler::call_irq_callback_functions;
pub use self::irq::{allocate_irq, disable_local, DisabledLocalIrqGuard, IrqAllocateHandle}; pub use self::irq::{disable_local, DisabledLocalIrqGuard, IrqLine};
pub(crate) use self::irq::{allocate_target_irq, IrqCallbackHandle, IrqLine};
pub use trapframe::TrapFrame; pub use trapframe::TrapFrame;
pub(crate) fn init() { pub(crate) fn init() {

View File

@ -1,5 +1,5 @@
use alloc::vec::Vec; use alloc::vec::Vec;
use jinux_frame::{bus::pci::capability::msix::CapabilityMsixData, trap::IrqAllocateHandle}; use jinux_frame::{bus::pci::capability::msix::CapabilityMsixData, trap::IrqLine};
pub struct VirtioMsixManager { pub struct VirtioMsixManager {
config_msix_vector: u16, config_msix_vector: u16,
@ -17,8 +17,8 @@ impl VirtioMsixManager {
pub fn new(mut msix: CapabilityMsixData) -> Self { pub fn new(mut msix: CapabilityMsixData) -> Self {
let mut msix_vector_list: Vec<u16> = (0..msix.table_size()).collect(); let mut msix_vector_list: Vec<u16> = (0..msix.table_size()).collect();
for i in msix_vector_list.iter() { for i in msix_vector_list.iter() {
let allocate_handle = jinux_frame::trap::allocate_irq().unwrap(); let irq = jinux_frame::trap::IrqLine::alloc().unwrap();
msix.set_interrupt_vector(allocate_handle, *i); msix.set_interrupt_vector(irq, *i);
} }
let config_msix_vector = msix_vector_list.pop().unwrap(); let config_msix_vector = msix_vector_list.pop().unwrap();
let shared_interrupt_vector = msix_vector_list.pop().unwrap(); let shared_interrupt_vector = msix_vector_list.pop().unwrap();
@ -32,7 +32,7 @@ impl VirtioMsixManager {
} }
/// Get config space change MSI-X IRQ, this function will return the MSI-X vector and corresponding IRQ. /// Get config space change MSI-X IRQ, this function will return the MSI-X vector and corresponding IRQ.
pub fn config_msix_irq(&mut self) -> (u16, &mut IrqAllocateHandle) { pub fn config_msix_irq(&mut self) -> (u16, &mut IrqLine) {
( (
self.config_msix_vector, self.config_msix_vector,
self.msix.irq_mut(self.config_msix_vector as usize).unwrap(), self.msix.irq_mut(self.config_msix_vector as usize).unwrap(),
@ -42,7 +42,7 @@ impl VirtioMsixManager {
/// Get shared interrupt IRQ used by virtqueue. If a virtqueue will not send interrupt frequently. /// Get shared interrupt IRQ used by virtqueue. If a virtqueue will not send interrupt frequently.
/// Then this virtqueue should use shared interrupt IRQ. /// Then this virtqueue should use shared interrupt IRQ.
/// This function will return the MSI-X vector and corresponding IRQ. /// This function will return the MSI-X vector and corresponding IRQ.
pub fn shared_interrupt_irq(&mut self) -> (u16, &mut IrqAllocateHandle) { pub fn shared_interrupt_irq(&mut self) -> (u16, &mut IrqLine) {
( (
self.shared_interrupt_vector, self.shared_interrupt_vector,
self.msix self.msix
@ -54,7 +54,7 @@ impl VirtioMsixManager {
/// Pop unused vector. If a virtqueue will send interrupt frequently. /// Pop unused vector. If a virtqueue will send interrupt frequently.
/// Then this virtqueue should use the single IRQ that this function provides. /// Then this virtqueue should use the single IRQ that this function provides.
/// this function will return the MSI-X vector and corresponding IRQ. /// this function will return the MSI-X vector and corresponding IRQ.
pub fn pop_unused_irq(&mut self) -> Option<(u16, &mut IrqAllocateHandle)> { pub fn pop_unused_irq(&mut self) -> Option<(u16, &mut IrqLine)> {
let vector = self.unused_msix_vectors.pop()?; let vector = self.unused_msix_vectors.pop()?;
self.used_msix_vectors.push(vector); self.used_msix_vectors.push(vector);
Some((vector, self.msix.irq_mut(vector as usize).unwrap())) Some((vector, self.msix.irq_mut(vector as usize).unwrap()))