Browse Source

完成中断管理模块重构 (#554)

- 支持中断共享
- 把现有驱动程序移植到新的irq模块
- 使用`ProcessorId`标识处理器id
- 尚未实现threaded_irq

性能上,edge irq flow handler里面,对于锁的使用,可能有点问题。为了获取/修改common data还有其他几个结构体的状态,进行了多次加锁和放锁,导致性能降低。这是接下来需要优化的点。
LoGin 1 year ago
parent
commit
e28411791f
100 changed files with 4472 additions and 2122 deletions
  1. 0 8
      .vscode/settings.json
  2. 0 1
      build-scripts/kernel_build/src/cfiles/arch/x86_64.rs
  3. 0 9
      docs/kernel/core_api/softirq.md
  4. 1 0
      kernel/crates/bitmap/src/alloc_bitmap.rs
  5. 1 1
      kernel/src/Makefile
  6. 3 1
      kernel/src/arch/riscv64/cpu.rs
  7. 9 6
      kernel/src/arch/x86_64/acpi.rs
  8. 7 2
      kernel/src/arch/x86_64/c_adapter.rs
  9. 5 3
      kernel/src/arch/x86_64/cpu.rs
  10. 0 205
      kernel/src/arch/x86_64/driver/apic/apic.c
  11. 0 284
      kernel/src/arch/x86_64/driver/apic/apic.h
  12. 0 96
      kernel/src/arch/x86_64/driver/apic/apic_timer.c
  13. 0 14
      kernel/src/arch/x86_64/driver/apic/apic_timer.h
  14. 89 15
      kernel/src/arch/x86_64/driver/apic/apic_timer.rs
  15. 1 75
      kernel/src/arch/x86_64/driver/apic/c_adapter.rs
  16. 9 0
      kernel/src/arch/x86_64/driver/apic/hw_irq.rs
  17. 318 24
      kernel/src/arch/x86_64/driver/apic/ioapic.rs
  18. 289 0
      kernel/src/arch/x86_64/driver/apic/lapic_vector.rs
  19. 13 13
      kernel/src/arch/x86_64/driver/apic/mod.rs
  20. 3 3
      kernel/src/arch/x86_64/driver/apic/x2apic.rs
  21. 6 6
      kernel/src/arch/x86_64/driver/apic/xapic.rs
  22. 0 6
      kernel/src/arch/x86_64/driver/c_adapter.rs
  23. 0 26
      kernel/src/arch/x86_64/driver/hpet.c
  24. 34 8
      kernel/src/arch/x86_64/driver/hpet.rs
  25. 0 1
      kernel/src/arch/x86_64/driver/mod.rs
  26. 0 30
      kernel/src/arch/x86_64/include/x86_64_ipi.h
  27. 3 1
      kernel/src/arch/x86_64/interrupt/c_adapter.rs
  28. 3 2
      kernel/src/arch/x86_64/interrupt/entry.rs
  29. 54 0
      kernel/src/arch/x86_64/interrupt/handle.rs
  30. 76 13
      kernel/src/arch/x86_64/interrupt/ipi.rs
  31. 8 5
      kernel/src/arch/x86_64/interrupt/mod.rs
  32. 89 0
      kernel/src/arch/x86_64/interrupt/msi.rs
  33. 20 20
      kernel/src/arch/x86_64/interrupt/trap.rs
  34. 0 15
      kernel/src/arch/x86_64/interrupt/x86_64_ipi.c
  35. 6 4
      kernel/src/arch/x86_64/kvm/vmx/ept.rs
  36. 4 4
      kernel/src/arch/x86_64/process/table.rs
  37. 22 7
      kernel/src/arch/x86_64/sched.rs
  38. 12 12
      kernel/src/arch/x86_64/smp/mod.rs
  39. 1 1
      kernel/src/driver/Makefile
  40. 1 1
      kernel/src/driver/base/device/driver.rs
  41. 9 3
      kernel/src/driver/base/device/mod.rs
  42. 45 0
      kernel/src/driver/input/ps2_dev/mod.rs
  43. 2 1
      kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs
  44. 36 12
      kernel/src/driver/input/ps2_mouse/ps_mouse_driver.rs
  45. 0 10
      kernel/src/driver/keyboard/Makefile
  46. 0 23
      kernel/src/driver/keyboard/mod.rs
  47. 0 209
      kernel/src/driver/keyboard/ps2_keyboard.c
  48. 0 40
      kernel/src/driver/keyboard/ps2_keyboard.h
  49. 126 49
      kernel/src/driver/keyboard/ps2_keyboard.rs
  50. 0 10
      kernel/src/driver/mouse/Makefile
  51. 0 58
      kernel/src/driver/mouse/ps2_mouse.c
  52. 0 38
      kernel/src/driver/mouse/ps2_mouse.h
  53. 21 15
      kernel/src/driver/net/e1000e/e1000e.rs
  54. 27 0
      kernel/src/driver/net/irq_handle.rs
  55. 1 0
      kernel/src/driver/net/mod.rs
  56. 33 7
      kernel/src/driver/net/virtio_net.rs
  57. 0 11
      kernel/src/driver/pci/Makefile
  58. 7 6
      kernel/src/driver/pci/pci.rs
  59. 0 95
      kernel/src/driver/pci/pci_irq.c
  60. 0 5
      kernel/src/driver/pci/pci_irq.h
  61. 89 54
      kernel/src/driver/pci/pci_irq.rs
  62. 85 0
      kernel/src/driver/virtio/irq.rs
  63. 16 0
      kernel/src/driver/virtio/mod.rs
  64. 63 14
      kernel/src/driver/virtio/transport_pci.rs
  65. 8 4
      kernel/src/driver/virtio/virtio.rs
  66. 0 8
      kernel/src/exception/Makefile
  67. 25 3
      kernel/src/exception/dummychip.rs
  68. 221 4
      kernel/src/exception/handle.rs
  69. 5 1
      kernel/src/exception/init.rs
  70. 51 2
      kernel/src/exception/ipi.rs
  71. 0 84
      kernel/src/exception/irq.c
  72. 0 175
      kernel/src/exception/irq.h
  73. 107 8
      kernel/src/exception/irqchip.rs
  74. 225 34
      kernel/src/exception/irqdata.rs
  75. 454 28
      kernel/src/exception/irqdesc.rs
  76. 333 9
      kernel/src/exception/irqdomain.rs
  77. 1093 0
      kernel/src/exception/manage.rs
  78. 26 0
      kernel/src/exception/mod.rs
  79. 8 0
      kernel/src/exception/msi.rs
  80. 91 0
      kernel/src/exception/resend.rs
  81. 0 25
      kernel/src/exception/softirq.h
  82. 16 31
      kernel/src/exception/softirq.rs
  83. 6 3
      kernel/src/exception/sysfs.rs
  84. 1 1
      kernel/src/filesystem/procfs/mod.rs
  85. 0 29
      kernel/src/filesystem/vfs/VFS.h
  86. 0 2
      kernel/src/include/bindings/wrapper.h
  87. 49 18
      kernel/src/libs/cpumask.rs
  88. 1 1
      kernel/src/libs/int_like.rs
  89. 2 2
      kernel/src/libs/lib_ui/textui.rs
  90. 3 1
      kernel/src/libs/wait_queue.rs
  91. 11 8
      kernel/src/mm/kernel_mapper.rs
  92. 7 7
      kernel/src/mm/percpu.rs
  93. 1 1
      kernel/src/process/c_adapter.rs
  94. 4 4
      kernel/src/process/idle.rs
  95. 17 1
      kernel/src/process/kthread.rs
  96. 25 30
      kernel/src/process/mod.rs
  97. 0 1
      kernel/src/process/process.h
  98. 16 0
      kernel/src/process/process.rs
  99. 10 7
      kernel/src/sched/cfs.rs
  100. 9 8
      kernel/src/sched/core.rs

+ 0 - 8
.vscode/settings.json

@@ -10,14 +10,12 @@
         "glib.h": "c",
         "asm.h": "c",
         "memory.h": "c",
-        "irq.h": "c",
         "multiboot2.h": "c",
         "kprint.h": "c",
         "8259a.h": "c",
         "ptrace.h": "c",
         "mouse.h": "c",
         "keyboard.h": "c",
-        "apic.h": "c",
         "ps2_keyboard.h": "c",
         "algorithm": "c",
         "array": "c",
@@ -27,7 +25,6 @@
         "cassert": "c",
         "cctype": "c",
         "cerrno": "c",
-        "cfloat": "c",
         "chrono": "c",
         "climits": "c",
         "clocale": "c",
@@ -83,7 +80,6 @@
         "cinttypes": "c",
         "cstdbool": "c",
         "typeinfo": "c",
-        "x86_64_ipi.h": "c",
         "unistd.h": "c",
         "syscall_num.h": "c",
         "stdint.h": "c",
@@ -92,7 +88,6 @@
         "types.h": "c",
         "string.h": "c",
         "math.h": "c",
-        "ipi.h": "c",
         "arch.h": "c",
         "stdio.h": "c",
         "wait_queue.h": "c",
@@ -109,10 +104,8 @@
         "ia64_msi.h": "c",
         "errno.h": "c",
         "bug.h": "c",
-        "apic_timer.h": "c",
         "sched.h": "c",
         "preempt.h": "c",
-        "softirq.h": "c",
         "screen_manager.h": "c",
         "textui.h": "c",
         "atomic.h": "c",
@@ -120,7 +113,6 @@
         "fat_ent.h": "c",
         "semaphore.h": "c",
         "mm-types.h": "c",
-        "vfs.h": "c",
         "current.h": "c",
         "traceback.h": "c",
         "bitcount.h": "c",

+ 0 - 1
build-scripts/kernel_build/src/cfiles/arch/x86_64.rs

@@ -18,7 +18,6 @@ impl CFilesArch for X86_64CFilesArch {
     }
 
     fn setup_files(&self, _c: &mut Build, files: &mut Vec<PathBuf>) {
-        files.push(arch_path("driver/hpet.c"));
         // 获取`kernel/src/arch/x86_64/driver/apic`下的所有C文件
         files.append(&mut FileUtils::list_all_files(
             &arch_path("driver/apic"),

+ 0 - 9
docs/kernel/core_api/softirq.md

@@ -162,12 +162,3 @@ fn main() {
 }
 ```
 
-### 3.4. 为C提供的接口
-
-```c
-extern void rs_softirq_init();
-extern void rs_raise_softirq(uint32_t sirq_num);
-extern void rs_unregister_softirq(uint32_t sirq_num);
-extern void rs_do_softirq();
-extern void rs_clear_softirq_pending(uint32_t softirq_num);
-```

+ 1 - 0
kernel/crates/bitmap/src/alloc_bitmap.rs

@@ -2,6 +2,7 @@ use alloc::vec::Vec;
 
 use crate::{bitmap_core::BitMapCore, traits::BitMapOps};
 
+#[derive(Clone)]
 pub struct AllocBitmap {
     elements: usize,
     data: Vec<usize>,

+ 1 - 1
kernel/src/Makefile

@@ -36,7 +36,7 @@ export ASFLAGS := --64
 LD_LIST := ""
 
 
-kernel_subdirs := common driver debug exception smp syscall libs time
+kernel_subdirs := common driver debug smp syscall libs time
 
 
 kernel_rust:

+ 3 - 1
kernel/src/arch/riscv64/cpu.rs

@@ -1,6 +1,8 @@
+use crate::smp::cpu::ProcessorId;
+
 /// 获取当前cpu的id
 #[inline]
-pub fn current_cpu_id() -> u32 {
+pub fn current_cpu_id() -> ProcessorId {
     unimplemented!("RiscV64 current_cpu_id")
 }
 

+ 9 - 6
kernel/src/arch/x86_64/acpi.rs

@@ -1,6 +1,6 @@
 use system_error::SystemError;
 
-use crate::{driver::acpi::acpi_manager, kinfo, mm::percpu::PerCpu};
+use crate::{driver::acpi::acpi_manager, kinfo, mm::percpu::PerCpu, smp::cpu::ProcessorId};
 
 use super::smp::SMP_BOOT_DATA;
 
@@ -11,16 +11,19 @@ pub(super) fn early_acpi_boot_init() -> Result<(), SystemError> {
     let processor_info = platform_info.processor_info.ok_or(SystemError::ENODEV)?;
 
     unsafe {
-        SMP_BOOT_DATA.set_phys_id(0, processor_info.boot_processor.local_apic_id as usize);
-        let mut cnt = 1;
+        SMP_BOOT_DATA.set_phys_id(
+            ProcessorId::new(0),
+            processor_info.boot_processor.local_apic_id as usize,
+        );
+        let mut cnt = ProcessorId::new(1);
         for ap in processor_info.application_processors.iter() {
-            if cnt >= PerCpu::MAX_CPU_NUM {
+            if cnt.data() >= PerCpu::MAX_CPU_NUM {
                 break;
             }
             SMP_BOOT_DATA.set_phys_id(cnt, ap.local_apic_id as usize);
-            cnt += 1;
+            cnt = ProcessorId::new(cnt.data() + 1);
         }
-        SMP_BOOT_DATA.set_cpu_count(cnt);
+        SMP_BOOT_DATA.set_cpu_count(cnt.data());
         SMP_BOOT_DATA.mark_initialized();
     }
     kinfo!(

+ 7 - 2
kernel/src/arch/x86_64/c_adapter.rs

@@ -1,6 +1,6 @@
-use crate::time::TimeArch;
+use crate::{sched::SchedArch, time::TimeArch};
 
-use super::{driver::tsc::TSCManager, syscall::init_syscall_64, CurrentTimeArch};
+use super::{driver::tsc::TSCManager, syscall::init_syscall_64, CurrentSchedArch, CurrentTimeArch};
 
 /// 获取当前的时间戳
 #[no_mangle]
@@ -18,3 +18,8 @@ unsafe extern "C" fn rs_tsc_get_cpu_khz() -> u64 {
 pub unsafe extern "C" fn rs_init_syscall_64() {
     init_syscall_64();
 }
+
+#[no_mangle]
+unsafe extern "C" fn rs_init_current_core_sched() {
+    CurrentSchedArch::initial_setup_sched_local();
+}

+ 5 - 3
kernel/src/arch/x86_64/cpu.rs

@@ -1,11 +1,13 @@
 use x86::cpuid::{cpuid, CpuIdResult};
 
-/// @brief 获取当前cpu的apic id
+use crate::smp::cpu::ProcessorId;
+
+/// 获取当前cpu的apic id
 #[inline]
-pub fn current_cpu_id() -> u32 {
+pub fn current_cpu_id() -> ProcessorId {
     let cpuid_res: CpuIdResult = cpuid!(0x1);
     let cpu_id = (cpuid_res.ebx >> 24) & 0xff;
-    return cpu_id;
+    return ProcessorId::new(cpu_id);
 }
 
 /// 重置cpu

+ 0 - 205
kernel/src/arch/x86_64/driver/apic/apic.c

@@ -1,205 +0,0 @@
-#include "apic.h"
-#include "apic_timer.h"
-#include <common/cpu.h>
-#include <common/glib.h>
-#include <common/kprint.h>
-#include <common/printk.h>
-#include <driver/acpi/acpi.h>
-#include <exception/softirq.h>
-#include <process/process.h>
-#include <sched/sched.h>
-
-#pragma GCC push_options
-#pragma GCC optimize("O0")
-// 导出定义在irq.c中的中段门表
-extern void (*interrupt_table[26])(void);
-extern uint32_t rs_current_pcb_preempt_count();
-extern uint32_t rs_current_pcb_pid();
-extern uint32_t rs_current_pcb_flags();
-extern void rs_apic_init_bsp();
-
-extern void rs_apic_local_apic_edge_ack(uint8_t irq_num);
-
-extern int rs_ioapic_install(uint8_t vector, uint8_t dest, bool level_triggered, bool active_high, bool dest_logical);
-extern void rs_ioapic_uninstall(uint8_t irq_num);
-extern void rs_ioapic_enable(uint8_t irq_num);
-extern void rs_ioapic_disable(uint8_t irq_num);
-
-/**
- * @brief 中断服务程序
- *
- * @param rsp 中断栈指针
- * @param number 中断向量号
- */
-void do_IRQ(struct pt_regs *rsp, ul number)
-{
-    
-    if ((rsp->cs & 0x3) == 3)
-    {
-        asm volatile("swapgs" ::: "memory");
-    }
-    if (number < 0x80 && number >= 32) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC
-    {
-        // ==========外部中断控制器========
-        irq_desc_t *irq = &interrupt_desc[number - 32];
-
-        // 执行中断上半部处理程序
-        if (irq != NULL && irq->handler != NULL)
-            irq->handler(number, irq->parameter, rsp);
-        else
-            kwarn("Intr vector [%d] does not have a handler!");
-        // 向中断控制器发送应答消息
-        // if (irq->controller != NULL && irq->controller->ack != NULL)
-        //     irq->controller->ack(number);
-        // else
-        //     rs_apic_local_apic_edge_ack(number);
-        rs_apic_local_apic_edge_ack(number);
-    }
-    else if (number >= 200)
-    {
-        rs_apic_local_apic_edge_ack(number);
-
-        {
-            irq_desc_t *irq = &SMP_IPI_desc[number - 200];
-            if (irq->handler != NULL)
-                irq->handler(number, irq->parameter, rsp);
-        }
-    }
-    else if (number >= 150 && number < 200)
-    {
-        irq_desc_t *irq = &local_apic_interrupt_desc[number - 150];
-
-        // 执行中断上半部处理程序
-        if (irq != NULL && irq->handler != NULL)
-            irq->handler(number, irq->parameter, rsp);
-        else
-            kwarn("Intr vector [%d] does not have a handler!");
-        // 向中断控制器发送应答消息
-        // if (irq->controller != NULL && irq->controller->ack != NULL)
-        //     irq->controller->ack(number);
-        // else
-        //     rs_apic_local_apic_edge_ack(number);
-        rs_apic_local_apic_edge_ack(number);
-    }
-    else
-    {
-
-        kwarn("do IRQ receive: %d", number);
-        // 忽略未知中断
-        return;
-    }
-
-    // kdebug("before softirq");
-    // 进入软中断处理程序
-    rs_do_softirq();
-
-    // kdebug("after softirq");
-    // 检测当前进程是否持有自旋锁,若持有自旋锁,则不进行抢占式的进程调度
-    if (rs_current_pcb_preempt_count() > 0)
-    {
-        return;
-    }
-    else if ((int32_t)rs_current_pcb_preempt_count() < 0)
-        kBUG("current_pcb->preempt_count<0! pid=%d", rs_current_pcb_pid()); // should not be here
-
-    // 检测当前进程是否可被调度
-    if ((rs_current_pcb_flags() & PF_NEED_SCHED) && number == APIC_TIMER_IRQ_NUM)
-    {
-        io_mfence();
-        sched();
-    }
-}
-
-// =========== 中断控制操作接口 ============
-void apic_ioapic_enable(ul irq_num)
-{
-    rs_ioapic_enable(irq_num);
-}
-
-void apic_ioapic_disable(ul irq_num)
-{
-    rs_ioapic_disable(irq_num);
-}
-
-ul apic_ioapic_install(ul irq_num, void *arg)
-{
-    struct apic_IO_APIC_RTE_entry *entry = (struct apic_IO_APIC_RTE_entry *)arg;
-    uint8_t dest = 0;
-    if (entry->dest_mode)
-    {
-        dest = entry->destination.logical.logical_dest;
-    }
-    else
-    {
-        dest = entry->destination.physical.phy_dest;
-    }
-
-    return rs_ioapic_install(entry->vector, dest, entry->trigger_mode, entry->polarity, entry->dest_mode);
-}
-
-void apic_ioapic_uninstall(ul irq_num)
-{
-    rs_ioapic_uninstall(irq_num);
-}
-
-void apic_ioapic_edge_ack(ul irq_num) // 边沿触发
-{
-
-    rs_apic_local_apic_edge_ack(irq_num);
-}
-
-/**
- * @brief local apic 边沿触发应答
- *
- * @param irq_num
- */
-
-void apic_local_apic_edge_ack(ul irq_num)
-{
-    rs_apic_local_apic_edge_ack(irq_num);
-}
-
-/**
- * @brief 构造RTE Entry结构体
- *
- * @param entry 返回的结构体
- * @param vector 中断向量
- * @param deliver_mode 投递模式
- * @param dest_mode 目标模式
- * @param deliver_status 投递状态
- * @param polarity 电平触发极性
- * @param irr 远程IRR标志位(只读)
- * @param trigger 触发模式
- * @param mask 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
- * @param dest_apicID 目标apicID
- */
-void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
-                         uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask,
-                         uint8_t dest_apicID)
-{
-
-    entry->vector = vector;
-    entry->deliver_mode = deliver_mode;
-    entry->dest_mode = dest_mode;
-    entry->deliver_status = deliver_status;
-    entry->polarity = polarity;
-    entry->remote_IRR = irr;
-    entry->trigger_mode = trigger;
-    entry->mask = mask;
-
-    entry->reserved = 0;
-
-    if (dest_mode == DEST_PHYSICAL)
-    {
-        entry->destination.physical.phy_dest = dest_apicID;
-        entry->destination.physical.reserved1 = 0;
-        entry->destination.physical.reserved2 = 0;
-    }
-    else
-    {
-        entry->destination.logical.logical_dest = dest_apicID;
-        entry->destination.logical.reserved1 = 0;
-    }
-}
-
-#pragma GCC pop_options

+ 0 - 284
kernel/src/arch/x86_64/driver/apic/apic.h

@@ -1,284 +0,0 @@
-#pragma once
-
-#include <common/asm.h>
-#include <process/ptrace.h>
-#include <exception/irq.h>
-#include <mm/mm.h>
-#include <arch/arch.h>
-
-#pragma GCC push_options
-#pragma GCC optimize("O0")
-
-// 当前apic启用状态标志
-extern uint8_t __apic_enable_state;
-#define APIC_XAPIC_ENABLED 0
-#define APIC_X2APIC_ENABLED 1
-#define CURRENT_APIC_STATE (__apic_enable_state)
-
-// ======== local apic 寄存器虚拟地址偏移量表 =======
-// 0x00~0x10 Reserved.
-#define LOCAL_APIC_OFFSET_Local_APIC_ID 0x20
-#define LOCAL_APIC_OFFSET_Local_APIC_Version 0x30
-// 0x40~0x70 Reserved.
-#define LOCAL_APIC_OFFSET_Local_APIC_TPR 0x80
-#define LOCAL_APIC_OFFSET_Local_APIC_APR 0x90
-#define LOCAL_APIC_OFFSET_Local_APIC_PPR 0xa0
-#define LOCAL_APIC_OFFSET_Local_APIC_EOI 0xb0
-#define LOCAL_APIC_OFFSET_Local_APIC_RRD 0xc0
-#define LOCAL_APIC_OFFSET_Local_APIC_LDR 0xd0
-#define LOCAL_APIC_OFFSET_Local_APIC_DFR 0xe0
-#define LOCAL_APIC_OFFSET_Local_APIC_SVR 0xf0
-
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_31_0 0x100
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_63_32 0x110
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_95_64 0x120
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_127_96 0x130
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_159_128 0x140
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_191_160 0x150
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_223_192 0x160
-#define LOCAL_APIC_OFFSET_Local_APIC_ISR_255_224 0x170
-
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_31_0 0x180
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_63_32 0x190
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_95_64 0x1a0
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_127_96 0x1b0
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_159_128 0x1c0
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_191_160 0x1d0
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_223_192 0x1e0
-#define LOCAL_APIC_OFFSET_Local_APIC_TMR_255_224 0x1f0
-
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_31_0 0x200
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_63_32 0x210
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_95_64 0x220
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_127_96 0x230
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_159_128 0x240
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_191_160 0x250
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_223_192 0x260
-#define LOCAL_APIC_OFFSET_Local_APIC_IRR_255_224 0x270
-
-#define LOCAL_APIC_OFFSET_Local_APIC_ESR 0x280
-
-// 0x290~0x2e0 Reserved.
-
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI 0x2f0
-#define LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0 0x300
-#define LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32 0x310
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER 0x320
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL 0x330
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR 0x340
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0 0x350
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1 0x360
-#define LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR 0x370
-// 初始计数寄存器(定时器专用)
-#define LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG 0x380
-// 当前计数寄存器(定时器专用)
-#define LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG 0x390
-// 0x3A0~0x3D0 Reserved.
-// 分频配置寄存器(定时器专用)
-#define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0
-
-uint32_t RCBA_vaddr = 0; // RCBA寄存器的虚拟地址
-
-/*
-
-1:	LVT	CMCI
-2:	LVT	Timer
-3:	LVT	Thermal Monitor
-4:	LVT	Performace Counter
-5:	LVT	LINT0
-6:	LVT	LINT1
-7:	LVT	Error
-
-*/
-/**
- * LVT表项
- * */
-struct apic_LVT
-{
-    uint vector : 8,         // 0-7位全部置为1
-        delivery_mode : 3,   // 第[10:8]位置为100, 表示NMI
-        reserved_1 : 1,      // 第11位保留
-        delivery_status : 1, // 第12位,投递状态 -> 发送挂起
-        polarity : 1,        // 第13位,电平触发极性 存在于LINT0,LINT1
-        remote_IRR : 1,      // 第14位,远程IRR标志位(只读) 存在于LINT0,LINT1
-        trigger_mode : 1,    // 第15位,触发模式(0位边沿触发,1为电平触发) 存在于LINT0,LINT1
-        mask : 1,            // 第16位,屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
-        timer_mode : 2,      // 第[18:17]位,定时模式。(00:一次性定时,   01:周期性定时,  10:指定TSC值计数), 存在于定时器寄存器
-        reserved_2 : 13;     // [31:19]位保留
-
-} __attribute((packed)); // 取消结构体的align
-
-/**
- * @brief I/O APIC 的中断定向寄存器的结构体
- *
- */
-struct apic_IO_APIC_RTE_entry
-{
-    unsigned int vector : 8, // 0~7
-        deliver_mode : 3,    // [10:8] 投递模式默认为NMI
-        dest_mode : 1,       // 11 目标模式(0位物理模式,1为逻辑模式)
-        deliver_status : 1,  // 12 投递状态
-        polarity : 1,        // 13 电平触发极性
-        remote_IRR : 1,      // 14 远程IRR标志位(只读)
-        trigger_mode : 1,    // 15 触发模式(0位边沿触发,1为电平触发)
-        mask : 1,            // 16 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
-        reserved : 15;       // [31:17]位保留
-
-    union
-    {
-        // 物理模式
-        struct
-        {
-            unsigned int reserved1 : 24, // [55:32] 保留
-                phy_dest : 4,            // [59:56] APIC ID
-                reserved2 : 4;           // [63:60] 保留
-        } physical;
-
-        // 逻辑模式
-        struct
-        {
-            unsigned int reserved1 : 24, // [55:32] 保留
-                logical_dest : 8;        // [63:56] 自定义APIC ID
-        } logical;
-    } destination;
-} __attribute__((packed));
-
-// ========== APIC的寄存器的参数定义 ==============
-// 投递模式
-#define LOCAL_APIC_FIXED 0
-#define IO_APIC_FIXED 0
-#define ICR_APIC_FIXED 0
-
-#define IO_APIC_Lowest_Priority 1
-#define ICR_Lowest_Priority 1
-
-#define LOCAL_APIC_SMI 2
-#define APIC_SMI 2
-#define ICR_SMI 2
-
-#define LOCAL_APIC_NMI 4
-#define APIC_NMI 4
-#define ICR_NMI 4
-
-#define LOCAL_APIC_INIT 5
-#define APIC_INIT 5
-#define ICR_INIT 5
-
-#define ICR_Start_up 6
-
-#define IO_APIC_ExtINT 7
-
-// 时钟模式
-#define APIC_LVT_Timer_One_Shot 0
-#define APIC_LVT_Timer_Periodic 1
-#define APIC_LVT_Timer_TSC_Deadline 2
-
-// 屏蔽
-#define UNMASKED 0
-#define MASKED 1
-#define APIC_LVT_INT_MASKED 0x10000UL
-
-// 触发模式
-#define EDGE_TRIGGER 0  // 边沿触发
-#define Level_TRIGGER 1 // 电平触发
-
-// 投递模式
-#define IDLE 0         // 挂起
-#define SEND_PENDING 1 // 发送等待
-
-// destination shorthand
-#define ICR_No_Shorthand 0
-#define ICR_Self 1
-#define ICR_ALL_INCLUDE_Self 2
-#define ICR_ALL_EXCLUDE_Self 3
-
-// 投递目标模式
-#define DEST_PHYSICAL 0 // 物理模式
-#define DEST_LOGIC 1    // 逻辑模式
-
-// level
-#define ICR_LEVEL_DE_ASSERT 0
-#define ICR_LEVEL_ASSERT 1
-
-// 远程IRR标志位, 在处理Local APIC标志位时置位,在收到处理器发来的EOI命令时复位
-#define IRR_RESET 0
-#define IRR_ACCEPT 1
-
-// 电平触发极性
-#define POLARITY_HIGH 0
-#define POLARITY_LOW 1
-
-/**
- * @brief 中断服务程序
- *
- * @param rsp 中断栈指针
- * @param number 中断向量号
- */
-void do_IRQ(struct pt_regs *rsp, ul number);
-void rs_apic_init_ap();
-
-#if ARCH(I386) || ARCH(X86_64)
-
-// =========== 中断控制操作接口 ============
-void apic_ioapic_enable(ul irq_num);
-void apic_ioapic_disable(ul irq_num);
-ul apic_ioapic_install(ul irq_num, void *arg);
-void apic_ioapic_uninstall(ul irq_num);
-void apic_ioapic_edge_ack(ul irq_num); // ioapic边沿触发 应答
-
-// void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答
-void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答
-#else
-void apic_ioapic_enable(ul irq_num)
-{
-    while (1)
-        ;
-}
-void apic_ioapic_disable(ul irq_num)
-{
-    while (1)
-        ;
-}
-ul apic_ioapic_install(ul irq_num, void *arg)
-{
-    while (1)
-        ;
-}
-void apic_ioapic_uninstall(ul irq_num)
-{
-    while (1)
-        ;
-}
-void apic_ioapic_edge_ack(ul irq_num)
-{
-    while (1)
-        ;
-} // ioapic边沿触发 应答
-
-// void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答
-void apic_local_apic_edge_ack(ul irq_num)
-{
-    while (1)
-        ;
-} // local apic边沿触发 应答
-
-#endif
-
-/**
- * @brief 构造RTE Entry结构体
- *
- * @param entry 返回的结构体
- * @param vector 中断向量
- * @param deliver_mode 投递模式
- * @param dest_mode 目标模式
- * @param deliver_status 投递状态
- * @param polarity 电平触发极性
- * @param irr 远程IRR标志位(只读)
- * @param trigger 触发模式
- * @param mask 屏蔽标志位,(0为未屏蔽, 1为已屏蔽)
- * @param dest_apicID 目标apicID
- */
-void apic_make_rte_entry(struct apic_IO_APIC_RTE_entry *entry, uint8_t vector, uint8_t deliver_mode, uint8_t dest_mode,
-                         uint8_t deliver_status, uint8_t polarity, uint8_t irr, uint8_t trigger, uint8_t mask, uint8_t dest_apicID);
-
-#pragma GCC pop_options

+ 0 - 96
kernel/src/arch/x86_64/driver/apic/apic_timer.c

@@ -1,96 +0,0 @@
-#include "apic_timer.h"
-#include <common/kprint.h>
-#include <exception/irq.h>
-#include <process/process.h>
-#include <sched/sched.h>
-
-
-// bsp 是否已经完成apic时钟初始化
-static bool bsp_initialized = false;
-
-extern void rs_apic_timer_install(int irq_num);
-extern void rs_apic_timer_uninstall(int irq_num);
-extern void rs_apic_timer_enable(int irq_num);
-extern void rs_apic_timer_disable(int irq_num);
-extern int rs_apic_timer_handle_irq();
-
-/**
- * @brief 初始化AP核的apic时钟
- *
- */
-void apic_timer_ap_core_init()
-{
-    while (!bsp_initialized)
-    {
-        pause();
-    }
-
-    apic_timer_init();
-}
-
-void apic_timer_enable(uint64_t irq_num)
-{
-    rs_apic_timer_enable(irq_num);
-}
-
-void apic_timer_disable(uint64_t irq_num)
-{
-    rs_apic_timer_disable(irq_num);
-}
-
-/**
- * @brief 安装local apic定时器中断
- *
- * @param irq_num 中断向量号
- * @param arg 初始计数值
- * @return uint64_t
- */
-uint64_t apic_timer_install(ul irq_num, void *arg)
-{
-
-    rs_apic_timer_install(irq_num);
-    return 0;
-}
-
-void apic_timer_uninstall(ul irq_num)
-{
-    rs_apic_timer_uninstall(irq_num);
-}
-
-hardware_intr_controller apic_timer_intr_controller = {
-    .enable = apic_timer_enable,
-    .disable = apic_timer_disable,
-    .install = apic_timer_install,
-    .uninstall = apic_timer_uninstall,
-    .ack = apic_local_apic_edge_ack,
-};
-
-/**
- * @brief local apic定时器的中断处理函数
- *
- * @param number 中断向量号
- * @param param 参数
- * @param regs 寄存器值
- */
-void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
-{
-    rs_apic_timer_handle_irq();
-}
-
-/**
- * @brief 初始化local APIC定时器
- *
- */
-void apic_timer_init()
-{
-    kinfo("Initializing apic timer for cpu %d", rs_current_pcb_cpuid());
-    io_mfence();
-    irq_register(APIC_TIMER_IRQ_NUM, NULL, &apic_timer_handler, 0, &apic_timer_intr_controller,
-                 "apic timer");
-    io_mfence();
-    if (rs_current_pcb_cpuid() == 0)
-    {
-        bsp_initialized = true;
-    }
-    kdebug("apic timer init done for cpu %d", rs_current_pcb_cpuid());
-}

+ 0 - 14
kernel/src/arch/x86_64/driver/apic/apic_timer.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <common/unistd.h>
-#include "apic.h"
-
-#define APIC_TIMER_IRQ_NUM 151
-
-/**
- * @brief 初始化local APIC定时器
- *
- */
-void apic_timer_init();
-
-void apic_timer_ap_core_init();

+ 89 - 15
kernel/src/arch/x86_64/driver/apic/apic_timer.rs

@@ -1,42 +1,111 @@
 use core::cell::RefCell;
 
 use crate::arch::driver::tsc::TSCManager;
-use crate::include::bindings::bindings::APIC_TIMER_IRQ_NUM;
+use crate::arch::interrupt::TrapFrame;
+use crate::driver::base::device::DeviceId;
+use crate::exception::irqdata::{IrqHandlerData, IrqLineStatus};
+use crate::exception::irqdesc::{
+    irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandleFlags, IrqHandler, IrqReturn,
+};
+use crate::exception::manage::irq_manager;
+use crate::exception::IrqNumber;
 
 use crate::kdebug;
 use crate::mm::percpu::PerCpu;
 use crate::sched::core::sched_update_jiffies;
 use crate::smp::core::smp_get_processor_id;
+use crate::smp::cpu::ProcessorId;
 use crate::time::clocksource::HZ;
+use alloc::string::ToString;
+use alloc::sync::Arc;
 pub use drop;
 use system_error::SystemError;
 use x86::cpuid::cpuid;
 use x86::msr::{wrmsr, IA32_X2APIC_DIV_CONF, IA32_X2APIC_INIT_COUNT};
 
+use super::lapic_vector::local_apic_chip;
 use super::xapic::XApicOffset;
 use super::{CurrentApic, LVTRegister, LocalAPIC, LVT};
 
-static mut LOCAL_APIC_TIMERS: [RefCell<LocalApicTimer>; PerCpu::MAX_CPU_NUM] =
-    [const { RefCell::new(LocalApicTimer::new()) }; PerCpu::MAX_CPU_NUM];
+pub const APIC_TIMER_IRQ_NUM: IrqNumber = IrqNumber::new(151);
 
+static mut LOCAL_APIC_TIMERS: [RefCell<LocalApicTimer>; PerCpu::MAX_CPU_NUM as usize] =
+    [const { RefCell::new(LocalApicTimer::new()) }; PerCpu::MAX_CPU_NUM as usize];
+
+#[allow(dead_code)]
 #[inline(always)]
-pub(super) fn local_apic_timer_instance(cpu_id: u32) -> core::cell::Ref<'static, LocalApicTimer> {
-    unsafe { LOCAL_APIC_TIMERS[cpu_id as usize].borrow() }
+pub(super) fn local_apic_timer_instance(
+    cpu_id: ProcessorId,
+) -> core::cell::Ref<'static, LocalApicTimer> {
+    unsafe { LOCAL_APIC_TIMERS[cpu_id.data() as usize].borrow() }
 }
 
 #[inline(always)]
 pub(super) fn local_apic_timer_instance_mut(
-    cpu_id: u32,
+    cpu_id: ProcessorId,
 ) -> core::cell::RefMut<'static, LocalApicTimer> {
-    unsafe { LOCAL_APIC_TIMERS[cpu_id as usize].borrow_mut() }
+    unsafe { LOCAL_APIC_TIMERS[cpu_id.data() as usize].borrow_mut() }
+}
+
+#[derive(Debug)]
+struct LocalApicTimerHandler;
+
+impl IrqHandler for LocalApicTimerHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        // empty (只是为了让编译通过,不会被调用到。真正的处理函数在LocalApicTimerIrqFlowHandler中)
+        Ok(IrqReturn::NotHandled)
+    }
+}
+
+#[derive(Debug)]
+struct LocalApicTimerIrqFlowHandler;
+
+impl IrqFlowHandler for LocalApicTimerIrqFlowHandler {
+    fn handle(&self, _irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
+        LocalApicTimer::handle_irq().ok();
+        CurrentApic.send_eoi();
+    }
+}
+
+pub fn apic_timer_init() {
+    irq_manager()
+        .request_irq(
+            APIC_TIMER_IRQ_NUM,
+            "LocalApic".to_string(),
+            &LocalApicTimerHandler,
+            IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_PERCPU,
+            Some(DeviceId::new(Some("lapic timer"), None).unwrap()),
+        )
+        .expect("Apic timer init failed");
+
+    LocalApicTimerIntrController.install();
+    LocalApicTimerIntrController.enable();
+}
+
+/// 初始化本地APIC定时器的中断描述符
+#[inline(never)]
+pub(super) fn local_apic_timer_irq_desc_init() {
+    let desc = irq_desc_manager().lookup(APIC_TIMER_IRQ_NUM).unwrap();
+    let irq_data: Arc<crate::exception::irqdata::IrqData> = desc.irq_data();
+    let mut chip_info_guard = irq_data.chip_info_write_irqsave();
+    chip_info_guard.set_chip(Some(local_apic_chip().clone()));
+
+    desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
+    drop(chip_info_guard);
+    desc.set_handler(&LocalApicTimerIrqFlowHandler);
 }
 
 /// 初始化BSP的APIC定时器
 ///
 fn init_bsp_apic_timer() {
     kdebug!("init_bsp_apic_timer");
-    assert!(smp_get_processor_id() == 0);
-    let mut local_apic_timer = local_apic_timer_instance_mut(0);
+    assert!(smp_get_processor_id().data() == 0);
+    let mut local_apic_timer = local_apic_timer_instance_mut(ProcessorId::new(0));
     local_apic_timer.init(
         LocalApicTimerMode::Periodic,
         LocalApicTimer::periodic_default_initial_count(),
@@ -48,7 +117,7 @@ fn init_bsp_apic_timer() {
 fn init_ap_apic_timer() {
     kdebug!("init_ap_apic_timer");
     let cpu_id = smp_get_processor_id();
-    assert!(cpu_id != 0);
+    assert!(cpu_id.data() != 0);
 
     let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id);
     local_apic_timer.init(
@@ -62,15 +131,16 @@ fn init_ap_apic_timer() {
 pub(super) struct LocalApicTimerIntrController;
 
 impl LocalApicTimerIntrController {
-    pub(super) fn install(&self, _irq_num: u8) {
+    pub(super) fn install(&self) {
         kdebug!("LocalApicTimerIntrController::install");
-        if smp_get_processor_id() == 0 {
+        if smp_get_processor_id().data() == 0 {
             init_bsp_apic_timer();
         } else {
             init_ap_apic_timer();
         }
     }
 
+    #[allow(dead_code)]
     pub(super) fn uninstall(&self) {
         let cpu_id = smp_get_processor_id();
         let local_apic_timer = local_apic_timer_instance(cpu_id);
@@ -157,7 +227,11 @@ impl LocalApicTimer {
         self.mode = LocalApicTimerMode::Periodic;
         self.set_divisor(divisor);
         self.set_initial_cnt(initial_count);
-        self.setup_lvt(APIC_TIMER_IRQ_NUM as u8, true, LocalApicTimerMode::Periodic);
+        self.setup_lvt(
+            APIC_TIMER_IRQ_NUM.data() as u8,
+            true,
+            LocalApicTimerMode::Periodic,
+        );
     }
 
     fn setup_lvt(&mut self, vector: u8, mask: bool, mode: LocalApicTimerMode) {
@@ -200,9 +274,9 @@ impl LocalApicTimer {
         return (res.ecx & (1 << 24)) != 0;
     }
 
-    pub(super) fn handle_irq() -> Result<(), SystemError> {
+    pub(super) fn handle_irq() -> Result<IrqReturn, SystemError> {
         sched_update_jiffies();
-        return Ok(());
+        return Ok(IrqReturn::Handled);
     }
 }
 

+ 1 - 75
kernel/src/arch/x86_64/driver/apic/c_adapter.rs

@@ -1,43 +1,4 @@
-use super::{
-    apic_timer::{LocalApicTimer, LocalApicTimerIntrController},
-    ioapic::{ioapic_disable, ioapic_enable, ioapic_install, ioapic_uninstall},
-    CurrentApic, LocalAPIC,
-};
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_timer_install(irq_num: u8) {
-    LocalApicTimerIntrController.install(irq_num);
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_timer_uninstall(_irq_num: u8) {
-    LocalApicTimerIntrController.uninstall();
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_timer_enable(_irq_num: u8) {
-    LocalApicTimerIntrController.enable();
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_timer_disable(_irq_num: u8) {
-    LocalApicTimerIntrController.disable();
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_local_apic_edge_ack(_irq_num: u8) {
-    CurrentApic.send_eoi();
-}
-
-/// 初始化bsp处理器的apic
-#[no_mangle]
-pub extern "C" fn rs_apic_init_bsp() -> i32 {
-    if CurrentApic.init_current_cpu() {
-        return 0;
-    }
-
-    return -1;
-}
+use super::{CurrentApic, LocalAPIC};
 
 #[no_mangle]
 pub extern "C" fn rs_apic_init_ap() -> i32 {
@@ -47,38 +8,3 @@ pub extern "C" fn rs_apic_init_ap() -> i32 {
 
     return -1;
 }
-
-#[no_mangle]
-unsafe extern "C" fn rs_ioapic_install(
-    vector: u8,
-    dest: u8,
-    level_triggered: bool,
-    active_high: bool,
-    dest_logic: bool,
-) -> i32 {
-    return ioapic_install(vector, dest, level_triggered, active_high, dest_logic)
-        .map(|_| 0)
-        .unwrap_or_else(|e| e.to_posix_errno());
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_ioapic_uninstall(vector: u8) {
-    ioapic_uninstall(vector);
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_ioapic_enable(vector: u8) {
-    ioapic_enable(vector);
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_ioapic_disable(vector: u8) {
-    ioapic_disable(vector);
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_apic_timer_handle_irq(_irq_num: u8) -> i32 {
-    return LocalApicTimer::handle_irq()
-        .map(|_| 0)
-        .unwrap_or_else(|e| e.to_posix_errno());
-}

+ 9 - 0
kernel/src/arch/x86_64/driver/apic/hw_irq.rs

@@ -0,0 +1,9 @@
+use crate::{exception::HardwareIrqNumber, int_like};
+
+int_like!(ApicId, u32);
+
+#[derive(Debug)]
+pub(super) struct HardwareIrqConfig {
+    pub apic_id: ApicId,
+    pub vector: HardwareIrqNumber,
+}

+ 318 - 24
kernel/src/arch/x86_64/driver/apic/ioapic.rs

@@ -1,16 +1,26 @@
 use core::ptr::NonNull;
 
 use acpi::madt::Madt;
+use alloc::sync::Arc;
 use bit_field::BitField;
 use bitflags::bitflags;
 use system_error::SystemError;
 
 use crate::{
     driver::acpi::acpi_manager,
+    exception::{
+        handle::{edge_irq_handler, fast_eoi_irq_handler},
+        irqchip::{IrqChip, IrqChipData, IrqChipFlags, IrqChipSetMaskResult, IrqChipState},
+        irqdata::{IrqData, IrqLineStatus},
+        irqdesc::{irq_desc_manager, IrqDesc, IrqFlowHandler},
+        manage::irq_manager,
+        IrqNumber,
+    },
     kdebug, kinfo,
     libs::{
+        cpumask::CpuMask,
         once::Once,
-        spinlock::SpinLock,
+        spinlock::{SpinLock, SpinLockGuard},
         volatile::{volwrite, Volatile},
     },
     mm::{
@@ -22,12 +32,18 @@ use crate::{
 use super::{CurrentApic, LocalAPIC};
 
 static mut __IOAPIC: Option<SpinLock<IoApic>> = None;
+static mut IOAPIC_IR_CHIP: Option<Arc<IoApicChip>> = None;
 
 #[allow(non_snake_case)]
 fn IOAPIC() -> &'static SpinLock<IoApic> {
     unsafe { __IOAPIC.as_ref().unwrap() }
 }
 
+#[inline(always)]
+pub(super) fn ioapic_ir_chip() -> Arc<dyn IrqChip> {
+    unsafe { IOAPIC_IR_CHIP.as_ref().unwrap().clone() }
+}
+
 #[allow(dead_code)]
 pub struct IoApic {
     reg: *mut u32,
@@ -253,6 +269,12 @@ impl IoApic {
         unsafe { (self.read(REG_VER).get_bits(16..24) + 1) as u8 }
     }
 
+    pub fn pending(&mut self, irq: u8) -> bool {
+        let rte_index = Self::vector_rte_index(irq);
+        let data = unsafe { self.read(REG_TABLE + 2 * rte_index) };
+        data & (1 << 12) != 0
+    }
+
     fn vector_rte_index(irq_num: u8) -> u8 {
         assert!(irq_num >= Self::VECTOR_BASE);
         irq_num - Self::VECTOR_BASE
@@ -272,12 +294,6 @@ impl IoApic {
             volwrite!(p, virt_eoi, irq_num as u32);
         }
     }
-
-    /// 边沿响应
-    #[allow(dead_code)]
-    fn edge_ack(&mut self, _irq_num: u8) {
-        CurrentApic.send_eoi();
-    }
 }
 
 /// Register index: ID
@@ -307,15 +323,126 @@ bitflags! {
     }
 }
 
-pub fn ioapic_init() {
+#[derive(Debug)]
+struct IoApicChipData {
+    inner: SpinLock<InnerIoApicChipData>,
+}
+
+impl IrqChipData for IoApicChipData {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+}
+
+impl IoApicChipData {
+    const DEFAULT: Self = Self::new(0, 0, 0, false, false, false, true);
+
+    const fn new(
+        rte_index: u8,
+        vector: u8,
+        dest: u8,
+        level_triggered: bool,
+        active_high: bool,
+        dest_logic: bool,
+        mask: bool,
+    ) -> Self {
+        IoApicChipData {
+            inner: SpinLock::new(InnerIoApicChipData {
+                rte_index,
+                vector,
+                dest,
+                level_triggered,
+                active_high,
+                dest_logic,
+                mask,
+            }),
+        }
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerIoApicChipData> {
+        self.inner.lock_irqsave()
+    }
+}
+
+#[derive(Debug)]
+struct InnerIoApicChipData {
+    rte_index: u8,
+    vector: u8,
+    dest: u8,
+    level_triggered: bool,
+    active_high: bool,
+    dest_logic: bool,
+    mask: bool,
+}
+
+impl InnerIoApicChipData {
+    /// 把中断数据同步到芯片
+    fn sync_to_chip(&self) -> Result<(), SystemError> {
+        ioapic_install(
+            self.vector,
+            self.dest,
+            self.level_triggered,
+            self.active_high,
+            self.dest_logic,
+            self.mask,
+        )
+    }
+}
+
+#[inline(never)]
+pub fn ioapic_init(ignore: &'static [IrqNumber]) {
     kinfo!("Initializing ioapic...");
     let ioapic = unsafe { IoApic::new() };
     unsafe {
         __IOAPIC = Some(SpinLock::new(ioapic));
     }
+    unsafe {
+        IOAPIC_IR_CHIP = Some(Arc::new(IoApicChip));
+    }
+
+    // 绑定irqchip
+    for i in 32..256 {
+        let irq = IrqNumber::new(i);
+
+        if ignore.contains(&irq) {
+            continue;
+        }
+
+        let desc = irq_desc_manager().lookup(irq).unwrap();
+        let irq_data = desc.irq_data();
+        let mut chip_info_guard = irq_data.chip_info_write_irqsave();
+        chip_info_guard.set_chip(Some(ioapic_ir_chip()));
+        let chip_data = IoApicChipData::DEFAULT;
+        chip_data.inner().rte_index = IoApic::vector_rte_index(i as u8);
+        chip_data.inner().vector = i as u8;
+        chip_info_guard.set_chip_data(Some(Arc::new(chip_data)));
+        drop(chip_info_guard);
+        let level = irq_data.is_level_type();
+
+        register_handler(&desc, level);
+    }
+
     kinfo!("IO Apic initialized.");
 }
 
+fn register_handler(desc: &Arc<IrqDesc>, level_triggered: bool) {
+    let fasteoi: bool;
+    if level_triggered {
+        desc.modify_status(IrqLineStatus::empty(), IrqLineStatus::IRQ_LEVEL);
+        fasteoi = true;
+    } else {
+        desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
+        fasteoi = false;
+    }
+
+    let handler: &dyn IrqFlowHandler = if fasteoi {
+        fast_eoi_irq_handler()
+    } else {
+        edge_irq_handler()
+    };
+    desc.set_handler(handler);
+}
+
 /// 安装中断
 ///
 /// ## 参数
@@ -326,12 +453,13 @@ pub fn ioapic_init() {
 /// * `active_high` - 是否为高电平有效
 /// * `dest_logic` - 是否为逻辑模式
 /// * `mask` - 是否屏蔽
-pub(super) fn ioapic_install(
+fn ioapic_install(
     vector: u8,
     dest: u8,
     level_triggered: bool,
     active_high: bool,
     dest_logic: bool,
+    mask: bool,
 ) -> Result<(), SystemError> {
     let rte_index = IoApic::vector_rte_index(vector);
     return IOAPIC().lock_irqsave().install(
@@ -341,24 +469,190 @@ pub(super) fn ioapic_install(
         level_triggered,
         active_high,
         dest_logic,
-        true,
+        mask,
     );
 }
 
-/// 卸载中断
-pub(super) fn ioapic_uninstall(vector: u8) {
-    let rte_index = IoApic::vector_rte_index(vector);
-    IOAPIC().lock_irqsave().disable(rte_index);
-}
+/// IoApic中断芯片
+///
+/// https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/io_apic.c#1994
+#[derive(Debug)]
+struct IoApicChip;
 
-/// 使能中断
-pub(super) fn ioapic_enable(vector: u8) {
-    let rte_index = IoApic::vector_rte_index(vector);
-    IOAPIC().lock_irqsave().enable(rte_index);
-}
+impl IrqChip for IoApicChip {
+    fn name(&self) -> &'static str {
+        "IR-IO-APIC"
+    }
 
-/// 禁用中断
-pub(super) fn ioapic_disable(vector: u8) {
-    let rte_index = IoApic::vector_rte_index(vector);
-    IOAPIC().lock_irqsave().disable(rte_index);
+    fn irq_startup(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        self.irq_unmask(irq)
+    }
+
+    fn irq_mask(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        let binding = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)?;
+        let chip_data = binding
+            .as_any_ref()
+            .downcast_ref::<IoApicChipData>()
+            .ok_or(SystemError::EINVAL)?;
+
+        let mut chip_data_inner = chip_data.inner();
+        chip_data_inner.mask = true;
+        chip_data_inner.sync_to_chip().ok();
+
+        drop(chip_data_inner);
+
+        return Ok(());
+    }
+
+    fn can_set_affinity(&self) -> bool {
+        true
+    }
+
+    fn can_set_flow_type(&self) -> bool {
+        true
+    }
+
+    fn irq_set_type(
+        &self,
+        irq: &Arc<IrqData>,
+        flow_type: IrqLineStatus,
+    ) -> Result<IrqChipSetMaskResult, SystemError> {
+        let binding = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)?;
+        let chip_data = binding
+            .as_any_ref()
+            .downcast_ref::<IoApicChipData>()
+            .ok_or(SystemError::EINVAL)?;
+        let mut chip_data_inner = chip_data.inner();
+
+        let level_triggered = flow_type.is_level_type();
+        let active_high = flow_type.is_level_high().unwrap_or(false);
+        chip_data_inner.active_high = active_high;
+        chip_data_inner.level_triggered = level_triggered;
+        chip_data_inner.sync_to_chip()?;
+
+        return Ok(IrqChipSetMaskResult::SetMaskOk);
+    }
+
+    fn irq_set_affinity(
+        &self,
+        irq: &Arc<IrqData>,
+        cpu: &CpuMask,
+        _force: bool,
+    ) -> Result<IrqChipSetMaskResult, SystemError> {
+        // 使用mask的第1个可用CPU
+        let dest = (cpu.first().ok_or(SystemError::EINVAL)?.data() & 0xff) as u8;
+
+        let binding = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)?;
+        let chip_data = binding
+            .as_any_ref()
+            .downcast_ref::<IoApicChipData>()
+            .ok_or(SystemError::EINVAL)?;
+
+        let mut chip_data_inner = chip_data.inner();
+        let origin_dest = chip_data_inner.dest;
+        if origin_dest == dest {
+            return Ok(IrqChipSetMaskResult::SetMaskOk);
+        }
+
+        chip_data_inner.dest = dest;
+
+        chip_data_inner.sync_to_chip()?;
+
+        return Ok(IrqChipSetMaskResult::SetMaskOk);
+    }
+
+    fn irq_unmask(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        IOAPIC()
+            .lock_irqsave()
+            .enable(IoApic::vector_rte_index(irq.irq().data() as u8));
+        Ok(())
+    }
+
+    fn can_mask_ack(&self) -> bool {
+        true
+    }
+
+    fn irq_mask_ack(&self, irq: &Arc<IrqData>) {
+        self.irq_mask(irq).ok();
+        self.irq_eoi(irq);
+    }
+
+    fn irq_eoi(&self, irq: &Arc<IrqData>) {
+        if irq.is_level_type() {
+            IOAPIC().lock_irqsave().level_ack(irq.irq().data() as u8);
+        } else {
+            CurrentApic.send_eoi();
+        }
+    }
+
+    fn retrigger(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
+        irq_manager().irq_chip_retrigger_hierarchy(irq_data)
+    }
+
+    fn irqchip_state(&self, irq: &Arc<IrqData>, which: IrqChipState) -> Result<bool, SystemError> {
+        let binding = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)?;
+        let chip_data = binding
+            .as_any_ref()
+            .downcast_ref::<IoApicChipData>()
+            .ok_or(SystemError::EINVAL)?;
+
+        match which {
+            IrqChipState::Pending => {
+                return Ok(IOAPIC().lock_irqsave().pending(irq.irq().data() as u8));
+            }
+            IrqChipState::Active => {
+                let chip_data_inner = chip_data.inner();
+                return Ok(!chip_data_inner.mask);
+            }
+            IrqChipState::Masked => {
+                let chip_data_inner = chip_data.inner();
+                return Ok(chip_data_inner.mask);
+            }
+            IrqChipState::LineLevel => {
+                let chip_data_inner = chip_data.inner();
+                return Ok(chip_data_inner.active_high);
+            }
+            #[allow(unreachable_patterns)]
+            _ => {
+                return Err(SystemError::EINVAL);
+            }
+        }
+    }
+
+    fn irq_disable(&self, irq: &Arc<IrqData>) {
+        let binding = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)
+            .unwrap();
+        let chip_data = binding
+            .as_any_ref()
+            .downcast_ref::<IoApicChipData>()
+            .ok_or(SystemError::EINVAL)
+            .unwrap();
+        let mut chip_data_inner = chip_data.inner();
+        chip_data_inner.mask = true;
+        chip_data_inner.sync_to_chip().ok();
+    }
+
+    fn irq_ack(&self, irq_data: &Arc<IrqData>) {
+        // irq_manager().irq_chip_ack_parent(irq_data);
+        self.irq_eoi(irq_data);
+    }
+
+    fn flags(&self) -> IrqChipFlags {
+        IrqChipFlags::IRQCHIP_SKIP_SET_WAKE | IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP
+    }
 }

+ 289 - 0
kernel/src/arch/x86_64/driver/apic/lapic_vector.rs

@@ -0,0 +1,289 @@
+use core::intrinsics::unlikely;
+
+use alloc::{string::ToString, sync::Arc};
+use intertrait::CastFrom;
+use system_error::SystemError;
+
+use crate::{
+    arch::{
+        driver::apic::{
+            apic_timer::{local_apic_timer_irq_desc_init, APIC_TIMER_IRQ_NUM},
+            ioapic::ioapic_init,
+        },
+        interrupt::{
+            entry::arch_setup_interrupt_gate,
+            ipi::{arch_ipi_handler_init, send_ipi, IPI_NUM_FLUSH_TLB, IPI_NUM_KICK_CPU},
+            msi::{X86MsiAddrHi, X86MsiAddrLoNormal, X86MsiDataNormal, X86_MSI_BASE_ADDRESS_LOW},
+        },
+    },
+    driver::open_firmware::device_node::DeviceNode,
+    exception::{
+        ipi::{IpiKind, IpiTarget},
+        irqchip::{IrqChip, IrqChipData, IrqChipFlags},
+        irqdata::IrqData,
+        irqdomain::{irq_domain_manager, IrqDomain, IrqDomainBusToken, IrqDomainOps},
+        msi::MsiMsg,
+        HardwareIrqNumber, IrqNumber,
+    },
+    kwarn,
+    libs::spinlock::{SpinLock, SpinLockGuard},
+    smp::{core::smp_get_processor_id, cpu::ProcessorId},
+};
+
+use super::{hw_irq::HardwareIrqConfig, CurrentApic, LocalAPIC};
+
+static mut LOCAL_APIC_CHIP: Option<Arc<LocalApicChip>> = None;
+
+pub fn local_apic_chip() -> &'static Arc<LocalApicChip> {
+    unsafe { LOCAL_APIC_CHIP.as_ref().unwrap() }
+}
+
+#[derive(Debug)]
+pub struct LocalApicChip {
+    inner: SpinLock<InnerIrqChip>,
+}
+
+impl LocalApicChip {
+    pub fn new() -> Self {
+        Self {
+            inner: SpinLock::new(InnerIrqChip {
+                flags: IrqChipFlags::empty(),
+            }),
+        }
+    }
+}
+
+impl IrqChip for LocalApicChip {
+    fn name(&self) -> &'static str {
+        "APIC"
+    }
+
+    fn can_set_flow_type(&self) -> bool {
+        false
+    }
+
+    fn irq_disable(&self, _irq: &Arc<IrqData>) {}
+
+    fn irq_ack(&self, _irq: &Arc<IrqData>) {
+        CurrentApic.send_eoi();
+    }
+
+    fn can_set_affinity(&self) -> bool {
+        false
+    }
+
+    fn can_mask_ack(&self) -> bool {
+        false
+    }
+
+    fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        // 这里临时处理,后续需要修改
+        return Ok(());
+    }
+
+    fn irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        Ok(())
+    }
+
+    fn irq_compose_msi_msg(&self, irq: &Arc<IrqData>, msg: &mut MsiMsg) {
+        let chip_data = irq.chip_info_read_irqsave().chip_data().unwrap();
+        let apicd = chip_data.ref_any().downcast_ref::<ApicChipData>().unwrap();
+        let cfg = &apicd.inner().hw_irq_cfg;
+        irq_msi_compose_msg(cfg, msg, false);
+    }
+
+    fn retrigger(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        let chip_data = irq
+            .chip_info_read_irqsave()
+            .chip_data()
+            .ok_or(SystemError::EINVAL)?;
+        let apicd = chip_data
+            .ref_any()
+            .downcast_ref::<ApicChipData>()
+            .ok_or(SystemError::EINVAL)?;
+        let inner = apicd.inner();
+
+        send_ipi(
+            IpiKind::SpecVector(inner.vector),
+            IpiTarget::Specified(inner.cpu),
+        );
+
+        Ok(())
+    }
+
+    fn flags(&self) -> IrqChipFlags {
+        self.inner.lock_irqsave().flags
+    }
+}
+
+#[derive(Debug)]
+struct InnerIrqChip {
+    flags: IrqChipFlags,
+}
+
+#[derive(Debug)]
+struct ApicChipData {
+    inner: SpinLock<InnerApicChipData>,
+}
+
+impl ApicChipData {
+    #[allow(dead_code)]
+    pub fn new(
+        hw_irq_cfg: HardwareIrqConfig,
+        irq: IrqNumber,
+        vector: HardwareIrqNumber,
+        cpu: ProcessorId,
+    ) -> Self {
+        Self {
+            inner: SpinLock::new(InnerApicChipData {
+                hw_irq_cfg,
+                irq,
+                vector,
+                prev_vector: None,
+                cpu,
+                prev_cpu: None,
+                status: ApicChipStatus::empty(),
+            }),
+        }
+    }
+
+    pub fn inner(&self) -> SpinLockGuard<InnerApicChipData> {
+        self.inner.lock_irqsave()
+    }
+}
+
+#[allow(dead_code)]
+#[derive(Debug)]
+struct InnerApicChipData {
+    hw_irq_cfg: HardwareIrqConfig,
+    irq: IrqNumber,
+    vector: HardwareIrqNumber,
+    prev_vector: Option<HardwareIrqNumber>,
+    cpu: ProcessorId,
+    prev_cpu: Option<ProcessorId>,
+    status: ApicChipStatus,
+}
+
+impl IrqChipData for ApicChipData {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+}
+
+bitflags! {
+    pub struct ApicChipStatus: u32 {
+        const MOVE_IN_PROGRESS = 1 << 0;
+        const IS_MANAGED = 1 << 1;
+        const CAN_RESERVE = 1 << 2;
+        const HAS_RESERVED = 1 << 3;
+    }
+}
+
+pub(super) fn irq_msi_compose_msg(cfg: &HardwareIrqConfig, msg: &mut MsiMsg, dmar: bool) {
+    *msg = MsiMsg::new_zeroed();
+
+    let arch_data = X86MsiDataNormal::new()
+        .with_delivery_mode(x86::apic::DeliveryMode::Fixed as u8)
+        .with_vector((cfg.vector.data() & 0xff) as u8);
+    let mut address_lo = X86MsiAddrLoNormal::new()
+        .with_base_address(X86_MSI_BASE_ADDRESS_LOW)
+        .with_dest_mode_logical(false)
+        .with_destid_0_7(cfg.apic_id.data() & 0xff);
+
+    let mut address_hi = X86MsiAddrHi::new();
+
+    /*
+     * 只有IOMMU本身可以使用将目标APIC ID放入地址的高位的技术。
+     * 任何其他尝试这样做的东西都只是在写内存,并且需要IR来
+     * 寻址不能在正常的32位地址范围内0xFFExxxxx寻址的APIC。
+     * 这通常是8位,但一些虚拟化程序允许在位5-11使用扩展的目的地ID字段,
+     * 总共支持15位的APIC ID。
+     */
+    if dmar {
+        address_hi.set_destid_8_31(cfg.apic_id.data() >> 8);
+    } else if cfg.apic_id.data() < 0x8000 {
+        // todo: 判断vmx是否支持 extended destination mode
+        // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/apic.c?fi=__irq_msi_compose_msg#2580
+        address_lo.set_virt_destid_8_14(cfg.apic_id.data() >> 8);
+    } else {
+        if unlikely(cfg.apic_id.data() > 0xff) {
+            kwarn!(
+                "irq_msi_compose_msg: Invalid APIC ID: {}",
+                cfg.apic_id.data()
+            );
+        }
+    }
+    msg.address_hi = address_hi.into();
+    msg.address_lo = address_lo.into();
+    msg.data = arch_data.into();
+}
+
+static mut X86_VECTOR_DOMAIN: Option<Arc<IrqDomain>> = None;
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn x86_vector_domain() -> &'static Arc<IrqDomain> {
+    unsafe { X86_VECTOR_DOMAIN.as_ref().unwrap() }
+}
+
+#[inline(never)]
+pub fn arch_early_irq_init() -> Result<(), SystemError> {
+    let vec_domain = irq_domain_manager()
+        .create_and_add(
+            "VECTOR".to_string(),
+            &X86VectorDomainOps,
+            IrqNumber::new(32),
+            HardwareIrqNumber::new(32),
+            223,
+        )
+        .ok_or(SystemError::ENOMEM)?;
+    irq_domain_manager().set_default_domain(vec_domain.clone());
+    unsafe { X86_VECTOR_DOMAIN = Some(vec_domain) };
+
+    let apic_chip = Arc::new(LocalApicChip::new());
+
+    unsafe { LOCAL_APIC_CHIP = Some(apic_chip) };
+
+    // todo: add vector matrix
+    // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#803
+    kwarn!("arch_early_irq_init: todo: add vector matrix");
+
+    local_apic_timer_irq_desc_init();
+    arch_ipi_handler_init();
+    CurrentApic.init_current_cpu();
+    if smp_get_processor_id().data() == 0 {
+        unsafe { arch_setup_interrupt_gate() };
+        ioapic_init(&[APIC_TIMER_IRQ_NUM, IPI_NUM_KICK_CPU, IPI_NUM_FLUSH_TLB]);
+    }
+    return Ok(());
+}
+
+/// x86的中断域操作
+///
+/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#693
+#[derive(Debug)]
+struct X86VectorDomainOps;
+
+impl IrqDomainOps for X86VectorDomainOps {
+    fn match_node(
+        &self,
+        _irq_domain: &Arc<IrqDomain>,
+        _device_node: &Arc<DeviceNode>,
+        _bus_token: IrqDomainBusToken,
+    ) -> bool {
+        todo!()
+    }
+
+    fn map(
+        &self,
+        _irq_domain: &Arc<IrqDomain>,
+        _hwirq: HardwareIrqNumber,
+        _virq: IrqNumber,
+    ) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
+
+    fn unmap(&self, _irq_domain: &Arc<IrqDomain>, _virq: IrqNumber) {
+        todo!()
+    }
+}

+ 13 - 13
kernel/src/arch/x86_64/driver/apic/mod.rs

@@ -6,7 +6,7 @@ use x86::{apic::Icr, msr::IA32_APIC_BASE};
 
 use crate::{
     arch::{
-        driver::apic::{ioapic::ioapic_init, x2apic::X2Apic, xapic::XApic},
+        driver::apic::{hw_irq::ApicId, x2apic::X2Apic, xapic::XApic},
         io::PortIOArch,
         CurrentPortIOArch,
     },
@@ -22,7 +22,9 @@ use self::{
 
 pub mod apic_timer;
 mod c_adapter;
+pub mod hw_irq;
 pub mod ioapic;
+pub mod lapic_vector;
 pub mod x2apic;
 pub mod xapic;
 
@@ -63,7 +65,7 @@ pub trait LocalAPIC {
     fn max_lvt_entry(&self) -> u8;
 
     /// @brief 获取当前处理器的APIC ID
-    fn id(&self) -> u32;
+    fn id(&self) -> ApicId;
 
     /// @brief 设置LVT寄存器
     ///
@@ -481,20 +483,20 @@ impl LocalAPIC for CurrentApic {
 
     fn init_current_cpu(&mut self) -> bool {
         let cpu_id = smp_get_processor_id();
-        if cpu_id == 0 {
+        if cpu_id.data() == 0 {
             unsafe {
                 self.mask8259a();
             }
         }
-        kinfo!("Initializing apic for cpu {}", cpu_id);
+        kinfo!("Initializing apic for cpu {:?}", cpu_id);
         if X2Apic::support() && X2Apic.init_current_cpu() {
-            if cpu_id == 0 {
+            if cpu_id.data() == 0 {
                 LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::X2Apic, Ordering::SeqCst);
             }
-            kinfo!("x2APIC initialized for cpu {}", cpu_id);
+            kinfo!("x2APIC initialized for cpu {:?}", cpu_id);
         } else {
             kinfo!("x2APIC not supported or failed to initialize, fallback to xAPIC.");
-            if cpu_id == 0 {
+            if cpu_id.data() == 0 {
                 LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::XApic, Ordering::SeqCst);
             }
             let apic_base =
@@ -512,11 +514,9 @@ impl LocalAPIC for CurrentApic {
                 xapic.init_current_cpu();
             }
 
-            kinfo!("xAPIC initialized for cpu {}", cpu_id);
-        }
-        if cpu_id == 0 {
-            ioapic_init();
+            kinfo!("xAPIC initialized for cpu {:?}", cpu_id);
         }
+
         kinfo!("Apic initialized.");
         return true;
     }
@@ -567,7 +567,7 @@ impl LocalAPIC for CurrentApic {
         }
     }
 
-    fn id(&self) -> u32 {
+    fn id(&self) -> ApicId {
         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
             return X2Apic.id();
         } else {
@@ -575,7 +575,7 @@ impl LocalAPIC for CurrentApic {
                 .borrow()
                 .as_ref()
                 .map(|xapic| xapic.id())
-                .unwrap_or(0);
+                .unwrap_or(ApicId::new(0));
         }
     }
 

+ 3 - 3
kernel/src/arch/x86_64/driver/apic/x2apic.rs

@@ -5,7 +5,7 @@ use x86::msr::{
 
 use crate::{kdebug, kinfo};
 
-use super::{LVTRegister, LocalAPIC, LVT};
+use super::{hw_irq::ApicId, LVTRegister, LocalAPIC, LVT};
 
 #[derive(Debug)]
 pub struct X2Apic;
@@ -84,8 +84,8 @@ impl LocalAPIC for X2Apic {
     }
 
     /// 获取 x2APIC 的 APIC ID
-    fn id(&self) -> u32 {
-        unsafe { rdmsr(IA32_X2APIC_APICID.into()) as u32 }
+    fn id(&self) -> ApicId {
+        unsafe { ApicId::new(rdmsr(IA32_X2APIC_APICID.into()) as u32) }
     }
 
     /// 设置 Local Vector Table (LVT) 寄存器

+ 6 - 6
kernel/src/arch/x86_64/driver/apic/xapic.rs

@@ -14,15 +14,15 @@ use crate::{
     smp::core::smp_get_processor_id,
 };
 
-use super::{LVTRegister, LocalAPIC, LVT};
+use super::{hw_irq::ApicId, LVTRegister, LocalAPIC, LVT};
 
 /// per-cpu的xAPIC的MMIO空间起始地址
-static mut XAPIC_INSTANCES: [RefCell<Option<XApic>>; PerCpu::MAX_CPU_NUM] =
-    [const { RefCell::new(None) }; PerCpu::MAX_CPU_NUM];
+static mut XAPIC_INSTANCES: [RefCell<Option<XApic>>; PerCpu::MAX_CPU_NUM as usize] =
+    [const { RefCell::new(None) }; PerCpu::MAX_CPU_NUM as usize];
 
 #[inline(always)]
 pub(super) fn current_xapic_instance() -> &'static RefCell<Option<XApic>> {
-    unsafe { &XAPIC_INSTANCES.as_ref()[smp_get_processor_id() as usize] }
+    unsafe { &XAPIC_INSTANCES.as_ref()[smp_get_processor_id().data() as usize] }
 }
 
 /// TODO:统一变量
@@ -300,8 +300,8 @@ impl LocalAPIC for XApic {
     }
 
     /// 获取ID
-    fn id(&self) -> u32 {
-        unsafe { self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID.into()) >> 24 }
+    fn id(&self) -> ApicId {
+        unsafe { ApicId::new(self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID.into()) >> 24) }
     }
 
     /// 设置LVT寄存器的值

+ 0 - 6
kernel/src/arch/x86_64/driver/c_adapter.rs

@@ -1,6 +0,0 @@
-use super::hpet::hpet_instance;
-
-#[no_mangle]
-unsafe extern "C" fn rs_handle_hpet_irq(timer_num: u32) {
-    hpet_instance().handle_irq(timer_num);
-}

+ 0 - 26
kernel/src/arch/x86_64/driver/hpet.c

@@ -1,26 +0,0 @@
-#include <common/glib.h>
-#include <common/kprint.h>
-#include <arch/x86_64/driver/apic/apic.h>
-
-extern void rs_handle_hpet_irq(uint32_t timer_num);
-
-hardware_intr_controller HPET_intr_controller =
-    {
-        .enable = apic_ioapic_enable,
-        .disable = apic_ioapic_disable,
-        .install = apic_ioapic_install,
-        .uninstall = apic_ioapic_uninstall,
-        .ack = apic_ioapic_edge_ack,
-};
-
-void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
-{
-    rs_handle_hpet_irq(param);
-}
-
-void c_hpet_register_irq()
-{
-    struct apic_IO_APIC_RTE_entry entry;
-    apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0);
-    irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
-}

+ 34 - 8
kernel/src/arch/x86_64/driver/hpet.rs

@@ -1,5 +1,4 @@
 use core::{
-    ffi::c_void,
     intrinsics::unlikely,
     mem::size_of,
     ptr::NonNull,
@@ -7,6 +6,7 @@ use core::{
 };
 
 use acpi::HpetInfo;
+use alloc::{string::ToString, sync::Arc};
 use system_error::SystemError;
 
 use crate::{
@@ -16,8 +16,11 @@ use crate::{
         timers::hpet::{HpetRegisters, HpetTimerRegisters},
     },
     exception::{
+        irqdata::IrqHandlerData,
+        irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn},
+        manage::irq_manager,
         softirq::{softirq_vectors, SoftirqNumber},
-        InterruptArch,
+        InterruptArch, IrqNumber,
     },
     kdebug, kerror, kinfo,
     libs::{
@@ -31,10 +34,6 @@ use crate::{
     time::timer::{clock, timer_get_first_expire, update_timer_jiffies},
 };
 
-extern "C" {
-    fn c_hpet_register_irq() -> c_void;
-}
-
 static mut HPET_INSTANCE: Option<Hpet> = None;
 
 #[inline(always)]
@@ -58,6 +57,8 @@ impl Hpet {
     /// HPET0 中断间隔为 10ms
     pub const HPET0_INTERVAL_USEC: u64 = 10000;
 
+    const HPET0_IRQ: IrqNumber = IrqNumber::new(34);
+
     fn new(mut hpet_info: HpetInfo) -> Result<Self, SystemError> {
         let paddr = PhysAddr::new(hpet_info.base_address);
         let map_size = size_of::<HpetRegisters>();
@@ -107,6 +108,8 @@ impl Hpet {
 
     /// 使能HPET
     pub fn hpet_enable(&self) -> Result<(), SystemError> {
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+
         // !!!这里是临时糊代码的,需要在apic重构的时候修改!!!
         let (inner_guard, regs) = unsafe { self.hpet_regs_mut() };
         let freq = regs.frequency();
@@ -135,8 +138,14 @@ impl Hpet {
         }
         drop(inner_guard);
 
-        // todo!("register irq in C");
-        unsafe { c_hpet_register_irq() };
+        irq_manager().request_irq(
+            Self::HPET0_IRQ,
+            "HPET0".to_string(),
+            &HpetIrqHandler,
+            IrqHandleFlags::IRQF_TRIGGER_RISING,
+            None,
+        )?;
+
         self.enabled.store(true, Ordering::SeqCst);
 
         let (inner_guard, regs) = unsafe { self.hpet_regs_mut() };
@@ -147,6 +156,8 @@ impl Hpet {
         drop(inner_guard);
 
         kinfo!("HPET enabled");
+
+        drop(irq_guard);
         return Ok(());
     }
 
@@ -251,3 +262,18 @@ pub fn hpet_init() -> Result<(), SystemError> {
 
     return Ok(());
 }
+
+#[derive(Debug)]
+struct HpetIrqHandler;
+
+impl IrqHandler for HpetIrqHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        hpet_instance().handle_irq(0);
+        return Ok(IrqReturn::Handled);
+    }
+}

+ 0 - 1
kernel/src/arch/x86_64/driver/mod.rs

@@ -1,5 +1,4 @@
 pub mod apic;
-mod c_adapter;
 pub mod hpet;
 pub mod tsc;
 pub mod video;

+ 0 - 30
kernel/src/arch/x86_64/include/x86_64_ipi.h

@@ -1,30 +0,0 @@
-/**
- * @file ipi.h
- * @author fslongjin(longjin@RinGoTek.cn)
- * @brief 多核通信驱动
- * @version 0.1
- * @date 2022-04-07
- *
- * @copyright Copyright (c) 2022
- *
- */
-
-#pragma once
-
-#include <common/kprint.h>
-#include <arch/x86_64/driver/apic/apic.h>
-
-/**
- * @brief ipi中断处理注册函数
- * 
- * @param irq_num 中断向量号
- * @param arg 参数
- * @param handler 处理函数
- * @param param 参数
- * @param controller 当前为NULL 
- * @param irq_name ipi中断名
- * @return int 成功:0
- */
-int ipi_regiserIPI(uint64_t irq_num, void *arg,
-                   void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs),
-                   uint64_t param, hardware_intr_controller *controller, char *irq_name);

+ 3 - 1
kernel/src/arch/x86_64/interrupt/c_adapter.rs

@@ -1,3 +1,5 @@
+use crate::smp::cpu::ProcessorId;
+
 use super::ipi::{ipi_send_smp_init, ipi_send_smp_startup};
 
 #[no_mangle]
@@ -9,7 +11,7 @@ unsafe extern "C" fn rs_ipi_send_smp_init() -> i32 {
 
 #[no_mangle]
 unsafe extern "C" fn rs_ipi_send_smp_startup(target_cpu: u32) -> i32 {
-    return ipi_send_smp_startup(target_cpu)
+    return ipi_send_smp_startup(ProcessorId::new(target_cpu))
         .map(|_| 0)
         .unwrap_or_else(|e| e.to_posix_errno());
 }

+ 3 - 2
kernel/src/arch/x86_64/interrupt/entry.rs

@@ -57,7 +57,8 @@ macro_rules! interrupt_handler {
                         lea rax, ret_from_intr[rip]
                         push rax
                         mov rsi, {irqnum}
-                        jmp do_IRQ
+                        jmp x86_64_do_irq
+                        // jmp do_IRQ
                         "
                     ),
                     irqnum = const($name),
@@ -294,7 +295,7 @@ interrupt_handler!(254);
 interrupt_handler!(255);
 
 #[inline(never)]
-pub(super) unsafe fn setup_interrupt_gate() {
+pub unsafe fn arch_setup_interrupt_gate() {
     set_intr_gate(32, 0, VirtAddr::new(irq_handler32 as usize));
     set_intr_gate(33, 0, VirtAddr::new(irq_handler33 as usize));
     set_intr_gate(34, 0, VirtAddr::new(irq_handler34 as usize));

+ 54 - 0
kernel/src/arch/x86_64/interrupt/handle.rs

@@ -0,0 +1,54 @@
+use core::intrinsics::likely;
+
+use crate::{
+    arch::{
+        driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC},
+        sched::sched,
+    },
+    exception::{irqdesc::irq_desc_manager, softirq::do_softirq, IrqNumber},
+    process::{
+        process::{current_pcb_flags, current_pcb_preempt_count},
+        ProcessFlags,
+    },
+};
+
+use super::TrapFrame;
+
+#[no_mangle]
+unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
+    // swapgs
+
+    if trap_frame.from_user() {
+        x86_64::registers::segmentation::GS::swap();
+        // 拒绝用户态中断
+        return;
+    }
+
+    // 由于x86上面,虚拟中断号与物理中断号是一一对应的,所以这里直接使用vector作为中断号来查询irqdesc
+
+    let desc = irq_desc_manager().lookup(IrqNumber::new(vector));
+
+    if likely(desc.is_some()) {
+        let desc = desc.unwrap();
+        let handler = desc.handler();
+        if likely(handler.is_some()) {
+            handler.unwrap().handle(&desc, trap_frame);
+        } else {
+            CurrentApic.send_eoi();
+        }
+    } else {
+        CurrentApic.send_eoi();
+    }
+
+    do_softirq();
+
+    if current_pcb_preempt_count() > 0 {
+        return;
+    }
+    // 检测当前进程是否可被调度
+    if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE))
+        && vector == APIC_TIMER_IRQ_NUM.data()
+    {
+        sched();
+    }
+}

+ 76 - 13
kernel/src/arch/x86_64/interrupt/ipi.rs

@@ -1,20 +1,33 @@
+use alloc::sync::Arc;
 use system_error::SystemError;
 use x86::apic::ApicId;
 
 use crate::{
     arch::{
-        driver::apic::{CurrentApic, LocalAPIC},
+        driver::apic::{lapic_vector::local_apic_chip, CurrentApic, LocalAPIC},
         smp::SMP_BOOT_DATA,
     },
-    exception::ipi::{IpiKind, IpiTarget},
+    exception::{
+        ipi::{FlushTLBIpiHandler, IpiKind, IpiTarget, KickCpuIpiHandler},
+        irqdata::{IrqData, IrqLineStatus},
+        irqdesc::{irq_desc_manager, IrqDesc, IrqFlowHandler, IrqHandler},
+        HardwareIrqNumber, IrqNumber,
+    },
+    kerror,
+    smp::cpu::ProcessorId,
 };
 
+use super::TrapFrame;
+
+pub const IPI_NUM_KICK_CPU: IrqNumber = IrqNumber::new(200);
+pub const IPI_NUM_FLUSH_TLB: IrqNumber = IrqNumber::new(201);
 /// IPI的种类(架构相关,指定了向量号)
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
-#[repr(u8)]
+#[repr(u32)]
 pub enum ArchIpiKind {
-    KickCpu = 200,
-    FlushTLB = 201,
+    KickCpu = IPI_NUM_KICK_CPU.data(),
+    FlushTLB = IPI_NUM_FLUSH_TLB.data(),
+    SpecVector(HardwareIrqNumber),
 }
 
 impl From<IpiKind> for ArchIpiKind {
@@ -22,6 +35,17 @@ impl From<IpiKind> for ArchIpiKind {
         match kind {
             IpiKind::KickCpu => ArchIpiKind::KickCpu,
             IpiKind::FlushTLB => ArchIpiKind::FlushTLB,
+            IpiKind::SpecVector(vec) => ArchIpiKind::SpecVector(vec),
+        }
+    }
+}
+
+impl Into<u8> for ArchIpiKind {
+    fn into(self) -> u8 {
+        match self {
+            ArchIpiKind::KickCpu => IPI_NUM_KICK_CPU.data() as u8,
+            ArchIpiKind::FlushTLB => IPI_NUM_FLUSH_TLB.data() as u8,
+            ArchIpiKind::SpecVector(vec) => (vec.data() & 0xFF) as u8,
         }
     }
 }
@@ -46,7 +70,7 @@ impl From<IpiTarget> for ArchIpiTarget {
             IpiTarget::All => ArchIpiTarget::All,
             IpiTarget::Other => ArchIpiTarget::Other,
             IpiTarget::Specified(cpu_id) => {
-                ArchIpiTarget::Specified(Self::cpu_id_to_apic_id(cpu_id as u32))
+                ArchIpiTarget::Specified(Self::cpu_id_to_apic_id(cpu_id))
             }
         }
     }
@@ -78,11 +102,11 @@ impl ArchIpiTarget {
     }
 
     #[inline(always)]
-    fn cpu_id_to_apic_id(cpu_id: u32) -> x86::apic::ApicId {
+    fn cpu_id_to_apic_id(cpu_id: ProcessorId) -> x86::apic::ApicId {
         if CurrentApic.x2apic_enabled() {
-            x86::apic::ApicId::X2Apic(cpu_id as u32)
+            x86::apic::ApicId::X2Apic(cpu_id.data() as u32)
         } else {
-            x86::apic::ApicId::XApic(cpu_id as u8)
+            x86::apic::ApicId::XApic(cpu_id.data() as u8)
         }
     }
 }
@@ -102,7 +126,7 @@ impl Into<x86::apic::DestinationShorthand> for ArchIpiTarget {
 pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
     // kdebug!("send_ipi: {:?} {:?}", kind, target);
 
-    let ipi_vec = ArchIpiKind::from(kind) as u8;
+    let ipi_vec = ArchIpiKind::from(kind).into();
     let target = ArchIpiTarget::from(target);
     let shorthand: x86::apic::DestinationShorthand = target.into();
     let destination: x86::apic::ApicId = target.into();
@@ -170,11 +194,11 @@ pub fn ipi_send_smp_init() -> Result<(), SystemError> {
 /// ## 参数
 ///
 /// * `target_cpu` - 目标CPU
-pub fn ipi_send_smp_startup(target_cpu: u32) -> Result<(), SystemError> {
-    if target_cpu as usize >= SMP_BOOT_DATA.cpu_count() {
+pub fn ipi_send_smp_startup(target_cpu: ProcessorId) -> Result<(), SystemError> {
+    if target_cpu.data() as usize >= SMP_BOOT_DATA.cpu_count() {
         return Err(SystemError::EINVAL);
     }
-    let target: ArchIpiTarget = IpiTarget::Specified(target_cpu as usize).into();
+    let target: ArchIpiTarget = IpiTarget::Specified(target_cpu).into();
 
     let icr = if CurrentApic.x2apic_enabled() {
         x86::apic::Icr::for_x2apic(
@@ -203,3 +227,42 @@ pub fn ipi_send_smp_startup(target_cpu: u32) -> Result<(), SystemError> {
     CurrentApic.write_icr(icr);
     return Ok(());
 }
+
+/// 初始化IPI处理函数
+pub fn arch_ipi_handler_init() {
+    do_init_irq_handler(IPI_NUM_KICK_CPU);
+    do_init_irq_handler(IPI_NUM_FLUSH_TLB);
+}
+
+fn do_init_irq_handler(irq: IrqNumber) {
+    let desc = irq_desc_manager().lookup(irq).unwrap();
+    let irq_data: Arc<IrqData> = desc.irq_data();
+    let mut chip_info_guard = irq_data.chip_info_write_irqsave();
+    chip_info_guard.set_chip(Some(local_apic_chip().clone()));
+
+    desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
+    drop(chip_info_guard);
+    desc.set_handler(&X86_64IpiIrqFlowHandler);
+}
+
+#[derive(Debug)]
+struct X86_64IpiIrqFlowHandler;
+
+impl IrqFlowHandler for X86_64IpiIrqFlowHandler {
+    fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
+        let irq = irq_desc.irq_data().irq();
+        match irq {
+            IPI_NUM_KICK_CPU => {
+                KickCpuIpiHandler.handle(irq, None, None).ok();
+            }
+            IPI_NUM_FLUSH_TLB => {
+                FlushTLBIpiHandler.handle(irq, None, None).ok();
+            }
+            _ => {
+                kerror!("Unknown IPI: {}", irq.data());
+            }
+        }
+
+        CurrentApic.send_eoi();
+    }
+}

+ 8 - 5
kernel/src/arch/x86_64/interrupt/mod.rs

@@ -1,6 +1,8 @@
 mod c_adapter;
 pub(super) mod entry;
+mod handle;
 pub mod ipi;
+pub mod msi;
 pub mod trap;
 
 use core::{
@@ -16,11 +18,9 @@ use crate::{
     kerror,
 };
 
-use self::entry::setup_interrupt_gate;
-
 use super::{
     asm::irqflags::{local_irq_restore, local_irq_save},
-    driver::apic::{CurrentApic, LocalAPIC},
+    driver::apic::{lapic_vector::arch_early_irq_init, CurrentApic, LocalAPIC},
 };
 
 /// @brief 关闭中断
@@ -45,8 +45,7 @@ impl InterruptArch for X86_64InterruptArch {
     #[inline(never)]
     unsafe fn arch_irq_init() -> Result<(), SystemError> {
         CurrentIrqArch::interrupt_disable();
-        setup_interrupt_gate();
-        CurrentApic.init_current_cpu();
+
         return Ok(());
     }
     unsafe fn interrupt_enable() {
@@ -90,6 +89,10 @@ impl InterruptArch for X86_64InterruptArch {
         kerror!("Unexpected IRQ trap at vector {}", irq.data());
         CurrentApic.send_eoi();
     }
+
+    fn arch_early_irq_init() -> Result<(), SystemError> {
+        arch_early_irq_init()
+    }
 }
 
 /// 中断栈帧结构体

+ 89 - 0
kernel/src/arch/x86_64/interrupt/msi.rs

@@ -0,0 +1,89 @@
+use bitfield_struct::bitfield;
+
+#[allow(dead_code)]
+#[derive(Debug)]
+pub enum X86MsiData {
+    Normal(X86MsiDataNormal),
+    Dmar(X86MsiDataDmar),
+}
+
+#[bitfield(u32)]
+pub struct X86MsiDataNormal {
+    #[bits(8)]
+    pub vector: u8,
+    #[bits(3)]
+    pub delivery_mode: u8,
+    #[bits(1)]
+    pub dest_mode_logical: bool,
+    #[bits(2)]
+    reserved: u8,
+    #[bits(1)]
+    pub active_low: bool,
+    #[bits(1)]
+    pub is_level_triggered: bool,
+    #[bits(16)]
+    reserved2: u16,
+}
+
+#[derive(Debug)]
+pub struct X86MsiDataDmar {
+    pub dmar_subhandle: u32,
+}
+
+impl X86MsiDataDmar {
+    #[allow(dead_code)]
+    pub const fn new(dmar_subhandle: u32) -> Self {
+        X86MsiDataDmar { dmar_subhandle }
+    }
+}
+
+pub const X86_MSI_BASE_ADDRESS_LOW: u32 = 0xfee00000 >> 20;
+
+#[allow(dead_code)]
+#[derive(Debug)]
+pub enum X86MsiAddrLo {
+    Normal(X86MsiAddrLoNormal),
+    Dmar(X86MsiAddrLoDmar),
+}
+
+#[bitfield(u32)]
+pub struct X86MsiAddrLoNormal {
+    #[bits(2)]
+    reserved_0: u32,
+    #[bits(1)]
+    pub dest_mode_logical: bool,
+    #[bits(1)]
+    pub redirecti_hint: bool,
+    #[bits(1)]
+    reserved_1: bool,
+    #[bits(7)]
+    pub virt_destid_8_14: u32,
+    #[bits(8)]
+    pub destid_0_7: u32,
+    #[bits(12)]
+    pub base_address: u32,
+}
+
+#[bitfield(u32)]
+pub struct X86MsiAddrLoDmar {
+    #[bits(2)]
+    reserved_0: u32,
+    #[bits(1)]
+    pub index_15: bool,
+    #[bits(1)]
+    pub subhandle_valid: bool,
+    #[bits(1)]
+    pub format: bool,
+    #[bits(15)]
+    pub index_0_14: u32,
+    #[bits(12)]
+    pub base_address: u32,
+}
+
+#[bitfield(u32)]
+pub struct X86MsiAddrHi {
+    #[bits(8)]
+    reserved: u32,
+    #[bits(24)]
+    pub destid_8_31: u32,
+}

+ 20 - 20
kernel/src/arch/x86_64/interrupt/trap.rs

@@ -73,7 +73,7 @@ unsafe extern "C" fn do_divide_error(regs: &'static TrapFrame, error_code: u64)
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Divide Error");
@@ -87,7 +87,7 @@ unsafe extern "C" fn do_debug(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Debug Exception");
@@ -101,7 +101,7 @@ unsafe extern "C" fn do_nmi(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("NMI Interrupt");
@@ -115,7 +115,7 @@ unsafe extern "C" fn do_int3(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Int3");
@@ -129,7 +129,7 @@ unsafe extern "C" fn do_overflow(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Overflow Exception");
@@ -143,7 +143,7 @@ unsafe extern "C" fn do_bounds(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Bounds Check");
@@ -157,7 +157,7 @@ unsafe extern "C" fn do_undefined_opcode(regs: &'static TrapFrame, error_code: u
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Undefined Opcode");
@@ -171,7 +171,7 @@ unsafe extern "C" fn do_dev_not_avaliable(regs: &'static TrapFrame, error_code:
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Device Not Available");
@@ -185,7 +185,7 @@ unsafe extern "C" fn do_double_fault(regs: &'static TrapFrame, error_code: u64)
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Double Fault");
@@ -199,7 +199,7 @@ unsafe extern "C" fn do_coprocessor_segment_overrun(regs: &'static TrapFrame, er
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Coprocessor Segment Overrun");
@@ -236,7 +236,7 @@ unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid(),
         msg1,
         msg2
@@ -252,7 +252,7 @@ unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code:
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Segment Not Exists");
@@ -266,7 +266,7 @@ unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Stack Segment Fault");
@@ -313,7 +313,7 @@ Segment Selector Index: {:#x}\n
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid(),
         msg1, msg2, msg3,
         error_code & 0xfff8
@@ -329,7 +329,7 @@ unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid(),
         x86::controlregs::cr2()
     );
@@ -370,7 +370,7 @@ unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64)
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("x87 FPU Error");
@@ -384,7 +384,7 @@ unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u6
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Alignment Check");
@@ -398,7 +398,7 @@ unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64)
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Machine Check");
@@ -412,7 +412,7 @@ unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("SIMD Exception");
@@ -426,7 +426,7 @@ unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error
         error_code,
         regs.rsp,
         regs.rip,
-        smp_get_processor_id(),
+        smp_get_processor_id().data(),
         ProcessManager::current_pid()
     );
     panic!("Virtualization Exception");

+ 0 - 15
kernel/src/arch/x86_64/interrupt/x86_64_ipi.c

@@ -1,15 +0,0 @@
-#include "x86_64_ipi.h"
-#include <arch/x86_64/driver/apic/apic.h>
-
-int ipi_regiserIPI(uint64_t irq_num, void *arg,
-                   void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs),
-                   uint64_t param, hardware_intr_controller *controller, char *irq_name)
-{
-    irq_desc_t *p = &SMP_IPI_desc[irq_num - 200];
-    p->controller = NULL; // 由于ipi不涉及到具体的硬件操作,因此不需要controller
-    p->irq_name = irq_name;
-    p->parameter = param;
-    p->flags = 0;
-    p->handler = handler;
-    return 0;
-} 

+ 6 - 4
kernel/src/arch/x86_64/kvm/vmx/ept.rs

@@ -4,6 +4,8 @@ use crate::arch::MMArch;
 use crate::mm::page::PageFlags;
 use crate::mm::{PageTableKind, PhysAddr, VirtAddr};
 use crate::smp::core::smp_get_processor_id;
+use crate::smp::cpu::AtomicProcessorId;
+use crate::smp::cpu::ProcessorId;
 use core::sync::atomic::{compiler_fence, AtomicUsize, Ordering};
 use system_error::SystemError;
 use x86::msr;
@@ -25,9 +27,9 @@ pub fn check_ept_features() -> Result<(), SystemError> {
 
 /// 标志当前没有处理器持有内核映射器的锁
 /// 之所以需要这个标志,是因为AtomicUsize::new(0)会把0当作一个处理器的id
-const EPT_MAPPER_NO_PROCESSOR: usize = !0;
+const EPT_MAPPER_NO_PROCESSOR: ProcessorId = ProcessorId::INVALID;
 /// 当前持有内核映射器锁的处理器
-static EPT_MAPPER_LOCK_OWNER: AtomicUsize = AtomicUsize::new(EPT_MAPPER_NO_PROCESSOR);
+static EPT_MAPPER_LOCK_OWNER: AtomicProcessorId = AtomicProcessorId::new(EPT_MAPPER_NO_PROCESSOR);
 /// 内核映射器的锁计数器
 static EPT_MAPPER_LOCK_COUNT: AtomicUsize = AtomicUsize::new(0);
 
@@ -41,7 +43,7 @@ pub struct EptMapper {
 }
 
 impl EptMapper {
-    fn lock_cpu(cpuid: usize, mapper: PageMapper) -> Self {
+    fn lock_cpu(cpuid: ProcessorId, mapper: PageMapper) -> Self {
         loop {
             match EPT_MAPPER_LOCK_OWNER.compare_exchange_weak(
                 EPT_MAPPER_NO_PROCESSOR,
@@ -69,7 +71,7 @@ impl EptMapper {
     /// @brief 锁定内核映射器, 并返回一个内核映射器对象
     #[inline(always)]
     pub fn lock() -> Self {
-        let cpuid = smp_get_processor_id() as usize;
+        let cpuid = smp_get_processor_id();
         let mapper = unsafe { PageMapper::current(PageTableKind::EPT, LockedFrameAllocator) };
         return Self::lock_cpu(cpuid, mapper);
     }

+ 4 - 4
kernel/src/arch/x86_64/process/table.rs

@@ -32,24 +32,24 @@ pub unsafe fn switch_fs_and_gs(fs: SegmentSelector, gs: SegmentSelector) {
 
 #[derive(Debug)]
 pub struct TSSManager {
-    tss: [TaskStateSegment; PerCpu::MAX_CPU_NUM],
+    tss: [TaskStateSegment; PerCpu::MAX_CPU_NUM as usize],
 }
 
 impl TSSManager {
     const fn new() -> Self {
         return Self {
-            tss: [TaskStateSegment::new(); PerCpu::MAX_CPU_NUM],
+            tss: [TaskStateSegment::new(); PerCpu::MAX_CPU_NUM as usize],
         };
     }
 
     /// 获取当前CPU的TSS
     pub unsafe fn current_tss() -> &'static mut TaskStateSegment {
-        &mut TSS_MANAGER.tss[smp_get_processor_id() as usize]
+        &mut TSS_MANAGER.tss[smp_get_processor_id().data() as usize]
     }
 
     /// 加载当前CPU的TSS
     pub unsafe fn load_tr() {
-        let index = (10 + smp_get_processor_id() * 2) as u16;
+        let index = (10 + smp_get_processor_id().data() * 2) as u16;
         let selector = SegmentSelector::new(index, Ring::Ring0);
 
         Self::set_tss_descriptor(

+ 22 - 7
kernel/src/arch/x86_64/sched.rs

@@ -1,9 +1,11 @@
+use core::hint::spin_loop;
+
 use crate::{
     exception::InterruptArch, include::bindings::bindings::enter_syscall_int, sched::SchedArch,
-    syscall::SYS_SCHED,
+    smp::core::smp_get_processor_id, syscall::SYS_SCHED,
 };
 
-use super::CurrentIrqArch;
+use super::{driver::apic::apic_timer::apic_timer_init, CurrentIrqArch};
 
 /// @brief 若内核代码不处在中断上下文中,那么将可以使用本函数,发起一个sys_sched系统调用,然后运行调度器。
 /// 由于只能在中断上下文中进行进程切换,因此需要发起一个系统调用SYS_SCHED。
@@ -14,9 +16,7 @@ pub extern "C" fn sched() {
     }
 }
 
-extern "C" {
-    fn apic_timer_init();
-}
+static mut BSP_INIT_OK: bool = false;
 
 pub struct X86_64SchedArch;
 
@@ -33,8 +33,23 @@ impl SchedArch for X86_64SchedArch {
     }
 
     fn initial_setup_sched_local() {
-        unsafe {
-            apic_timer_init();
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+
+        let cpu_id = smp_get_processor_id();
+
+        if cpu_id.data() != 0 {
+            while !unsafe { BSP_INIT_OK } {
+                spin_loop();
+            }
+        }
+
+        apic_timer_init();
+        if smp_get_processor_id().data() == 0 {
+            unsafe {
+                BSP_INIT_OK = true;
+            }
         }
+
+        drop(irq_guard);
     }
 }

+ 12 - 12
kernel/src/arch/x86_64/smp/mod.rs

@@ -15,7 +15,7 @@ use crate::{
     libs::rwlock::RwLock,
     mm::percpu::PerCpu,
     process::ProcessManager,
-    smp::{core::smp_get_processor_id, SMPArch},
+    smp::{core::smp_get_processor_id, cpu::ProcessorId, SMPArch},
 };
 
 use super::{acpi::early_acpi_boot_init, CurrentIrqArch};
@@ -35,7 +35,7 @@ struct ApStartStackInfo {
 #[no_mangle]
 unsafe extern "C" fn smp_ap_start() -> ! {
     CurrentIrqArch::interrupt_disable();
-    let vaddr = cpu_core_info[smp_get_processor_id() as usize].stack_start as usize;
+    let vaddr = cpu_core_info[smp_get_processor_id().data() as usize].stack_start as usize;
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
     let v = ApStartStackInfo { vaddr };
     smp_init_switch_stack(&v);
@@ -55,8 +55,8 @@ unsafe extern "sysv64" fn smp_init_switch_stack(st: &ApStartStackInfo) -> ! {
 
 unsafe extern "C" fn smp_ap_start_stage1() -> ! {
     let id = smp_get_processor_id();
-    kdebug!("smp_ap_start_stage1: id: {}\n", id);
-    let current_idle = ProcessManager::idle_pcb()[smp_get_processor_id() as usize].clone();
+    kdebug!("smp_ap_start_stage1: id: {}\n", id.data());
+    let current_idle = ProcessManager::idle_pcb()[smp_get_processor_id().data() as usize].clone();
 
     let tss = TSSManager::current_tss();
 
@@ -80,7 +80,7 @@ pub struct SmpBootData {
     /// CPU的物理ID(指的是Local APIC ID)
     ///
     /// 这里必须保证第0项的是bsp的物理ID
-    phys_id: [usize; PerCpu::MAX_CPU_NUM],
+    phys_id: [usize; PerCpu::MAX_CPU_NUM as usize],
 }
 
 #[allow(dead_code)]
@@ -99,17 +99,17 @@ impl SmpBootData {
         self.phys_id[0]
     }
 
-    pub unsafe fn set_cpu_count(&self, cpu_count: usize) {
+    pub unsafe fn set_cpu_count(&self, cpu_count: u32) {
         if self.initialized.load(Ordering::SeqCst) == false {
             let p = self as *const SmpBootData as *mut SmpBootData;
-            (*p).cpu_count = cpu_count;
+            (*p).cpu_count = cpu_count.try_into().unwrap();
         }
     }
 
-    pub unsafe fn set_phys_id(&self, cpu_id: usize, phys_id: usize) {
+    pub unsafe fn set_phys_id(&self, cpu_id: ProcessorId, phys_id: usize) {
         if self.initialized.load(Ordering::SeqCst) == false {
             let p = self as *const SmpBootData as *mut SmpBootData;
-            (*p).phys_id[cpu_id] = phys_id;
+            (*p).phys_id[cpu_id.data() as usize] = phys_id;
         }
     }
 
@@ -122,19 +122,19 @@ impl SmpBootData {
 pub(super) static SMP_BOOT_DATA: SmpBootData = SmpBootData {
     initialized: AtomicBool::new(false),
     cpu_count: 0,
-    phys_id: [0; PerCpu::MAX_CPU_NUM],
+    phys_id: [0; PerCpu::MAX_CPU_NUM as usize],
 };
 
 #[allow(dead_code)]
 #[derive(Debug)]
 pub struct X86_64SmpManager {
-    ia64_cpu_to_sapicid: RwLock<[Option<usize>; PerCpu::MAX_CPU_NUM]>,
+    ia64_cpu_to_sapicid: RwLock<[Option<usize>; PerCpu::MAX_CPU_NUM as usize]>,
 }
 
 impl X86_64SmpManager {
     pub const fn new() -> Self {
         return Self {
-            ia64_cpu_to_sapicid: RwLock::new([None; PerCpu::MAX_CPU_NUM]),
+            ia64_cpu_to_sapicid: RwLock::new([None; PerCpu::MAX_CPU_NUM as usize]),
         };
     }
     /// initialize the logical cpu number to APIC ID mapping

+ 1 - 1
kernel/src/driver/Makefile

@@ -1,7 +1,7 @@
 
 CFLAGS += -I .
 
-kernel_driver_subdirs:=pci acpi disk keyboard mouse multiboot2 timers hid 
+kernel_driver_subdirs:=acpi disk multiboot2 timers hid 
 
 ECHO:
 	@echo "$@"

+ 1 - 1
kernel/src/driver/base/device/driver.rs

@@ -50,7 +50,7 @@ pub fn driver_manager() -> &'static DriverManager {
 /// 否则在运行时会报错
 pub trait Driver: Sync + Send + Debug + KObject {
     fn coredump(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
-        Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
+        Err(SystemError::ENOSYS)
     }
 
     /// @brief: 获取驱动标识符

+ 9 - 3
kernel/src/driver/base/device/mod.rs

@@ -9,6 +9,7 @@ use crate::{
         acpi::glue::acpi_device_notify,
         base::map::{LockedDevsMap, LockedKObjMap},
     },
+    exception::irqdata::IrqHandlerData,
     filesystem::{
         sysfs::{
             file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOps,
@@ -875,7 +876,7 @@ impl DeviceMatcher<&str> for DeviceMatchName {
 }
 
 /// Cookie to identify the device
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Hash)]
 pub struct DeviceId {
     data: Option<&'static str>,
     allocated: Option<String>,
@@ -883,7 +884,7 @@ pub struct DeviceId {
 
 impl DeviceId {
     #[allow(dead_code)]
-    pub fn new(data: Option<&'static str>, allocated: Option<String>) -> Option<Self> {
+    pub fn new(data: Option<&'static str>, allocated: Option<String>) -> Option<Arc<Self>> {
         if data.is_none() && allocated.is_none() {
             return None;
         }
@@ -893,7 +894,7 @@ impl DeviceId {
             return None;
         }
 
-        return Some(Self { data, allocated });
+        return Some(Arc::new(Self { data, allocated }));
     }
 
     pub fn id(&self) -> Option<&str> {
@@ -904,6 +905,7 @@ impl DeviceId {
         }
     }
 
+    #[allow(dead_code)]
     pub fn set_allocated(&mut self, allocated: String) {
         self.allocated = Some(allocated);
         self.data = None;
@@ -915,3 +917,7 @@ impl PartialEq for DeviceId {
         return self.id() == other.id();
     }
 }
+
+impl Eq for DeviceId {}
+
+impl IrqHandlerData for DeviceId {}

+ 45 - 0
kernel/src/driver/input/ps2_dev/mod.rs

@@ -1 +1,46 @@
+use bitfield_struct::bitfield;
+
 pub mod ps2_device;
+
+/// PS2键盘控制器的状态寄存器
+#[bitfield(u8)]
+pub struct Ps2StatusRegister {
+    /// 输出缓冲区满标志
+    ///
+    /// (必须在尝试从 IO 端口 0x60 读取数据之前设置)
+    pub outbuf_full: bool,
+
+    /// 输入缓冲区满标志
+    ///
+    /// (在尝试向 IO 端口 0x60 或 IO 端口 0x64 写入数据之前必须清除)
+    pub inbuf_full: bool,
+
+    /// 系统标志
+    ///
+    /// 如果系统通过自检 (POST),则意味着在复位时被清除并由固件设置(通过 PS/2 控制器配置字节)
+    pub system_flag: bool,
+
+    /// 命令/数据标志
+    ///
+    /// (0 = 写入输入缓冲区的数据是 PS/2 设备的数据,1 = 写入输入缓冲区的数据是 PS/2 控制器命令的数据)
+    pub command_data: bool,
+
+    /// 未知标志1
+    ///
+    /// 可能是“键盘锁”(现代系统中更可能未使用)
+    pub unknown1: bool,
+
+    /// 未知标志2
+    ///
+    /// 可能是“接收超时”或“第二个 PS/2 端口输出缓冲区已满”
+    pub unknown2: bool,
+    /// 超时错误标志
+    ///
+    /// 超时错误(0 = 无错误,1 = 超时错误)
+    pub timeout_error: bool,
+
+    /// 奇偶校验错误标志
+    ///
+    /// (0 = 无错误,1 = 奇偶校验错误)
+    pub parity_error: bool,
+}

+ 2 - 1
kernel/src/driver/input/ps2_mouse/ps_mouse_device.rs

@@ -3,6 +3,7 @@ use core::hint::spin_loop;
 use alloc::{
     string::ToString,
     sync::{Arc, Weak},
+    vec::Vec,
 };
 use kdepends::ringbuffer::{AllocRingBuffer, RingBuffer};
 use system_error::SystemError;
@@ -637,7 +638,7 @@ impl IndexNode for Ps2MouseDevice {
         self
     }
 
-    fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, SystemError> {
+    fn list(&self) -> Result<Vec<alloc::string::String>, SystemError> {
         todo!()
     }
 

+ 36 - 12
kernel/src/driver/input/ps2_mouse/ps_mouse_driver.rs

@@ -10,7 +10,7 @@ use crate::{
     arch::{io::PortIOArch, CurrentPortIOArch},
     driver::{
         base::{
-            device::{bus::Bus, driver::Driver, Device, IdTable},
+            device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable},
             kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
             kset::KSet,
         },
@@ -19,6 +19,12 @@ use crate::{
             serio_driver::{serio_driver_manager, SerioDriver},
         },
     },
+    exception::{
+        irqdata::IrqHandlerData,
+        irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn},
+        manage::irq_manager,
+        IrqNumber,
+    },
     filesystem::kernfs::KernFSInode,
     init::initcall::INITCALL_DEVICE,
     libs::{
@@ -29,18 +35,30 @@ use crate::{
 
 use super::ps_mouse_device::{ps2_mouse_device, Ps2MouseDevice};
 
-extern "C" {
-    fn c_ps2_mouse_init();
-}
+const PS2_MOUSE_IRQ_NUM: IrqNumber = IrqNumber::new(0x2c);
 
 #[no_mangle]
-unsafe extern "C" fn ps2_mouse_driver_interrupt() {
-    if let Some(psmouse_device) = ps2_mouse_device() {
-        ps2_mouse_driver()
-            .interrupt(&(psmouse_device as Arc<dyn SerioDevice>), 0, 0)
-            .ok();
-    } else {
-        unsafe { CurrentPortIOArch::in8(0x60) };
+unsafe extern "C" fn ps2_mouse_driver_interrupt() {}
+
+#[derive(Debug)]
+struct Ps2MouseIrqHandler;
+
+impl IrqHandler for Ps2MouseIrqHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dev_id: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        if let Some(psmouse_device) = ps2_mouse_device() {
+            return Ok(ps2_mouse_driver()
+                .interrupt(&(psmouse_device as Arc<dyn SerioDevice>), 0, 0)
+                .map(|_| IrqReturn::Handled)
+                .unwrap_or_else(|_| IrqReturn::NotHandled));
+        } else {
+            unsafe { CurrentPortIOArch::in8(0x60) };
+            return Ok(IrqReturn::NotHandled);
+        }
     }
 }
 
@@ -226,7 +244,13 @@ impl SerioDriver for Ps2MouseDriver {
         device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
 
         device.init()?;
-        unsafe { c_ps2_mouse_init() };
+        irq_manager().request_irq(
+            PS2_MOUSE_IRQ_NUM,
+            "psmouse".to_string(),
+            &Ps2MouseIrqHandler,
+            IrqHandleFlags::IRQF_SHARED | IrqHandleFlags::IRQF_TRIGGER_RISING,
+            Some(DeviceId::new(Some(Self::NAME), None).unwrap()),
+        )?;
         return Ok(());
     }
 

+ 0 - 10
kernel/src/driver/keyboard/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 23
kernel/src/driver/keyboard/mod.rs

@@ -1,24 +1 @@
-use crate::init::initcall::INITCALL_LATE;
-use core::ffi::c_void;
-use system_error::SystemError;
-use unified_init::macros::unified_init;
-
 pub mod ps2_keyboard;
-// pub mod ps2_keyboard_inode;
-
-extern "C" {
-    fn ps2_keyboard_init() -> c_void;
-}
-
-/// 初始化ps2键盘
-///
-/// todo: 将ps2键盘适配到设备驱动模型后,把初始化时机改为INITCALL_DEVICE
-///
-/// 当前是LATE的原因是键盘驱动的TypeOneFSM需要在tty设备初始化之后才能工作。
-#[unified_init(INITCALL_LATE)]
-fn rs_ps2_keyboard_init() -> Result<(), SystemError> {
-    unsafe {
-        ps2_keyboard_init();
-    }
-    return Ok(());
-}

+ 0 - 209
kernel/src/driver/keyboard/ps2_keyboard.c

@@ -1,209 +0,0 @@
-#include "ps2_keyboard.h"
-#include <arch/x86_64/driver/apic/apic.h>
-#include <mm/mm.h>
-#include <mm/slab.h>
-#include <common/printk.h>
-#include <filesystem/vfs/VFS.h>
-#include <common/spinlock.h>
-#include <common/kfifo.h>
-
-// 键盘输入缓冲区
-static struct kfifo_t kb_buf;
-
-extern void ps2_keyboard_register(struct vfs_file_operations_t *);
-extern void ps2_keyboard_parse_keycode(uint8_t input);
-
-// 缓冲区读写锁
-static spinlock_t ps2_kb_buf_rw_lock;
-
-/**
- * @brief 重置ps2键盘输入缓冲区
- *
- * @param kbp 缓冲区对象指针
- */
-static void ps2_keyboard_reset_buffer(struct kfifo_t *kbp)
-{
-    kfifo_reset(kbp);
-}
-struct apic_IO_APIC_RTE_entry entry;
-
-hardware_intr_controller ps2_keyboard_intr_controller =
-    {
-        .enable = apic_ioapic_enable,
-        .disable = apic_ioapic_disable,
-        .install = apic_ioapic_install,
-        .uninstall = apic_ioapic_uninstall,
-        .ack = apic_ioapic_edge_ack,
-
-};
-
-/**
- * @brief 打开键盘文件
- *
- * @param inode 所在的inode
- * @param filp 文件指针
- * @return long
- */
-long ps2_keyboard_open(void *inode, void *filp)
-{
-    ps2_keyboard_reset_buffer(&kb_buf);
-    return 0;
-}
-
-/**
- * @brief 关闭键盘文件
- *
- * @param inode 所在的inode
- * @param filp 文件指针
- * @return long
- */
-long ps2_keyboard_close(void *inode, void *filp)
-{
-    ps2_keyboard_reset_buffer(&kb_buf);
-    return 0;
-}
-
-/**
- * @brief 键盘io控制接口
- *
- * @param inode 所在的inode
- * @param filp 键盘文件指针
- * @param cmd 命令
- * @param arg 参数
- * @return long
- */
-long ps2_keyboard_ioctl(void *inode, void *filp, uint64_t cmd, uint64_t arg)
-{
-    switch (cmd)
-    {
-    case KEYBOARD_CMD_RESET_BUFFER:
-        ps2_keyboard_reset_buffer(&kb_buf);
-        break;
-
-    default:
-        break;
-    }
-    return 0;
-}
-
-/**
- * @brief 读取键盘文件的操作接口
- *
- * @param filp 文件指针
- * @param buf 输出缓冲区
- * @param count 要读取的字节数
- * @param position 读取的位置
- * @return long 读取的字节数
- */
-long ps2_keyboard_read(void *filp, char *buf, int64_t count, long *position)
-{
-    // 缓冲区为空则等待
-    while (kfifo_empty(&kb_buf))
-        ;
-
-    count = (count > kb_buf.size) ? kb_buf.size : count;
-    return kfifo_out(&kb_buf, buf, count);
-}
-
-/**
- * @brief 键盘文件写入接口(无作用,空)
- *
- * @param filp
- * @param buf
- * @param count
- * @param position
- * @return long
- */
-long ps2_keyboard_write(void *filp, char *buf, int64_t count, long *position)
-{
-    return 0;
-}
-/**
- * @brief ps2键盘驱动的虚拟文件接口
- *
- */
-struct vfs_file_operations_t ps2_keyboard_fops =
-    {
-        .open = ps2_keyboard_open,
-        .close = ps2_keyboard_close,
-        .ioctl = ps2_keyboard_ioctl,
-        .read = ps2_keyboard_read,
-        .write = ps2_keyboard_write,
-};
-
-/**
- * @brief 键盘中断处理函数(中断上半部)
- *  将数据存入缓冲区
- * @param irq_num 中断向量号
- * @param param 参数
- * @param regs 寄存器信息
- */
-void ps2_keyboard_handler(ul irq_num, ul buf_vaddr, struct pt_regs *regs)
-{
-    unsigned char x = io_in8(PORT_PS2_KEYBOARD_DATA);
-    ps2_keyboard_parse_keycode((uint8_t)x);
-}
-/**
- * @brief 初始化键盘驱动程序的函数
- *
- */
-void ps2_keyboard_init()
-{
-
-    // ======= 初始化键盘循环队列缓冲区 ===========
-
-    // 初始化键盘循环队列缓冲区
-    kfifo_alloc(&kb_buf, ps2_keyboard_buffer_size, 0);
-
-    // ======== 初始化中断RTE entry ==========
-
-    entry.vector = PS2_KEYBOARD_INTR_VECTOR; // 设置中断向量号
-    entry.deliver_mode = IO_APIC_FIXED;      // 投递模式:混合
-    entry.dest_mode = DEST_PHYSICAL;         // 物理模式投递中断
-    entry.deliver_status = IDLE;
-    entry.trigger_mode = EDGE_TRIGGER; // 设置边沿触发
-    entry.polarity = POLARITY_HIGH;    // 高电平触发
-    entry.remote_IRR = IRR_RESET;
-    entry.mask = MASKED;
-    entry.reserved = 0;
-
-    entry.destination.physical.reserved1 = 0;
-    entry.destination.physical.reserved2 = 0;
-    entry.destination.physical.phy_dest = 0; // 设置投递到BSP处理器
-
-    // ======== 初始化键盘控制器,写入配置值 =========
-    wait_ps2_keyboard_write();
-    io_out8(PORT_PS2_KEYBOARD_CONTROL, PS2_KEYBOARD_COMMAND_WRITE);
-    wait_ps2_keyboard_write();
-    io_out8(PORT_PS2_KEYBOARD_DATA, PS2_KEYBOARD_PARAM_INIT);
-    wait_ps2_keyboard_write();
-
-    // 执行一百万次nop,等待键盘控制器把命令执行完毕
-    for (int i = 0; i < 1000; ++i)
-        for (int j = 0; j < 1000; ++j)
-            nop();
-
-
-    // 初始化键盘缓冲区的读写锁
-    spin_init(&ps2_kb_buf_rw_lock);
-
-    // 注册中断处理程序
-    irq_register(PS2_KEYBOARD_INTR_VECTOR, &entry, &ps2_keyboard_handler, (ul)&kb_buf, &ps2_keyboard_intr_controller, "ps/2 keyboard");
-
-    // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。
-    io_in8(PORT_PS2_KEYBOARD_DATA);
-    // 将设备挂载到devfs
-    ps2_keyboard_register(&ps2_keyboard_fops);
-
-    kinfo("ps/2 keyboard registered.");
-}
-
-/**
- * @brief 键盘驱动卸载函数
- *
- */
-void ps2_keyboard_exit()
-{
-    irq_unregister(PS2_KEYBOARD_INTR_VECTOR);
-    kfifo_free_alloc(&kb_buf);
-}

+ 0 - 40
kernel/src/driver/keyboard/ps2_keyboard.h

@@ -1,40 +0,0 @@
-#pragma once
-
-#include <common/glib.h>
-
-#define PS2_KEYBOARD_INTR_VECTOR 0x21 // 键盘的中断向量号
-
-// 定义键盘循环队列缓冲区大小为100bytes
-#define ps2_keyboard_buffer_size 8
-
-#define KEYBOARD_CMD_RESET_BUFFER 1
-
-#define PORT_PS2_KEYBOARD_DATA 0x60
-#define PORT_PS2_KEYBOARD_STATUS 0x64
-#define PORT_PS2_KEYBOARD_CONTROL 0x64
-
-#define PS2_KEYBOARD_COMMAND_WRITE 0x60 // 向键盘发送配置命令
-#define PS2_KEYBOARD_COMMAND_READ 0x20  // 读取键盘的配置值
-#define PS2_KEYBOARD_PARAM_INIT 0x47    // 初始化键盘控制器的配置值
-
-// ========= 检测键盘控制器输入/输出缓冲区是否已满
-#define PS2_KEYBOARD_FLAG_OUTBUF_FULL 0x01 // 键盘的输出缓冲区已满标志位
-#define PS2_KEYBOARD_FLAG_INBUF_FULL 0x02 // 键盘的输入缓冲区已满标志位
-
-// 等待向键盘控制器写入信息完成
-// todo: bugfix:在不包含ps2键盘控制器的机器上,这里会卡死
-#define wait_ps2_keyboard_write()                                              \
-  while (io_in8(PORT_PS2_KEYBOARD_STATUS) & PS2_KEYBOARD_FLAG_INBUF_FULL)
-// #define wait_ps2_keyboard_write() (1)
-// 等待从键盘控制器读取信息完成
-#define wait_ps2_keyboard_read()                                               \
-  while (io_in8(PORT_PS2_KEYBOARD_STATUS) & PS2_KEYBOARD_FLAG_OUTBUF_FULL)
-// #define wait_ps2_keyboard_read() (1)
-
-extern struct vfs_file_operations_t ps2_keyboard_fops;
-
-/**
- * @brief 键盘驱动卸载函数
- *
- */
-void ps2_keyboard_exit();

+ 126 - 49
kernel/src/driver/keyboard/ps2_keyboard.rs

@@ -1,9 +1,24 @@
-use core::{ffi::c_void, sync::atomic::AtomicI32};
+use core::hint::spin_loop;
 
-use alloc::sync::{Arc, Weak};
+use alloc::{
+    string::ToString,
+    sync::{Arc, Weak},
+};
+
+use unified_init::macros::unified_init;
 
 use crate::{
-    driver::base::device::device_number::{DeviceNumber, Major},
+    arch::{io::PortIOArch, CurrentPortIOArch},
+    driver::{
+        base::device::device_number::{DeviceNumber, Major},
+        input::ps2_dev::Ps2StatusRegister,
+    },
+    exception::{
+        irqdata::IrqHandlerData,
+        irqdesc::{IrqHandleFlags, IrqHandler, IrqReturn},
+        manage::irq_manager,
+        IrqNumber,
+    },
     filesystem::{
         devfs::{devfs_register, DevFS, DeviceINode},
         vfs::{
@@ -11,13 +26,30 @@ use crate::{
             FileSystem, FileType, IndexNode, Metadata,
         },
     },
-    include::bindings::bindings::vfs_file_operations_t,
+    init::initcall::INITCALL_DEVICE,
     libs::{keyboard_parser::TypeOneFSM, rwlock::RwLock, spinlock::SpinLock},
     time::TimeSpec,
 };
 use system_error::SystemError;
+
+/// PS2键盘的中断向量号
+const PS2_KEYBOARD_INTR_VECTOR: IrqNumber = IrqNumber::new(0x21);
+
+const PORT_PS2_KEYBOARD_DATA: u8 = 0x60;
+const PORT_PS2_KEYBOARD_STATUS: u8 = 0x64;
+const PORT_PS2_KEYBOARD_CONTROL: u8 = 0x64;
+
+/// 向键盘发送配置命令
+const PS2_KEYBOARD_COMMAND_WRITE: u8 = 0x60;
+
+/// 读取键盘的配置值
+#[allow(dead_code)]
+const PS2_KEYBOARD_COMMAND_READ: u8 = 0x20;
+/// 初始化键盘控制器的配置值
+const PS2_KEYBOARD_PARAM_INIT: u8 = 0x47;
+
 #[derive(Debug)]
-pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>, AtomicI32); // self.1 用来记录有多少个文件打开了这个inode
+pub struct LockedPS2KeyBoardInode(RwLock<PS2KeyBoardInode>);
 
 lazy_static! {
     static ref PS2_KEYBOARD_FSM: SpinLock<TypeOneFSM> = SpinLock::new(TypeOneFSM::new());
@@ -33,17 +65,14 @@ pub struct PS2KeyBoardInode {
     fs: Weak<DevFS>,
     /// INode 元数据
     metadata: Metadata,
-    /// 键盘操作函数
-    f_ops: vfs_file_operations_t,
 }
 
 impl LockedPS2KeyBoardInode {
-    pub fn new(f_ops: &vfs_file_operations_t) -> Arc<Self> {
+    pub fn new() -> Arc<Self> {
         let inode = PS2KeyBoardInode {
             // uuid: Uuid::new_v5(),
             self_ref: Weak::default(),
             fs: Weak::default(),
-            f_ops: f_ops.clone(), // 从引用复制一遍获取所有权
             metadata: Metadata {
                 dev_id: 1,
                 inode_id: generate_inode_id(),
@@ -62,10 +91,7 @@ impl LockedPS2KeyBoardInode {
             },
         };
 
-        let result = Arc::new(LockedPS2KeyBoardInode(
-            RwLock::new(inode),
-            AtomicI32::new(0),
-        ));
+        let result = Arc::new(LockedPS2KeyBoardInode(RwLock::new(inode)));
         result.0.write().self_ref = Arc::downgrade(&result);
 
         return result;
@@ -78,9 +104,8 @@ impl DeviceINode for LockedPS2KeyBoardInode {
     }
 }
 
-#[no_mangle] // 不重命名
-pub extern "C" fn ps2_keyboard_register(f_ops: &vfs_file_operations_t) {
-    devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new(f_ops))
+fn ps2_keyboard_register() {
+    devfs_register("ps2_keyboard", LockedPS2KeyBoardInode::new())
         .expect("Failed to register ps/2 keyboard");
 }
 
@@ -88,21 +113,11 @@ impl IndexNode for LockedPS2KeyBoardInode {
     fn read_at(
         &self,
         _offset: usize,
-        len: usize,
-        buf: &mut [u8],
+        _len: usize,
+        _buf: &mut [u8],
         _data: &mut FilePrivateData,
     ) -> Result<usize, SystemError> {
-        let guard = self.0.read();
-        let func = guard.f_ops.read.unwrap();
-        let r = unsafe {
-            func(
-                0 as *mut c_void,
-                &mut buf[0..len] as *mut [u8] as *mut i8,
-                len as i64,
-                0 as *mut i64,
-            )
-        };
-        return Ok(r as usize);
+        return Err(SystemError::ENOSYS);
     }
 
     fn write_at(
@@ -112,28 +127,14 @@ impl IndexNode for LockedPS2KeyBoardInode {
         _buf: &[u8],
         _data: &mut FilePrivateData,
     ) -> Result<usize, SystemError> {
-        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+        return Err(SystemError::ENOSYS);
     }
 
     fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
-        let prev_ref_count = self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
-        if prev_ref_count == 0 {
-            // 第一次打开,需要初始化
-            let guard = self.0.write();
-            let func = guard.f_ops.open.unwrap();
-            let _ = unsafe { func(0 as *mut c_void, 0 as *mut c_void) };
-        }
         return Ok(());
     }
 
     fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
-        let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
-        if prev_ref_count == 1 {
-            // 最后一次关闭,需要释放
-            let guard = self.0.write();
-            let func = guard.f_ops.close.unwrap();
-            let _ = unsafe { func(0 as *mut c_void, 0 as *mut c_void) };
-        }
         return Ok(());
     }
 
@@ -166,9 +167,85 @@ impl IndexNode for LockedPS2KeyBoardInode {
     }
 }
 
-#[allow(dead_code)]
-#[no_mangle]
-/// for test
-pub extern "C" fn ps2_keyboard_parse_keycode(input: u8) {
-    PS2_KEYBOARD_FSM.lock().parse(input);
+#[derive(Debug)]
+struct Ps2KeyboardIrqHandler;
+
+impl IrqHandler for Ps2KeyboardIrqHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dev_id: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        // 先检查状态寄存器,看看是否有数据
+        let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
+        let status = Ps2StatusRegister::from(status);
+        if !status.outbuf_full() {
+            return Ok(IrqReturn::NotHandled);
+        }
+
+        let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
+        // wait_ps2_keyboard_read();
+        PS2_KEYBOARD_FSM.lock().parse(input);
+
+        return Ok(IrqReturn::Handled);
+    }
+}
+
+impl Ps2KeyboardIrqHandler {
+    const INTR_HANDLE_FLAGS: IrqHandleFlags =
+        IrqHandleFlags::from_bits_truncate(IrqHandleFlags::IRQF_TRIGGER_RISING.bits());
+}
+
+/// 等待 PS/2 键盘的输入缓冲区为空
+fn wait_ps2_keyboard_write() {
+    let mut status: Ps2StatusRegister;
+    loop {
+        status = Ps2StatusRegister::from(unsafe {
+            CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into())
+        });
+        if !status.inbuf_full() {
+            break;
+        }
+
+        spin_loop();
+    }
+}
+#[unified_init(INITCALL_DEVICE)]
+fn ps2_keyboard_init() -> Result<(), SystemError> {
+    // ======== 初始化键盘控制器,写入配置值 =========
+    wait_ps2_keyboard_write();
+    unsafe {
+        CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_CONTROL.into(), PS2_KEYBOARD_COMMAND_WRITE);
+        wait_ps2_keyboard_write();
+        CurrentPortIOArch::out8(PORT_PS2_KEYBOARD_DATA.into(), PS2_KEYBOARD_PARAM_INIT);
+        wait_ps2_keyboard_write();
+    }
+
+    // 执行一百万次nop,等待键盘控制器把命令执行完毕
+    for _ in 0..1000000 {
+        spin_loop();
+    }
+
+    irq_manager()
+        .request_irq(
+            PS2_KEYBOARD_INTR_VECTOR,
+            "ps2keyboard".to_string(),
+            &Ps2KeyboardIrqHandler,
+            Ps2KeyboardIrqHandler::INTR_HANDLE_FLAGS,
+            None,
+        )
+        .expect("Failed to request irq for ps2 keyboard");
+
+    // 先读一下键盘的数据,防止由于在键盘初始化之前,由于按键被按下从而导致接收不到中断。
+    let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
+    let status = Ps2StatusRegister::from(status);
+    if status.outbuf_full() {
+        unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };
+    }
+
+    // 将设备挂载到devfs
+    ps2_keyboard_register();
+
+    Ok(())
 }

+ 0 - 10
kernel/src/driver/mouse/Makefile

@@ -1,10 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@

+ 0 - 58
kernel/src/driver/mouse/ps2_mouse.c

@@ -1,58 +0,0 @@
-#include "ps2_mouse.h"
-#include <arch/x86_64/driver/apic/apic.h>
-#include <mm/mm.h>
-#include <mm/slab.h>
-#include <common/printk.h>
-#include <common/kprint.h>
-
-extern void ps2_mouse_driver_interrupt();
-
-/**
- * @brief 鼠标中断处理函数(中断上半部)
- *  将数据存入缓冲区
- * @param irq_num 中断向量号
- * @param param 参数
- * @param regs 寄存器信息
- */
-void ps2_mouse_handler(ul irq_num, ul param, struct pt_regs *regs)
-{
-    ps2_mouse_driver_interrupt();
-}
-
-struct apic_IO_APIC_RTE_entry ps2_mouse_entry;
-
-hardware_intr_controller ps2_mouse_intr_controller =
-    {
-        .enable = apic_ioapic_enable,
-        .disable = apic_ioapic_disable,
-        .install = apic_ioapic_install,
-        .uninstall = apic_ioapic_uninstall,
-        .ack = apic_ioapic_edge_ack,
-
-};
-
-/**
- * @brief 初始化鼠标驱动程序
- *
- */
-void c_ps2_mouse_init()
-{
-    // ======== 初始化中断RTE entry ==========
-
-    ps2_mouse_entry.vector = PS2_MOUSE_INTR_VECTOR;   // 设置中断向量号
-    ps2_mouse_entry.deliver_mode = IO_APIC_FIXED; // 投递模式:混合
-    ps2_mouse_entry.dest_mode = DEST_PHYSICAL;    // 物理模式投递中断
-    ps2_mouse_entry.deliver_status = IDLE;
-    ps2_mouse_entry.trigger_mode = EDGE_TRIGGER; // 设置边沿触发
-    ps2_mouse_entry.polarity = POLARITY_HIGH;    // 高电平触发
-    ps2_mouse_entry.remote_IRR = IRR_RESET;
-    ps2_mouse_entry.mask = MASKED;
-    ps2_mouse_entry.reserved = 0;
-
-    ps2_mouse_entry.destination.physical.reserved1 = 0;
-    ps2_mouse_entry.destination.physical.reserved2 = 0;
-    ps2_mouse_entry.destination.physical.phy_dest = 0; // 设置投递到BSP处理器
-
-    // 注册中断处理程序
-    irq_register(PS2_MOUSE_INTR_VECTOR, &ps2_mouse_entry, &ps2_mouse_handler, 0, &ps2_mouse_intr_controller, "ps/2 mouse");
-}

+ 0 - 38
kernel/src/driver/mouse/ps2_mouse.h

@@ -1,38 +0,0 @@
-#pragma once
-
-#include <common/glib.h>
-
-#define PS2_MOUSE_INTR_VECTOR 0x2c // 鼠标的中断向量号
-
-#define KEYBOARD_COMMAND_SEND_TO_PS2_MOUSE 0xd4 // 键盘控制器向鼠标设备发送数据的命令
-
-#define PS2_MOUSE_GET_ID 0xf2                    // 获取鼠标的ID
-#define PS2_MOUSE_SET_SAMPLING_RATE 0xf3         // 设置鼠标的采样率
-#define PS2_MOUSE_ENABLE 0xf4                    // 允许鼠标设备发送数据包
-#define PS2_MOUSE_DISABLE 0xf5                   // 禁止鼠标设备发送数据包
-#define PS2_MOUSE_SET_DEFAULT_SAMPLING_RATE 0xf6 // 设置使用默认采样率100hz,分辨率4px/mm
-#define PS2_MOUSE_RESEND_LAST_PACKET 0xfe        // 重新发送上一条数据包
-#define PS2_MOUSE_RESET 0xff                     // 重启鼠标
-
-#define KEYBOARD_COMMAND_ENABLE_PS2_MOUSE_PORT 0xa8 // 通过键盘控制器开启鼠标端口的命令
-
-#define ps2_mouse_buffer_size 360
-
-#define PORT_KEYBOARD_DATA 0x60
-#define PORT_KEYBOARD_STATUS 0x64
-#define PORT_KEYBOARD_CONTROL 0x64
-
-#define KEYBOARD_COMMAND_WRITE 0x60 // 向键盘发送配置命令
-#define KEYBOARD_COMMAND_READ 0x20  // 读取键盘的配置值
-#define KEYBOARD_PARAM_INIT 0x47    // 初始化键盘控制器的配置值
-
-// ========= 检测键盘控制器输入/输出缓冲区是否已满
-#define KEYBOARD_FLAG_OUTBUF_FULL 0x01 // 键盘的输出缓冲区已满标志位
-#define KEYBOARD_FLAG_INBUF_FULL 0x02  // 键盘的输入缓冲区已满标志位
-
-
-/**
- * @brief 初始化鼠标驱动程序
- *
- */
-void c_ps2_mouse_init();

+ 21 - 15
kernel/src/driver/net/e1000e/e1000e.rs

@@ -1,6 +1,8 @@
 // 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
 // Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
 
+use alloc::string::ToString;
+use alloc::sync::Arc;
 use alloc::vec::Vec;
 use core::intrinsics::unlikely;
 use core::mem::size_of;
@@ -9,15 +11,18 @@ use core::slice::{from_raw_parts, from_raw_parts_mut};
 use core::sync::atomic::{compiler_fence, Ordering};
 
 use super::e1000e_driver::e1000e_driver_init;
+use crate::driver::base::device::DeviceId;
 use crate::driver::net::dma::{dma_alloc, dma_dealloc};
+use crate::driver::net::irq_handle::DefaultNetIrqHandler;
 use crate::driver::pci::pci::{
     get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
     PCI_DEVICE_LINKEDLIST,
 };
 use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
-use crate::include::bindings::bindings::pt_regs;
+use crate::exception::IrqNumber;
+
 use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly};
-use crate::net::net_core::poll_ifaces_try_lock_onetime;
+
 use crate::{kdebug, kinfo};
 
 const PAGE_SIZE: usize = 4096;
@@ -55,7 +60,7 @@ const E1000E_REG_SIZE: u8 = 4;
 const E1000E_DMA_PAGES: usize = 1;
 
 // 中断相关
-const E1000E_RECV_VECTOR: u16 = 57;
+const E1000E_RECV_VECTOR: IrqNumber = IrqNumber::new(57);
 
 // napi队列中暂时存储的buffer个数
 const E1000E_RECV_NAPI: usize = 1024;
@@ -157,12 +162,6 @@ impl E1000EBuffer {
     }
 }
 
-// 中断处理函数, 调用协议栈的poll函数,未来可能会用napi来替换这里
-// Interrupt handler
-unsafe extern "C" fn e1000e_irq_handler(_irq_num: u64, _irq_paramer: u64, _regs: *mut pt_regs) {
-    poll_ifaces_try_lock_onetime().ok();
-}
-
 #[allow(dead_code)]
 pub struct E1000EDevice {
     // 设备寄存器
@@ -201,7 +200,10 @@ impl E1000EDevice {
     // 从PCI标准设备进行驱动初始化
     // init the device for PCI standard device struct
     #[allow(unused_assignments)]
-    pub fn new(device: &mut PciDeviceStructureGeneralDevice) -> Result<Self, E1000EPciError> {
+    pub fn new(
+        device: &mut PciDeviceStructureGeneralDevice,
+        device_id: Arc<DeviceId>,
+    ) -> Result<Self, E1000EPciError> {
         // 从BAR0获取我们需要的寄存器
         // Build registers sturcts from BAR0
         device.bar_ioremap().unwrap()?;
@@ -230,10 +232,9 @@ impl E1000EDevice {
         let msg = PciIrqMsg {
             irq_common_message: IrqCommonMsg::init_from(
                 0,
-                "E1000E_RECV_IRQ",
-                0,
-                e1000e_irq_handler,
-                None,
+                "E1000E_RECV_IRQ".to_string(),
+                &DefaultNetIrqHandler,
+                device_id,
             ),
             irq_specific_message: IrqSpecificMsg::msi_default(),
         };
@@ -619,7 +620,12 @@ pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
                     "Detected e1000e PCI device with device id {:#x}",
                     header.device_id
                 );
-                let e1000e = E1000EDevice::new(standard_device)?;
+
+                // todo: 根据pci的path来生成device id
+                let e1000e = E1000EDevice::new(
+                    standard_device,
+                    DeviceId::new(None, Some(format!("e1000e_{}", header.device_id))).unwrap(),
+                )?;
                 e1000e_driver_init(e1000e);
             }
         }

+ 27 - 0
kernel/src/driver/net/irq_handle.rs

@@ -0,0 +1,27 @@
+use alloc::sync::Arc;
+use system_error::SystemError;
+
+use crate::{
+    exception::{
+        irqdata::IrqHandlerData,
+        irqdesc::{IrqHandler, IrqReturn},
+        IrqNumber,
+    },
+    net::net_core::poll_ifaces_try_lock_onetime,
+};
+
+/// 默认的网卡中断处理函数
+#[derive(Debug)]
+pub struct DefaultNetIrqHandler;
+
+impl IrqHandler for DefaultNetIrqHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        poll_ifaces_try_lock_onetime().ok();
+        Ok(IrqReturn::Handled)
+    }
+}

+ 1 - 0
kernel/src/driver/net/mod.rs

@@ -10,6 +10,7 @@ use system_error::SystemError;
 
 mod dma;
 pub mod e1000e;
+pub mod irq_handle;
 pub mod virtio_net;
 
 pub trait NetDriver: Driver {

+ 33 - 7
kernel/src/driver/net/virtio_net.rs

@@ -15,14 +15,15 @@ use super::NetDriver;
 use crate::{
     driver::{
         base::{
-            device::{bus::Bus, driver::Driver, Device, IdTable},
+            device::{bus::Bus, driver::Driver, Device, DeviceId, IdTable},
             kobject::{KObjType, KObject, KObjectState},
         },
-        virtio::virtio_impl::HalImpl,
+        virtio::{irq::virtio_irq_manager, virtio_impl::HalImpl, VirtIODevice},
     },
+    exception::{irqdesc::IrqReturn, IrqNumber},
     kerror, kinfo,
     libs::spinlock::SpinLock,
-    net::{generate_iface_id, NET_DRIVERS},
+    net::{generate_iface_id, net_core::poll_ifaces_try_lock_onetime, NET_DRIVERS},
     time::Instant,
 };
 use system_error::SystemError;
@@ -40,7 +41,8 @@ impl<T: Transport> Clone for VirtioNICDriver<T> {
     }
 }
 
-/// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
+/// 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
+///
 /// 由于smoltcp的设计,导致需要在poll的时候获取网卡驱动的可变引用,
 /// 同时需要在token的consume里面获取可变引用。为了避免双重加锁,所以需要这个包裹器。
 struct VirtioNICDriverWrapper<T: Transport>(UnsafeCell<VirtioNICDriver<T>>);
@@ -76,6 +78,7 @@ pub struct VirtioInterface<T: Transport> {
     iface_id: usize,
     iface: SpinLock<smoltcp::iface::Interface>,
     name: String,
+    dev_id: Arc<DeviceId>,
 }
 
 impl<T: Transport> Debug for VirtioInterface<T> {
@@ -90,7 +93,7 @@ impl<T: Transport> Debug for VirtioInterface<T> {
 }
 
 impl<T: Transport> VirtioInterface<T> {
-    pub fn new(mut driver: VirtioNICDriver<T>) -> Arc<Self> {
+    pub fn new(mut driver: VirtioNICDriver<T>, dev_id: Arc<DeviceId>) -> Arc<Self> {
         let iface_id = generate_iface_id();
         let mut iface_config = smoltcp::iface::Config::new();
 
@@ -109,12 +112,31 @@ impl<T: Transport> VirtioInterface<T> {
             iface_id,
             iface: SpinLock::new(iface),
             name: format!("eth{}", iface_id),
+            dev_id,
         });
 
         return result;
     }
 }
 
+impl<T: Transport + 'static> VirtIODevice for VirtioInterface<T> {
+    fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError> {
+        poll_ifaces_try_lock_onetime().ok();
+        return Ok(IrqReturn::Handled);
+    }
+
+    fn dev_id(&self) -> &Arc<DeviceId> {
+        return &self.dev_id;
+    }
+}
+
+impl<T: Transport> Drop for VirtioInterface<T> {
+    fn drop(&mut self) {
+        // 从全局的网卡接口信息表中删除这个网卡的接口信息
+        NET_DRIVERS.write_irqsave().remove(&self.iface_id);
+    }
+}
+
 impl<T: 'static + Transport> VirtioNICDriver<T> {
     pub fn new(driver_net: VirtIONet<HalImpl, T, 2>) -> Self {
         let mut iface_config = smoltcp::iface::Config::new();
@@ -223,7 +245,7 @@ impl<T: Transport> phy::RxToken for VirtioNetToken<T> {
 }
 
 /// @brief virtio-net 驱动的初始化与测试
-pub fn virtio_net<T: Transport + 'static>(transport: T) {
+pub fn virtio_net<T: Transport + 'static>(transport: T, dev_id: Arc<DeviceId>) {
     let driver_net: VirtIONet<HalImpl, T, 2> =
         match VirtIONet::<HalImpl, T, 2>::new(transport, 4096) {
             Ok(net) => net,
@@ -234,12 +256,16 @@ pub fn virtio_net<T: Transport + 'static>(transport: T) {
         };
     let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address());
     let driver: VirtioNICDriver<T> = VirtioNICDriver::new(driver_net);
-    let iface = VirtioInterface::new(driver);
+    let iface = VirtioInterface::new(driver, dev_id);
     let name = iface.name.clone();
     // 将网卡的接口信息注册到全局的网卡接口信息表中
     NET_DRIVERS
         .write_irqsave()
         .insert(iface.nic_id(), iface.clone());
+
+    virtio_irq_manager()
+        .register_device(iface.clone())
+        .expect("Register virtio net failed");
     kinfo!(
         "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]",
         name,

+ 0 - 11
kernel/src/driver/pci/Makefile

@@ -1,11 +0,0 @@
-SRC = $(wildcard *.c)
-OBJ = $(SRC:.c=.o)
-CFLAGS += -I .
-
-.PHONY: all
-
-all: $(OBJ)
-
-%.o: %.c
-	$(CC) $(CFLAGS) -c $< -o $@
-	

+ 7 - 6
kernel/src/driver/pci/pci.rs

@@ -3,6 +3,7 @@
 
 use super::pci_irq::{IrqType, PciIrqError};
 use crate::arch::{PciArch, TraitPciArch};
+use crate::exception::IrqNumber;
 use crate::include::bindings::bindings::PAGE_2M_SIZE;
 use crate::libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
 
@@ -371,7 +372,7 @@ pub trait PciDeviceStructure: Send + Sync {
     /// @brief 返回结构体中的irq_type的可变引用
     fn irq_type_mut(&mut self) -> Option<&mut IrqType>;
     /// @brief 返回结构体中的irq_vector的可变引用
-    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>>;
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>>;
 }
 
 /// Pci_Device_Structure_Header PCI设备结构体共有的头部
@@ -404,7 +405,7 @@ pub struct PciDeviceStructureGeneralDevice {
     // 中断结构体,包括legacy,msi,msix三种情况
     pub irq_type: IrqType,
     // 使用的中断号的vec集合
-    pub irq_vector: Vec<u16>,
+    pub irq_vector: Vec<IrqNumber>,
     pub standard_device_bar: PciStandardDeviceBar,
     pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。
     pub subsystem_vendor_id: u16,
@@ -464,7 +465,7 @@ impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
         Some(&mut self.irq_type)
     }
     #[inline(always)]
-    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
         Some(&mut self.irq_vector)
     }
 }
@@ -476,7 +477,7 @@ pub struct PciDeviceStructurePciToPciBridge {
     // 中断结构体,包括legacy,msi,msix三种情况
     pub irq_type: IrqType,
     // 使用的中断号的vec集合
-    pub irq_vector: Vec<u16>,
+    pub irq_vector: Vec<IrqNumber>,
     pub bar0: u32,
     pub bar1: u32,
     pub primary_bus_number: u8,
@@ -528,7 +529,7 @@ impl PciDeviceStructure for PciDeviceStructurePciToPciBridge {
         Some(&mut self.irq_type)
     }
     #[inline(always)]
-    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
         Some(&mut self.irq_vector)
     }
 }
@@ -587,7 +588,7 @@ impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
         None
     }
     #[inline(always)]
-    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
         None
     }
 }

+ 0 - 95
kernel/src/driver/pci/pci_irq.c

@@ -1,95 +0,0 @@
-#include "pci_irq.h"
-#include "exception/irq.h"
-#include <common/errno.h>
-#include <common/kprint.h>
-#include "common/string.h"
-#include "mm/slab.h"
-
-// 现在pci设备的中断由自己进行控制,这些不执行内容的函数是为了适配旧的中断处理机制
-void pci_irq_enable(ul irq_num)
-{
-}
-void pci_irq_disable(ul irq_num)
-{
-}
-ul pci_irq_install(ul num , void* data)
-{
-}
-void pci_irq_uninstall(ul irq_num)
-{
-}
-/// @brief 与本操作系统的中断机制进行交互,把中断处理函数等注册到中断结构体中(被rust调用)
-/// @param irq_num 要进行注册的中断号
-/// @param pci_irq_handler 对应的中断处理函数
-/// @param parameter 中断处理函数传入参数
-/// @param irq_name 中断名字
-/// @param pci_irq_ack 对于中断的回复,为NULL时会使用默认回应
-uint16_t c_irq_install(ul irq_num, void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul parameter, const char *irq_name, void (*pci_irq_ack)(ul irq_num))
-{
-    // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
-    irq_desc_t *p = NULL;
-    hardware_intr_controller *pci_interrupt_controller = NULL;
-    if (irq_num >= 32 && irq_num < 0x80)
-        p = &interrupt_desc[irq_num - 32];
-    else if (irq_num >= 150 && irq_num < 200)
-        p = &local_apic_interrupt_desc[irq_num - 150];
-    else
-    {
-        // kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
-        return EINVAL;
-    }
-    if (p->irq_name != NULL)
-    {
-        return EAGAIN;
-    }
-    pci_interrupt_controller = kzalloc(sizeof(hardware_intr_controller), 0);
-    if (pci_interrupt_controller)
-    {
-        pci_interrupt_controller->enable = pci_irq_enable;
-        pci_interrupt_controller->disable = pci_irq_disable;
-        pci_interrupt_controller->install = pci_irq_install;
-        pci_interrupt_controller->uninstall = pci_irq_uninstall;
-        pci_interrupt_controller->ack = pci_irq_ack;
-        p->controller = pci_interrupt_controller;
-    }
-    else
-    {
-        return EAGAIN;
-    }
-    size_t namelen = strlen(irq_name) + 1;
-    p->irq_name = (char *)kzalloc(namelen, 0);
-    memset(p->irq_name, 0, namelen);
-    strncpy(p->irq_name, irq_name, namelen);
-    p->parameter = parameter;
-    p->flags = 0;
-    p->handler = pci_irq_handler;
-    return 0;
-};
-
-/// @brief 与本操作系统的中断机制进行交互,把中断处理函数等从中断结构体中移除,需要释放空间的进行空间的释放
-/// @param irq_num 要进行注销的中断号
-void c_irq_uninstall(ul irq_num)
-{
-    // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
-    irq_desc_t *p = NULL;
-    if (irq_num >= 32 && irq_num < 0x80)
-        p = &interrupt_desc[irq_num - 32];
-    else if (irq_num >= 150 && irq_num < 200)
-        p = &local_apic_interrupt_desc[irq_num - 150];
-    else
-    {
-        kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
-    }
-    if (p->irq_name != NULL)
-    {
-        kfree(p->irq_name);
-        p->irq_name = NULL;
-    }
-    if (p->controller != NULL)
-    {
-        kfree(p->controller);
-        p->controller = NULL;
-    }
-    p->parameter = 0;
-    p->handler = NULL;
-}

+ 0 - 5
kernel/src/driver/pci/pci_irq.h

@@ -1,5 +0,0 @@
-#pragma once
-#include <common/glib.h>
-#include <process/ptrace.h>
-uint16_t c_irq_install(ul irq_num,void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs),ul parameter,const char *irq_name,void (*pci_irq_ack)(ul irq_num));
-void c_irq_uninstall(ul irq_num);

+ 89 - 54
kernel/src/driver/pci/pci_irq.rs

@@ -3,16 +3,19 @@
 use core::mem::size_of;
 use core::ptr::NonNull;
 
-use alloc::ffi::CString;
+use alloc::string::String;
+use alloc::sync::Arc;
 use alloc::vec::Vec;
+use system_error::SystemError;
 
 use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
 use crate::arch::msi::{arch_msi_message_address, arch_msi_message_data};
 use crate::arch::{PciArch, TraitPciArch};
-use crate::include::bindings::bindings::{
-    c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL,
-};
 
+use crate::driver::base::device::DeviceId;
+use crate::exception::irqdesc::{IrqHandleFlags, IrqHandler};
+use crate::exception::manage::irq_manager;
+use crate::exception::IrqNumber;
 use crate::libs::volatile::{volread, volwrite, Volatile};
 
 /// MSIX表的一项
@@ -37,8 +40,8 @@ pub enum PciIrqError {
     PciDeviceNotSupportIrq,
     IrqTypeUnmatch,
     InvalidIrqIndex(u16),
-    InvalidIrqNum(u16),
-    IrqNumOccupied(u16),
+    InvalidIrqNum(IrqNumber),
+    IrqNumOccupied(IrqNumber),
     DeviceIrqOverflow,
     MxiIrqNumWrong,
     PciBarNotInited,
@@ -78,29 +81,35 @@ pub struct PciIrqMsg {
 // PCI设备install中断时需要传递的共同参数
 #[derive(Clone, Debug)]
 pub struct IrqCommonMsg {
-    irq_index: u16,     //要install的中断号在PCI设备中的irq_vector的index
-    irq_name: CString,  //中断名字
-    irq_parameter: u16, //中断额外参数,可传入中断处理函数
-    irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
-    irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
+    irq_index: u16,                      //要install的中断号在PCI设备中的irq_vector的index
+    irq_name: String,                    //中断名字
+    irq_hander: &'static dyn IrqHandler, // 中断处理函数
+    /// 全局设备标志符
+    dev_id: Arc<DeviceId>,
 }
 
 impl IrqCommonMsg {
     pub fn init_from(
         irq_index: u16,
-        irq_name: &str,
-        irq_parameter: u16,
-        irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs),
-        irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>,
+        irq_name: String,
+        irq_hander: &'static dyn IrqHandler,
+        dev_id: Arc<DeviceId>,
     ) -> Self {
         IrqCommonMsg {
             irq_index,
-            irq_name: CString::new(irq_name).expect("CString::new failed"),
-            irq_parameter,
+            irq_name,
             irq_hander,
-            irq_ack,
+            dev_id,
         }
     }
+
+    pub fn set_handler(&mut self, irq_hander: &'static dyn IrqHandler) {
+        self.irq_hander = irq_hander;
+    }
+
+    pub fn dev_id(&self) -> &Arc<DeviceId> {
+        &self.dev_id
+    }
 }
 
 // PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX
@@ -347,28 +356,43 @@ pub trait PciInterrupt: PciDeviceStructure {
                     }
                     let irq_num =
                         self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
+
+                    let irq_num = IrqNumber::new(irq_num.into());
                     let common_msg = &msg.irq_common_message;
-                    let result = unsafe {
-                        c_irq_install(
-                            irq_num as u64,
-                            Some(common_msg.irq_hander),
-                            common_msg.irq_parameter as u64,
-                            common_msg.irq_name.as_ptr(),
-                            common_msg.irq_ack,
-                        )
-                    };
-                    match result as u32 {
-                        EINVAL => {
+
+                    let result = irq_manager().request_irq(
+                        irq_num,
+                        common_msg.irq_name.clone(),
+                        common_msg.irq_hander,
+                        IrqHandleFlags::empty(),
+                        Some(common_msg.dev_id.clone()),
+                    );
+
+                    match result {
+                        Ok(_) => {}
+                        Err(SystemError::EINVAL) => {
                             return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
                         }
-                        EAGAIN => {
+
+                        Err(SystemError::EAGAIN_OR_EWOULDBLOCK) => {
+                            return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
+                                irq_num,
+                            )));
+                        }
+
+                        Err(_) => {
+                            kerror!(
+                                "Failed to request pci irq {} for device {}",
+                                irq_num.data(),
+                                &common_msg.irq_name
+                            );
                             return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
                                 irq_num,
                             )));
                         }
-                        _ => {}
                     }
-                    //MSI中断只需配置一次PCI寄存器
+
+                    // MSI中断只需配置一次PCI寄存器
                     if common_msg.irq_index == 0 {
                         let msg_address = arch_msi_message_address(0);
                         let trigger = match msg.irq_specific_message {
@@ -377,8 +401,8 @@ pub trait PciInterrupt: PciDeviceStructure {
                             }
                             IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
                         };
-                        let msg_data = arch_msi_message_data(irq_num, 0, trigger);
-                        //写入Message Data和Message Address
+                        let msg_data = arch_msi_message_data(irq_num.data() as u16, 0, trigger);
+                        // 写入Message Data和Message Address
                         if address_64 {
                             PciArch::write_config(
                                 &self.common_header().bus_device_function,
@@ -496,26 +520,39 @@ pub trait PciInterrupt: PciDeviceStructure {
                     }
                     let irq_num =
                         self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
+
                     let common_msg = &msg.irq_common_message;
-                    let result = unsafe {
-                        c_irq_install(
-                            irq_num as u64,
-                            Some(common_msg.irq_hander),
-                            common_msg.irq_parameter as u64,
-                            common_msg.irq_name.as_ptr(),
-                            common_msg.irq_ack,
-                        )
-                    };
-                    match result as u32 {
-                        EINVAL => {
+
+                    let result = irq_manager().request_irq(
+                        irq_num,
+                        common_msg.irq_name.clone(),
+                        common_msg.irq_hander,
+                        IrqHandleFlags::empty(),
+                        Some(common_msg.dev_id.clone()),
+                    );
+
+                    match result {
+                        Ok(_) => {}
+                        Err(SystemError::EINVAL) => {
                             return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
                         }
-                        EAGAIN => {
+
+                        Err(SystemError::EAGAIN_OR_EWOULDBLOCK) => {
+                            return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
+                                irq_num,
+                            )));
+                        }
+
+                        Err(_) => {
+                            kerror!(
+                                "Failed to request pci irq {} for device {}",
+                                irq_num.data(),
+                                &common_msg.irq_name
+                            );
                             return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
                                 irq_num,
                             )));
                         }
-                        _ => {}
                     }
 
                     let msg_address = arch_msi_message_address(0);
@@ -525,7 +562,7 @@ pub trait PciInterrupt: PciDeviceStructure {
                         }
                         IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
                     };
-                    let msg_data = arch_msi_message_data(irq_num, 0, trigger);
+                    let msg_data = arch_msi_message_data(irq_num.data() as u16, 0, trigger);
                     //写入Message Data和Message Address
                     let pcistandardbar = self
                         .bar()
@@ -589,9 +626,8 @@ pub trait PciInterrupt: PciDeviceStructure {
                     ..
                 } => {
                     for vector in self.irq_vector_mut().unwrap() {
-                        unsafe {
-                            c_irq_uninstall(vector.clone() as u64);
-                        }
+                        let irq = IrqNumber::new((*vector).into());
+                        irq_manager().free_irq(irq, None);
                     }
                     PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
                     PciArch::write_config(
@@ -636,9 +672,8 @@ pub trait PciInterrupt: PciDeviceStructure {
                     ..
                 } => {
                     for vector in self.irq_vector_mut().unwrap() {
-                        unsafe {
-                            c_irq_uninstall(vector.clone() as u64);
-                        }
+                        let irq = IrqNumber::new((*vector).into());
+                        irq_manager().free_irq(irq, None);
                     }
                     PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
                     let pcistandardbar = self

+ 85 - 0
kernel/src/driver/virtio/irq.rs

@@ -0,0 +1,85 @@
+use alloc::sync::Arc;
+use hashbrown::HashMap;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{driver::base::device::DeviceId, init::initcall::INITCALL_CORE, libs::rwlock::RwLock};
+
+use super::VirtIODevice;
+
+static mut VIRTIO_IRQ_MANAGER: Option<VirtIOIrqManager> = None;
+
+#[inline(always)]
+pub fn virtio_irq_manager() -> &'static VirtIOIrqManager {
+    unsafe { VIRTIO_IRQ_MANAGER.as_ref().unwrap() }
+}
+
+pub struct VirtIOIrqManager {
+    map: RwLock<HashMap<Arc<DeviceId>, Arc<dyn VirtIODevice>>>,
+}
+
+impl VirtIOIrqManager {
+    fn new() -> Self {
+        VirtIOIrqManager {
+            map: RwLock::new(HashMap::new()),
+        }
+    }
+
+    /// 注册一个新的设备到virtio中断请求(IRQ)映射中。
+    ///
+    /// # 参数
+    ///
+    /// - `device` - 实现了 `VirtIODevice` trait 的设备对象,被封装在 `Arc` 智能指针中。
+    ///
+    /// # 返回值
+    ///
+    /// - 如果设备成功注册,返回 `Ok(())`。
+    /// - 如果设备ID已经存在于映射中,返回 `Err(SystemError::EEXIST)`。
+    pub fn register_device(&self, device: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
+        let mut map = self.map.write_irqsave();
+
+        if map.contains_key(device.dev_id()) {
+            return Err(SystemError::EEXIST);
+        }
+
+        map.insert(device.dev_id().clone(), device);
+
+        return Ok(());
+    }
+
+    /// 取消注册设备
+    ///
+    /// 这个函数会从内部映射中移除指定的设备。设备是通过设备ID来识别的。
+    ///
+    /// # 参数
+    ///
+    /// - `device` - 需要被取消注册的设备,它是一个实现了 `VirtIODevice` trait 的智能指针。
+    #[allow(dead_code)]
+    pub fn unregister_device(&self, dev_id: &Arc<DeviceId>) {
+        let mut map = self.map.write_irqsave();
+        map.remove(dev_id);
+    }
+
+    /// 查找并返回指定设备ID的设备。
+    ///
+    /// # 参数
+    /// - `dev_id` - 我们要查找的设备的设备ID。
+    ///
+    /// # 返回
+    /// - 如果找到了设备,返回一个包含设备的`Option<Arc<dyn VirtIODevice>>`。
+    /// - 如果没有找到设备,返回`None`。
+
+    pub fn lookup_device(&self, dev_id: &Arc<DeviceId>) -> Option<Arc<dyn VirtIODevice>> {
+        let map = self.map.read_irqsave();
+        map.get(dev_id).map(|x| x.clone())
+    }
+}
+
+#[unified_init(INITCALL_CORE)]
+fn init_virtio_irq_manager() -> Result<(), SystemError> {
+    let manager = VirtIOIrqManager::new();
+    unsafe {
+        VIRTIO_IRQ_MANAGER = Some(manager);
+    }
+    return Ok(());
+}

+ 16 - 0
kernel/src/driver/virtio/mod.rs

@@ -1,3 +1,19 @@
+use core::any::Any;
+
+use alloc::sync::Arc;
+use system_error::SystemError;
+
+use crate::exception::{irqdesc::IrqReturn, IrqNumber};
+
+use super::base::device::DeviceId;
+
+pub(super) mod irq;
 pub mod transport_pci;
 pub mod virtio;
 pub mod virtio_impl;
+
+pub trait VirtIODevice: Send + Sync + Any {
+    fn handle_irq(&self, _irq: IrqNumber) -> Result<IrqReturn, SystemError>;
+
+    fn dev_id(&self) -> &Arc<DeviceId>;
+}

+ 63 - 14
kernel/src/driver/virtio/transport_pci.rs

@@ -1,22 +1,31 @@
 //! PCI transport for VirtIO.
 use crate::arch::{PciArch, TraitPciArch};
+use crate::driver::base::device::DeviceId;
 use crate::driver::pci::pci::{
     BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
     PciStandardDeviceBar, PCI_CAP_ID_VNDR,
 };
 
 use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
-use crate::include::bindings::bindings::pt_regs;
+use crate::driver::virtio::irq::virtio_irq_manager;
+use crate::exception::irqdata::IrqHandlerData;
+use crate::exception::irqdesc::{IrqHandler, IrqReturn};
+
+use crate::exception::IrqNumber;
+
 use crate::libs::volatile::{
     volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
 };
 use crate::mm::VirtAddr;
-use crate::net::net_core::poll_ifaces_try_lock_onetime;
+
+use alloc::string::ToString;
+use alloc::sync::Arc;
 use core::{
     fmt::{self, Display, Formatter},
     mem::{align_of, size_of},
     ptr::{self, addr_of_mut, NonNull},
 };
+use system_error::SystemError;
 use virtio_drivers::{
     transport::{DeviceStatus, DeviceType, Transport},
     Error, Hal, PhysAddr,
@@ -57,7 +66,7 @@ const VIRTIO_PCI_CAP_ISR_CFG: u8 = 3;
 const VIRTIO_PCI_CAP_DEVICE_CFG: u8 = 4;
 
 /// Virtio设备接收中断的设备号
-const VIRTIO_RECV_VECTOR: u16 = 56;
+const VIRTIO_RECV_VECTOR: IrqNumber = IrqNumber::new(56);
 /// Virtio设备接收中断的设备号的表项号
 const VIRTIO_RECV_VECTOR_INDEX: u16 = 0;
 // 接收的queue号
@@ -82,6 +91,7 @@ fn device_type(pci_device_id: u16) -> DeviceType {
 /// PCI transport for VirtIO.
 ///
 /// Ref: 4.1 Virtio Over PCI Bus
+#[allow(dead_code)]
 #[derive(Debug, Clone)]
 pub struct PciTransport {
     device_type: DeviceType,
@@ -96,21 +106,24 @@ pub struct PciTransport {
     isr_status: NonNull<Volatile<u8>>,
     /// The VirtIO device-specific configuration within some BAR.
     config_space: Option<NonNull<[u32]>>,
-}
-
-unsafe extern "C" fn virtio_irq_hander(_irq_num: u64, _irq_paramer: u64, _regs: *mut pt_regs) {
-    // kdebug!("12345");
-    poll_ifaces_try_lock_onetime().ok();
+    irq: IrqNumber,
+    dev_id: Arc<DeviceId>,
 }
 
 impl PciTransport {
     /// Construct a new PCI VirtIO device driver for the given device function on the given PCI
     /// root controller.
     ///
+    /// ## 参数
     ///
+    /// - `device` - The PCI device structure for the VirtIO device.
+    /// - `irq_handler` - An optional handler for the device's interrupt. If `None`, a default
+    ///     handler `DefaultVirtioIrqHandler` will be used.
     pub fn new<H: Hal>(
         device: &mut PciDeviceStructureGeneralDevice,
+        dev_id: Arc<DeviceId>,
     ) -> Result<Self, VirtioPciError> {
+        let irq = VIRTIO_RECV_VECTOR;
         let header = &device.common_header;
         let bus_device_function = header.bus_device_function;
         if header.vendor_id != VIRTIO_VENDOR_ID {
@@ -128,7 +141,7 @@ impl PciTransport {
         let standard_device = device.as_standard_device_mut().unwrap();
         // 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
         let irq_vector = standard_device.irq_vector_mut().unwrap();
-        irq_vector.push(VIRTIO_RECV_VECTOR);
+        irq_vector.push(irq);
         standard_device
             .irq_init(IRQ::PCI_IRQ_MSIX)
             .expect("IRQ init failed");
@@ -136,10 +149,9 @@ impl PciTransport {
         let msg = PciIrqMsg {
             irq_common_message: IrqCommonMsg::init_from(
                 0,
-                "Virtio_Recv_IRQ",
-                0,
-                virtio_irq_hander,
-                None,
+                "Virtio_IRQ".to_string(),
+                &DefaultVirtioIrqHandler,
+                dev_id.clone(),
             ),
             irq_specific_message: IrqSpecificMsg::msi_default(),
         };
@@ -222,6 +234,8 @@ impl PciTransport {
             notify_off_multiplier,
             isr_status,
             config_space,
+            irq,
+            dev_id,
         })
     }
 }
@@ -374,7 +388,9 @@ impl Transport for PciTransport {
 impl Drop for PciTransport {
     fn drop(&mut self) {
         // Reset the device when the transport is dropped.
-        self.set_status(DeviceStatus::empty())
+        self.set_status(DeviceStatus::empty());
+
+        // todo: 调用pci的中断释放函数,并且在virtio_irq_manager里面删除对应的设备的中断
     }
 }
 
@@ -544,3 +560,36 @@ fn get_bar_region_slice<T>(
 fn nonnull_slice_from_raw_parts<T>(data: NonNull<T>, len: usize) -> NonNull<[T]> {
     NonNull::new(ptr::slice_from_raw_parts_mut(data.as_ptr(), len)).unwrap()
 }
+
+/// `DefaultVirtioIrqHandler` 是一个默认的virtio设备中断处理程序。
+///
+/// 当虚拟设备产生中断时,该处理程序会被调用。
+///
+/// 它首先检查设备ID是否存在,然后尝试查找与设备ID关联的设备。
+/// 如果找到设备,它会调用设备的 `handle_irq` 方法来处理中断。
+/// 如果没有找到设备,它会记录一条警告并返回 `IrqReturn::NotHandled`,表示中断未被处理。
+#[derive(Debug)]
+struct DefaultVirtioIrqHandler;
+
+impl IrqHandler for DefaultVirtioIrqHandler {
+    fn handle(
+        &self,
+        irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        dev_id: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        let dev_id = dev_id.ok_or(SystemError::EINVAL)?;
+        let dev_id = dev_id
+            .arc_any()
+            .downcast::<DeviceId>()
+            .map_err(|_| SystemError::EINVAL)?;
+
+        if let Some(dev) = virtio_irq_manager().lookup_device(&dev_id) {
+            return dev.handle_irq(irq);
+        } else {
+            // 未绑定具体设备,因此无法处理中断
+
+            return Ok(IrqReturn::NotHandled);
+        }
+    }
+}

+ 8 - 4
kernel/src/driver/virtio/virtio.rs

@@ -1,5 +1,6 @@
 use super::transport_pci::PciTransport;
 use super::virtio_impl::HalImpl;
+use crate::driver::base::device::DeviceId;
 use crate::driver::net::virtio_net::virtio_net;
 use crate::driver::pci::pci::{
     get_pci_device_structure_mut, PciDeviceStructure, PciDeviceStructureGeneralDevice,
@@ -7,6 +8,7 @@ use crate::driver::pci::pci::{
 };
 use crate::libs::rwlock::RwLockWriteGuard;
 use crate::{kdebug, kerror, kwarn};
+use alloc::sync::Arc;
 use alloc::{boxed::Box, collections::LinkedList};
 use virtio_drivers::transport::{DeviceType, Transport};
 const NETWORK_CLASS: u8 = 0x2;
@@ -23,14 +25,16 @@ pub fn virtio_probe() {
     let mut list = PCI_DEVICE_LINKEDLIST.write();
     if let Ok(virtio_list) = virtio_device_search(&mut list) {
         for virtio_device in virtio_list {
-            match PciTransport::new::<HalImpl>(virtio_device) {
+            let dev_id = virtio_device.common_header.device_id;
+            let dev_id = DeviceId::new(None, Some(format!("virtio_{}", dev_id))).unwrap();
+            match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) {
                 Ok(mut transport) => {
                     kdebug!(
                         "Detected virtio PCI device with device type {:?}, features {:#018x}",
                         transport.device_type(),
                         transport.read_device_features(),
                     );
-                    virtio_device_init(transport);
+                    virtio_device_init(transport, dev_id);
                 }
                 Err(err) => {
                     kerror!("Pci transport create failed because of error: {}", err);
@@ -43,7 +47,7 @@ pub fn virtio_probe() {
 }
 
 ///@brief 为virtio设备寻找对应的驱动进行初始化
-fn virtio_device_init(transport: impl Transport + 'static) {
+fn virtio_device_init(transport: impl Transport + 'static, dev_id: Arc<DeviceId>) {
     match transport.device_type() {
         DeviceType::Block => {
             kwarn!("Not support virtio_block device for now");
@@ -54,7 +58,7 @@ fn virtio_device_init(transport: impl Transport + 'static) {
         DeviceType::Input => {
             kwarn!("Not support virtio_input device for now");
         }
-        DeviceType::Network => virtio_net(transport),
+        DeviceType::Network => virtio_net(transport, dev_id),
         t => {
             kwarn!("Unrecognized virtio device: {:?}", t);
         }

+ 0 - 8
kernel/src/exception/Makefile

@@ -1,8 +0,0 @@
-
-CFLAGS += -I .
-
-
-all: irq.o
-
-irq.o: irq.c
-	$(CC) $(CFLAGS) -c irq.c -o irq.o

+ 25 - 3
kernel/src/exception/dummychip.rs

@@ -41,10 +41,23 @@ impl IrqChip for NoIrqChip {
     fn name(&self) -> &'static str {
         "none"
     }
+
+    fn can_mask_ack(&self) -> bool {
+        false
+    }
+
     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
         Ok(())
     }
 
+    fn can_set_affinity(&self) -> bool {
+        false
+    }
+
+    fn can_set_flow_type(&self) -> bool {
+        false
+    }
+
     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
 
     fn irq_ack(&self, irq: &Arc<IrqData>) {
@@ -78,17 +91,26 @@ impl IrqChip for DummyIrqChip {
         "dummy"
     }
 
+    fn can_mask_ack(&self) -> bool {
+        false
+    }
+
     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
         Ok(())
     }
 
+    fn can_set_flow_type(&self) -> bool {
+        false
+    }
+
+    fn can_set_affinity(&self) -> bool {
+        false
+    }
+
     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
 
     fn irq_ack(&self, _irq: &Arc<IrqData>) {}
 
-    fn irq_mask(&self, _irq: &Arc<IrqData>) {}
-    fn irq_unmask(&self, _irq: &Arc<IrqData>) {}
-
     fn irq_startup(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
         Ok(())
     }

+ 221 - 4
kernel/src/exception/handle.rs

@@ -1,10 +1,22 @@
+use core::{intrinsics::unlikely, ops::BitAnd};
+
 use alloc::sync::Arc;
+use system_error::SystemError;
 
-use crate::arch::CurrentIrqArch;
+use crate::{
+    arch::{interrupt::TrapFrame, CurrentIrqArch},
+    exception::irqdesc::InnerIrqDesc,
+    libs::spinlock::SpinLockGuard,
+    process::{ProcessFlags, ProcessManager},
+};
 
 use super::{
-    irqdesc::{IrqDesc, IrqFlowHandler},
-    InterruptArch,
+    irqdata::{IrqData, IrqHandlerData, IrqStatus},
+    irqdesc::{
+        InnerIrqAction, IrqDesc, IrqDescState, IrqFlowHandler, IrqReturn, ThreadedHandlerFlags,
+    },
+    manage::{irq_manager, IrqManager},
+    InterruptArch, IrqNumber,
 };
 
 /// 获取用于处理错误的中断的处理程序
@@ -13,15 +25,220 @@ pub fn bad_irq_handler() -> &'static dyn IrqFlowHandler {
     &HandleBadIrq
 }
 
+/// 获取用于处理快速EOI的中断的处理程序
+#[inline(always)]
+pub fn fast_eoi_irq_handler() -> &'static dyn IrqFlowHandler {
+    &FastEOIIrqHandler
+}
+
+/// 获取用于处理边沿触发中断的处理程序
+#[inline(always)]
+pub fn edge_irq_handler() -> &'static dyn IrqFlowHandler {
+    &EdgeIrqHandler
+}
+
 /// handle spurious and unhandled irqs
 #[derive(Debug)]
 struct HandleBadIrq;
 
 impl IrqFlowHandler for HandleBadIrq {
     /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/handle.c?fi=handle_bad_irq#33
-    fn handle(&self, irq_desc: &Arc<IrqDesc>) {
+    fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
         // todo: print_irq_desc
         // todo: 增加kstat计数
         CurrentIrqArch::ack_bad_irq(irq_desc.irq());
     }
 }
+
+#[derive(Debug)]
+struct FastEOIIrqHandler;
+
+impl IrqFlowHandler for FastEOIIrqHandler {
+    fn handle(&self, _irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
+        // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/chip.c?r=&mo=17578&fi=689#689
+        todo!("FastEOIIrqHandler");
+    }
+}
+
+#[derive(Debug)]
+struct EdgeIrqHandler;
+
+impl IrqFlowHandler for EdgeIrqHandler {
+    // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/chip.c?fi=handle_edge_irq#775
+    fn handle(&self, irq_desc: &Arc<IrqDesc>, _trap_frame: &mut TrapFrame) {
+        let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = irq_desc.inner();
+        if !irq_may_run(&desc_inner_guard) {
+            // kdebug!("!irq_may_run");
+            desc_inner_guard
+                .internal_state_mut()
+                .insert(IrqDescState::IRQS_PENDING);
+            mask_ack_irq(desc_inner_guard.irq_data());
+            return;
+        }
+
+        if desc_inner_guard.common_data().disabled() {
+            // kdebug!("desc_inner_guard.common_data().disabled()");
+            desc_inner_guard
+                .internal_state_mut()
+                .insert(IrqDescState::IRQS_PENDING);
+            mask_ack_irq(desc_inner_guard.irq_data());
+            return;
+        }
+
+        let irq_data = desc_inner_guard.irq_data().clone();
+
+        irq_data.chip_info_read_irqsave().chip().irq_ack(&irq_data);
+
+        loop {
+            if unlikely(desc_inner_guard.actions().is_empty()) {
+                kdebug!("no action for irq {}", irq_data.irq().data());
+                irq_manager().mask_irq(&irq_data);
+                return;
+            }
+
+            // 当我们在处理一个中断时,如果另一个中断到来,我们本可以屏蔽它.
+            // 如果在此期间没有被禁用,请重新启用它。
+            if desc_inner_guard
+                .internal_state()
+                .contains(IrqDescState::IRQS_PENDING)
+            {
+                let status = desc_inner_guard.common_data().status();
+                if status.disabled() == false && status.masked() {
+                    // kdebug!("re-enable irq");
+                    irq_manager().unmask_irq(&desc_inner_guard);
+                }
+            }
+
+            // kdebug!("handle_irq_event");
+
+            desc_inner_guard
+                .internal_state_mut()
+                .remove(IrqDescState::IRQS_PENDING);
+            desc_inner_guard.common_data().set_inprogress();
+
+            drop(desc_inner_guard);
+
+            let _r = do_handle_irq_event(irq_desc);
+
+            desc_inner_guard = irq_desc.inner();
+            desc_inner_guard.common_data().clear_inprogress();
+
+            if !(desc_inner_guard
+                .internal_state()
+                .contains(IrqDescState::IRQS_PENDING)
+                && desc_inner_guard.common_data().disabled() == false)
+            {
+                break;
+            }
+        }
+    }
+}
+
+/// 判断中断是否可以运行
+fn irq_may_run(desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) -> bool {
+    let mask = IrqStatus::IRQD_IRQ_INPROGRESS | IrqStatus::IRQD_WAKEUP_ARMED;
+    let status = desc_inner_guard.common_data().status();
+
+    // 如果中断不在处理中并且没有被唤醒,则可以运行
+    if status.bitand(mask).is_empty() {
+        return true;
+    }
+
+    // todo: 检查其他处理器是否在轮询当前中断
+    return false;
+}
+
+fn mask_ack_irq(irq_data: &Arc<IrqData>) {
+    let chip = irq_data.chip_info_read_irqsave().chip();
+    if chip.can_mask_ack() {
+        chip.irq_mask_ack(&irq_data);
+        irq_data.common_data().set_masked();
+    } else {
+        irq_manager().mask_irq(irq_data);
+        chip.irq_ack(&irq_data);
+    }
+}
+
+impl IrqManager {
+    pub(super) fn do_irq_wake_thread(
+        &self,
+        desc: &Arc<IrqDesc>,
+        action_inner: &mut SpinLockGuard<'_, InnerIrqAction>,
+    ) {
+        let thread = action_inner.thread();
+
+        if thread.is_none() {
+            return;
+        }
+
+        let thread = thread.unwrap();
+        if thread.flags().contains(ProcessFlags::EXITING) {
+            return;
+        }
+
+        // 如果线程已经在运行,我们不需要唤醒它
+        if action_inner
+            .thread_flags_mut()
+            .test_and_set_bit(ThreadedHandlerFlags::IRQTF_RUNTHREAD)
+        {
+            return;
+        }
+
+        desc.inc_threads_active();
+
+        ProcessManager::wakeup(&thread).ok();
+    }
+}
+
+/// 处理中断事件
+///
+/// https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/handle.c?fi=handle_irq_event#139
+#[inline(never)]
+fn do_handle_irq_event(desc: &Arc<IrqDesc>) -> Result<(), SystemError> {
+    let desc_inner_guard = desc.inner();
+    let irq_data = desc_inner_guard.irq_data().clone();
+    let actions = desc_inner_guard.actions().clone();
+    drop(desc_inner_guard);
+
+    let irq = irq_data.irq();
+    let mut r = Ok(IrqReturn::NotHandled);
+
+    for action in actions {
+        let mut action_inner: SpinLockGuard<'_, InnerIrqAction> = action.inner();
+        // kdebug!("do_handle_irq_event: action: {:?}", action_inner.name());
+        let dynamic_data = action_inner
+            .dev_id()
+            .clone()
+            .map(|d| d as Arc<dyn IrqHandlerData>);
+        r = action_inner
+            .handler()
+            .unwrap()
+            .handle(irq, None, dynamic_data);
+
+        if let Ok(IrqReturn::WakeThread) = r {
+            if unlikely(action_inner.thread_fn().is_none()) {
+                warn_no_thread(irq, &mut action_inner);
+            } else {
+                irq_manager().do_irq_wake_thread(desc, &mut action_inner);
+            }
+        };
+    }
+
+    return r.map(|_| ());
+}
+
+fn warn_no_thread(irq: IrqNumber, action_inner: &mut SpinLockGuard<'_, InnerIrqAction>) {
+    // warn on once
+    if action_inner
+        .thread_flags_mut()
+        .test_and_set_bit(ThreadedHandlerFlags::IRQTF_WARNED)
+    {
+        return;
+    }
+
+    kwarn!(
+        "irq {}, device {} returned IRQ_WAKE_THREAD, but no threaded handler",
+        irq.data(),
+        action_inner.name()
+    );
+}

+ 5 - 1
kernel/src/exception/init.rs

@@ -2,7 +2,10 @@ use system_error::SystemError;
 
 use crate::arch::CurrentIrqArch;
 
-use super::{dummychip::dummy_chip_init, irqdesc::early_irq_init, InterruptArch};
+use super::{
+    dummychip::dummy_chip_init, irqdesc::early_irq_init, irqdomain::irq_domain_manager_init,
+    InterruptArch,
+};
 
 /// 初始化中断
 #[inline(never)]
@@ -10,6 +13,7 @@ pub fn irq_init() -> Result<(), SystemError> {
     // todo: 通用初始化
 
     dummy_chip_init();
+    irq_domain_manager_init();
     early_irq_init().expect("early_irq_init failed");
 
     // 初始化架构相关的中断

+ 51 - 2
kernel/src/exception/ipi.rs

@@ -1,9 +1,25 @@
+use alloc::sync::Arc;
+use system_error::SystemError;
+
+use crate::{
+    arch::{sched::sched, MMArch},
+    mm::MemoryManagementArch,
+    smp::cpu::ProcessorId,
+};
+
+use super::{
+    irqdata::IrqHandlerData,
+    irqdesc::{IrqHandler, IrqReturn},
+    HardwareIrqNumber, IrqNumber,
+};
+
 #[allow(dead_code)]
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
-#[repr(u8)]
 pub enum IpiKind {
     KickCpu,
     FlushTLB,
+    /// 指定中断向量号
+    SpecVector(HardwareIrqNumber),
 }
 
 /// IPI投递目标
@@ -17,5 +33,38 @@ pub enum IpiTarget {
     /// 除了当前CPU以外的所有CPU
     Other,
     /// 指定的CPU
-    Specified(usize),
+    Specified(ProcessorId),
+}
+
+/// 处理跨核心CPU唤醒的IPI
+#[derive(Debug)]
+pub struct KickCpuIpiHandler;
+
+impl IrqHandler for KickCpuIpiHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        sched();
+        Ok(IrqReturn::Handled)
+    }
+}
+
+/// 处理TLB刷新的IPI
+#[derive(Debug)]
+pub struct FlushTLBIpiHandler;
+
+impl IrqHandler for FlushTLBIpiHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        unsafe { MMArch::invalidate_all() };
+
+        Ok(IrqReturn::Handled)
+    }
 }

+ 0 - 84
kernel/src/exception/irq.c

@@ -1,84 +0,0 @@
-
-#include "irq.h"
-#include <common/errno.h>
-
-
-#include <common/asm.h>
-#include <common/printk.h>
-#include <common/string.h>
-#include <mm/slab.h>
-#include <arch/arch.h>
-
-#pragma GCC push_options
-#pragma GCC optimize("O0")
-
-/**
- * @brief 中断注册函数
- *
- * @param irq_num 中断向量号
- * @param arg 传递给中断安装接口的参数
- * @param handler 中断处理函数
- * @param paramater 中断处理函数的参数
- * @param controller 中断控制器结构
- * @param irq_name 中断名
- * @return int
- */
-int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater,
-                 hardware_intr_controller *controller, char *irq_name)
-{
-    // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
-    irq_desc_t *p = NULL;
-    if (irq_num >= 32 && irq_num < 0x80)
-        p = &interrupt_desc[irq_num - 32];
-    else if (irq_num >= 150 && irq_num < 200)
-        p = &local_apic_interrupt_desc[irq_num - 150];
-    else
-    {
-        kerror("irq_register(): invalid irq num: %ld.", irq_num);
-        return -EINVAL;
-    }
-    p->controller = controller;
-    if (p->irq_name == NULL)
-    {
-        int namelen = sizeof(strlen(irq_name) + 1);
-        p->irq_name = (char *)kmalloc(namelen, 0);
-        memset(p->irq_name, 0, namelen);
-        strncpy(p->irq_name, irq_name, namelen);
-    }
-
-    p->parameter = paramater;
-    p->flags = 0;
-    p->handler = handler;
-    io_mfence();
-    p->controller->install(irq_num, arg);
-    io_mfence();
-    p->controller->enable(irq_num);
-    io_mfence();
-
-    return 0;
-}
-
-/**
- * @brief 中断注销函数
- *
- * @param irq_num 中断向量号
- * @return int
- */
-int irq_unregister(ul irq_num)
-{
-    irq_desc_t *p = &interrupt_desc[irq_num - 32];
-    p->controller->disable(irq_num);
-    p->controller->uninstall(irq_num);
-
-    p->controller = NULL;
-    if (p->irq_name)
-        kfree(p->irq_name);
-    p->irq_name = NULL;
-    p->parameter = (ul)NULL;
-    p->flags = 0;
-    p->handler = NULL;
-
-    return 0;
-}
-
-#pragma GCC optimize("O0")

+ 0 - 175
kernel/src/exception/irq.h

@@ -1,175 +0,0 @@
-/**
- * @file irq.h
- * @author longjin
- * @brief 中断处理程序
- * @version 0.1
- * @date 2022-01-28
- *
- * @copyright Copyright (c) 2022
- *
- */
-
-#pragma once
-#include <common/glib.h>
-
-#include <process/ptrace.h>
-#pragma GCC push_options
-#pragma GCC optimize ("O0")
-
-#define IRQ_NUM 26
-#define SMP_IRQ_NUM 10
-#define LOCAL_APIC_IRQ_NUM 50
-
-extern void (*interrupt_table[IRQ_NUM])(void);
-extern void do_IRQ(struct pt_regs *regs, ul number);
-
-
-extern void (*SMP_interrupt_table[SMP_IRQ_NUM])(void);
-
-extern void (*syscall_intr_table[1])(void);
-extern void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void);
-
-/* ========= 中断向量分配表 ==========
-
-0~255 IDT
-
-0   ~   31	trap fault abort for system
-	0	devide error
-	1	debug
-	2	NMI
-	3	breakpoint
-	4	overflow
-	5	bound range
-	6	undefined opcode
-	7	device	not available
-	8	double fault
-	9	coprocessor segment overrun
-	10	invalid TSS
-	11	segment not present
-	12	stack segment fault
-	13	general protection
-	14	page fault
-	15	
-	16	x87 FPU error
-	17	alignment check
-	18	machine check
-	19	SIMD exception
-	20	virtualization exception
-21  ~   31	Do not use
-
-32  ~   55	I/O APIC
-	32	8259A
-	33	keyboard
-	34	HPET timer 0,8254 counter 0
-	35	serial port A
-	36	serial port B
-	37	parallel port
-	38	floppy
-	39	parallel port
-	40	RTC,HPET timer 1
-	41	Generic
-	42	Generic
-	43	HPET timer 2
-	44	HPET timer 3	/ mouse
-	45	FERR#
-	46	SATA primary
-	47	SATA secondary
-	48	PIRQA
-	49	PIRQB
-	50	PIRQC
-	51	PIRQD
-	52	PIRQE
-	53	PIRQF
-	54	PIRQG
-	55	PIRQH
-	56  VIRTIO_RECV
-	57  E1000E_RECV
-	
-	
-0x80		system call
-0x81		system interrupt 系统中断
-
-[150,200)	Local APIC
-	150	CMCI
-	151	Timer
-	152	Thermal Monitor
-	153	Performance Counter
-	154	LINT0
-	155	LINT1
-	156	Error
-	157 xhci_controller_0
-	158 xhci_controller_1
-	159 xhci_controller_2
-	160 xhci_controller_3
-
-200 ~   255	MP IPI
-
-	200 kick cpu 功能(使得某个核心立即运行进程调度)
-
-*/
-
-#define APIC_TIMER_IRQ_NUM 151
-
-typedef struct hardware_intr_type
-{
-    // 使能中断操作接口
-    void (*enable)(ul irq_num);
-    // 禁止中断操作接口
-    void (*disable)(ul irq_num);
-
-    // 安装中断操作接口
-    ul (*install)(ul irq_num, void *arg);
-    // 卸载中断操作接口
-    void (*uninstall)(ul irq_num);
-    // 应答中断操作接口
-    void (*ack)(ul irq_num);
-} hardware_intr_controller;
-
-// 中断描述结构体
-typedef struct
-{
-    hardware_intr_controller *controller;
-    // 中断名
-    char *irq_name;
-    // 中断处理函数的参数
-    ul parameter;
-    // 中断处理函数
-    void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs);
-
-    // 自定义的标志位
-    ul flags;
-} irq_desc_t;
-
-
-// 这几个表一定要放在这里,否则在HPET初始化后收到中断,会产生page fault
-irq_desc_t interrupt_desc[IRQ_NUM] = {0};
-irq_desc_t local_apic_interrupt_desc[LOCAL_APIC_IRQ_NUM] = {0};
-irq_desc_t SMP_IPI_desc[SMP_IRQ_NUM] = {0};
-
-
-/**
- * @brief 中断注册函数
- * 
- * @param irq_num 中断向量号
- * @param arg 传递给中断安装接口的参数
- * @param handler 中断处理函数
- * @param paramater 中断处理函数的参数
- * @param controller 中断控制器结构
- * @param irq_name 中断名
- * @return int 
- */
-int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter, struct pt_regs *regs), ul paramater, hardware_intr_controller *controller, char *irq_name);
-
-/**
- * @brief 中断注销函数
- * 
- * @param irq_num 中断向量号
- * @return int 
- */
-int irq_unregister(ul irq_num);
-
-/**
- * @brief 初始化中断模块
- */
-void irq_init();
-#pragma GCC pop_options

+ 107 - 8
kernel/src/exception/irqchip.rs

@@ -6,11 +6,15 @@ use alloc::{
 };
 use system_error::SystemError;
 
-use crate::{libs::spinlock::SpinLock, mm::VirtAddr};
+use crate::{
+    libs::{cpumask::CpuMask, spinlock::SpinLock},
+    mm::VirtAddr,
+};
 
 use super::{
     irqdata::{IrqData, IrqLineStatus},
     irqdomain::IrqDomain,
+    manage::IrqManager,
     msi::MsiMsg,
 };
 
@@ -41,18 +45,58 @@ pub trait IrqChip: Sync + Send + Any + Debug {
     fn irq_ack(&self, irq: &Arc<IrqData>);
 
     /// mask an interrupt source
-    fn irq_mask(&self, _irq: &Arc<IrqData>) {}
+    ///
+    /// 用于屏蔽中断
+    ///
+    /// 如果返回ENOSYS,则表明irq_mask()不支持.
+    ///
+    /// 如果返回错误,那么中断的屏蔽状态将不会改变。
+    fn irq_mask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
+
+    /// 指示当前芯片是否实现了`irq_mask_ack`函数
+    fn can_mask_ack(&self) -> bool;
+
     /// ack and mask an interrupt source
     fn irq_mask_ack(&self, _irq: &Arc<IrqData>) {}
+
     /// unmask an interrupt source
-    fn irq_unmask(&self, _irq: &Arc<IrqData>) {}
+    ///
+    /// 用于取消屏蔽中断
+    ///
+    /// 如果返回ENOSYS,则表明irq_unmask()不支持.
+    fn irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
     /// end of interrupt
     fn irq_eoi(&self, _irq: &Arc<IrqData>) {}
 
-    // todo: set affinity
+    /// 指示当前芯片是否可以设置中断亲和性。
+    fn can_set_affinity(&self) -> bool;
+
+    /// 在SMP机器上设置CPU亲和性。
+    ///
+    /// 如果force参数为真,它告诉驱动程序无条件地应用亲和性设置。
+    /// 不需要对提供的亲和性掩码进行完整性检查。这用于CPU热插拔,其中目标CPU尚未在cpu_online_mask中设置。
+    fn irq_set_affinity(
+        &self,
+        _irq: &Arc<IrqData>,
+        _cpu: &CpuMask,
+        _force: bool,
+    ) -> Result<IrqChipSetMaskResult, SystemError> {
+        Err(SystemError::ENOSYS)
+    }
 
     /// retrigger an IRQ to the CPU
-    fn retrigger(&self, _irq: &Arc<IrqData>) {}
+    fn retrigger(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
+
+    /// 指示当前芯片是否可以设置中断流类型。
+    ///
+    /// 如果返回true,则可以调用irq_set_type()。
+    fn can_set_flow_type(&self) -> bool;
 
     /// set the flow type of an interrupt
     ///
@@ -62,7 +106,7 @@ pub trait IrqChip: Sync + Send + Any + Debug {
         &self,
         _irq: &Arc<IrqData>,
         _flow_type: IrqLineStatus,
-    ) -> Result<(), SystemError> {
+    ) -> Result<IrqChipSetMaskResult, SystemError> {
         Err(SystemError::ENOSYS)
     }
 
@@ -108,6 +152,8 @@ pub trait IrqChip: Sync + Send + Any + Debug {
     fn irq_release_resources(&self, _irq: &Arc<IrqData>) {}
 
     /// optional to compose message content for MSI
+    ///
+    /// 组装MSI消息并返回到msg中
     fn irq_compose_msi_msg(&self, _irq: &Arc<IrqData>, _msg: &mut MsiMsg) {}
 
     /// optional to write message content for MSI
@@ -163,7 +209,10 @@ pub enum IrqChipState {
     LineLevel,
 }
 
-pub trait IrqChipData: Sync + Send + Any + Debug {}
+/// 中断芯片的数据(per-irq的)
+pub trait IrqChipData: Sync + Send + Any + Debug {
+    fn as_any_ref(&self) -> &dyn Any;
+}
 
 bitflags! {
     /// 定义 IrqGcFlags 位标志
@@ -240,10 +289,23 @@ pub struct IrqChipType {
     // todo https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#1024
 }
 
+#[allow(dead_code)]
+#[derive(Debug)]
+pub enum IrqChipSetMaskResult {
+    /// core updates mask ok.
+    SetMaskOk,
+    /// core updates mask ok. No change.
+    SetMaskOkNoChange,
+    /// core updates mask ok. Done.(same as SetMaskOk)
+    ///
+    /// 支持堆叠irq芯片的特殊代码, 表示跳过所有子irq芯片。
+    SetMaskOkDone,
+}
+
 bitflags! {
     /// IrqChip specific flags
     pub struct IrqChipFlags: u32 {
-        /// 在调用chip.irq_set_type()之前屏蔽
+        /// 在调用chip.irq_set_type()之前屏蔽中断
         const IRQCHIP_SET_TYPE_MASKED = 1 << 0;
         /// 只有在irq被处理时才发出irq_eoi()
         const IRQCHIP_EOI_IF_HANDLED = 1 << 1;
@@ -269,3 +331,40 @@ bitflags! {
         const IRQCHIP_IMMUTABLE = 1 << 11;
     }
 }
+
+impl IrqManager {
+    /// Acknowledge the parent interrupt
+    #[allow(dead_code)]
+    pub fn irq_chip_ack_parent(&self, irq_data: &Arc<IrqData>) {
+        let parent_data = irq_data.parent_data().map(|p| p.upgrade()).flatten();
+
+        if let Some(parent_data) = parent_data {
+            let parent_chip = parent_data.chip_info_read_irqsave().chip();
+            parent_chip.irq_ack(&parent_data);
+        }
+    }
+
+    /// 在硬件中重新触发中断
+    ///
+    /// 遍历中断域的层次结构,并检查是否存在一个硬件重新触发函数。如果存在则调用它
+    pub fn irq_chip_retrigger_hierarchy(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
+        let mut data: Option<Arc<IrqData>> = Some(irq_data.clone());
+        loop {
+            if let Some(d) = data {
+                if let Err(e) = d.chip_info_read_irqsave().chip().retrigger(&d) {
+                    if e == SystemError::ENOSYS {
+                        data = d.parent_data().map(|p| p.upgrade()).flatten();
+                    } else {
+                        return Err(e);
+                    }
+                } else {
+                    return Ok(());
+                }
+            } else {
+                break;
+            }
+        }
+
+        return Ok(());
+    }
+}

+ 225 - 34
kernel/src/exception/irqdata.rs

@@ -1,8 +1,13 @@
 use core::{any::Any, fmt::Debug};
 
 use alloc::sync::{Arc, Weak};
+use intertrait::CastFromSync;
 
-use crate::libs::spinlock::SpinLock;
+use crate::libs::{
+    cpumask::CpuMask,
+    rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
+    spinlock::{SpinLock, SpinLockGuard},
+};
 
 use super::{
     irqchip::{IrqChip, IrqChipData},
@@ -22,6 +27,8 @@ pub struct IrqData {
     /// 中断号, 用于表示软件逻辑视角的中断号,全局唯一
     irq: IrqNumber,
     inner: SpinLock<InnerIrqData>,
+
+    chip_info: RwLock<InnerIrqChipInfo>,
 }
 
 impl IrqData {
@@ -36,25 +43,28 @@ impl IrqData {
             inner: SpinLock::new(InnerIrqData {
                 hwirq,
                 common_data,
-                chip,
-                chip_data: None,
+
                 domain: None,
                 parent_data: None,
             }),
+            chip_info: RwLock::new(InnerIrqChipInfo {
+                chip: Some(chip),
+                chip_data: None,
+            }),
         };
     }
 
     pub fn irqd_set(&self, status: IrqStatus) {
         // clone是为了释放inner锁
-        let common_data = self.inner.lock().common_data.clone();
-        common_data.irqd_set(status);
+        let common_data = self.inner.lock_irqsave().common_data.clone();
+        common_data.insert_status(status);
     }
 
     #[allow(dead_code)]
     pub fn irqd_clear(&self, status: IrqStatus) {
         // clone是为了释放inner锁
-        let common_data = self.inner.lock().common_data.clone();
-        common_data.irqd_clear(status);
+        let common_data = self.inner.lock_irqsave().common_data.clone();
+        common_data.clear_status(status);
     }
 
     pub fn irq(&self) -> IrqNumber {
@@ -65,17 +75,13 @@ impl IrqData {
         self.inner.lock_irqsave().hwirq
     }
 
-    pub fn chip(&self) -> Arc<dyn IrqChip> {
-        self.inner.lock_irqsave().chip.clone()
-    }
-
     /// 是否为电平触发
     pub fn is_level_type(&self) -> bool {
         self.inner
             .lock_irqsave()
             .common_data
             .inner
-            .lock()
+            .lock_irqsave()
             .state
             .is_level_type()
     }
@@ -85,29 +91,95 @@ impl IrqData {
             .lock_irqsave()
             .common_data
             .inner
-            .lock()
+            .lock_irqsave()
             .state
             .is_wakeup_set()
     }
+
+    pub fn common_data(&self) -> Arc<IrqCommonData> {
+        self.inner.lock_irqsave().common_data.clone()
+    }
+
+    pub fn domain(&self) -> Option<Arc<IrqDomain>> {
+        self.inner.lock_irqsave().domain.clone()
+    }
+
+    pub fn inner(&self) -> SpinLockGuard<InnerIrqData> {
+        self.inner.lock_irqsave()
+    }
+
+    pub fn chip_info_read(&self) -> RwLockReadGuard<InnerIrqChipInfo> {
+        self.chip_info.read()
+    }
+
+    pub fn chip_info_read_irqsave(&self) -> RwLockReadGuard<InnerIrqChipInfo> {
+        self.chip_info.read_irqsave()
+    }
+
+    pub fn chip_info_write_irqsave(&self) -> RwLockWriteGuard<InnerIrqChipInfo> {
+        self.chip_info.write_irqsave()
+    }
+
+    pub fn parent_data(&self) -> Option<Weak<IrqData>> {
+        self.inner.lock_irqsave().parent_data.clone()
+    }
 }
 
 #[allow(dead_code)]
 #[derive(Debug)]
-struct InnerIrqData {
+pub struct InnerIrqData {
     /// 硬件中断号, 用于表示在某个IrqDomain中的中断号
     hwirq: HardwareIrqNumber,
     /// 涉及的所有irqchip之间共享的数据
     common_data: Arc<IrqCommonData>,
-    /// 绑定到的中断芯片
-    chip: Arc<dyn IrqChip>,
-    /// 中断芯片的私有数据(与当前irq相关)
-    chip_data: Option<Arc<dyn IrqChipData>>,
+
     /// 中断域
     domain: Option<Arc<IrqDomain>>,
     /// 中断的父中断(如果具有中断域继承的话)
     parent_data: Option<Weak<IrqData>>,
 }
 
+impl InnerIrqData {
+    pub fn set_hwirq(&mut self, hwirq: HardwareIrqNumber) {
+        self.hwirq = hwirq;
+    }
+
+    #[allow(dead_code)]
+    pub fn domain(&self) -> Option<Arc<IrqDomain>> {
+        self.domain.clone()
+    }
+
+    pub fn set_domain(&mut self, domain: Option<Arc<IrqDomain>>) {
+        self.domain = domain;
+    }
+}
+
+#[derive(Debug)]
+pub struct InnerIrqChipInfo {
+    /// 绑定到的中断芯片
+    chip: Option<Arc<dyn IrqChip>>,
+    /// 中断芯片的私有数据(与当前irq相关)
+    chip_data: Option<Arc<dyn IrqChipData>>,
+}
+
+impl InnerIrqChipInfo {
+    pub fn set_chip(&mut self, chip: Option<Arc<dyn IrqChip>>) {
+        self.chip = chip;
+    }
+
+    pub fn set_chip_data(&mut self, chip_data: Option<Arc<dyn IrqChipData>>) {
+        self.chip_data = chip_data;
+    }
+
+    pub fn chip(&self) -> Arc<dyn IrqChip> {
+        self.chip.clone().unwrap()
+    }
+
+    pub fn chip_data(&self) -> Option<Arc<dyn IrqChipData>> {
+        self.chip_data.clone()
+    }
+}
+
 /// per irq data shared by all irqchips
 ///
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#147
@@ -122,19 +194,100 @@ impl IrqCommonData {
             state: IrqStatus::empty(),
             handler_data: None,
             msi_desc: None,
+            affinity: CpuMask::new(),
         };
         return IrqCommonData {
             inner: SpinLock::new(inner),
         };
     }
 
-    pub fn irqd_set(&self, status: IrqStatus) {
-        self.inner.lock_irqsave().irqd_set(status);
+    pub fn insert_status(&self, status: IrqStatus) {
+        self.inner.lock_irqsave().irqd_insert(status);
     }
 
-    pub fn irqd_clear(&self, status: IrqStatus) {
+    pub fn clear_status(&self, status: IrqStatus) {
         self.inner.lock_irqsave().irqd_clear(status);
     }
+
+    pub fn clear_managed_shutdown(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .remove(IrqStatus::IRQD_MANAGED_SHUTDOWN);
+    }
+
+    #[allow(dead_code)]
+    pub fn masked(&self) -> bool {
+        self.inner.lock_irqsave().state.masked()
+    }
+
+    pub fn set_masked(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .insert(IrqStatus::IRQD_IRQ_MASKED);
+    }
+
+    pub fn clear_masked(&self) {
+        self.clear_status(IrqStatus::IRQD_IRQ_MASKED);
+    }
+
+    pub fn set_inprogress(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .insert(IrqStatus::IRQD_IRQ_INPROGRESS);
+    }
+
+    pub fn clear_inprogress(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .remove(IrqStatus::IRQD_IRQ_INPROGRESS);
+    }
+
+    pub fn disabled(&self) -> bool {
+        self.inner.lock_irqsave().state.disabled()
+    }
+
+    #[allow(dead_code)]
+    pub fn set_disabled(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .insert(IrqStatus::IRQD_IRQ_DISABLED);
+    }
+
+    pub fn clear_disabled(&self) {
+        self.clear_status(IrqStatus::IRQD_IRQ_DISABLED);
+    }
+
+    pub fn status(&self) -> IrqStatus {
+        self.inner.lock_irqsave().state
+    }
+
+    pub fn trigger_type(&self) -> IrqLineStatus {
+        self.inner.lock_irqsave().state.trigger_type()
+    }
+
+    pub fn set_trigger_type(&self, trigger: IrqLineStatus) {
+        self.inner.lock_irqsave().state.set_trigger_type(trigger);
+    }
+
+    pub fn set_started(&self) {
+        self.inner
+            .lock_irqsave()
+            .state
+            .insert(IrqStatus::IRQD_IRQ_STARTED);
+    }
+
+    pub fn affinity(&self) -> CpuMask {
+        self.inner.lock_irqsave().affinity.clone()
+    }
+
+    pub fn set_affinity(&self, affinity: CpuMask) {
+        self.inner.lock_irqsave().affinity = affinity;
+    }
 }
 
 #[allow(dead_code)]
@@ -145,11 +298,11 @@ struct InnerIrqCommonData {
     /// per-IRQ data for the irq_chip methods
     handler_data: Option<Arc<dyn IrqHandlerData>>,
     msi_desc: Option<Arc<MsiDesc>>,
-    // todo: affinity
+    affinity: CpuMask,
 }
 
 impl InnerIrqCommonData {
-    pub fn irqd_set(&mut self, status: IrqStatus) {
+    pub fn irqd_insert(&mut self, status: IrqStatus) {
         self.state.insert(status);
     }
 
@@ -158,7 +311,8 @@ impl InnerIrqCommonData {
     }
 }
 
-pub trait IrqHandlerData: Send + Sync + Any + Debug {}
+/// 中断处理函数传入的数据
+pub trait IrqHandlerData: Send + Sync + Any + Debug + CastFromSync {}
 
 bitflags! {
     /// 中断线状态
@@ -219,12 +373,45 @@ bitflags! {
 
 
 
+}
+
+impl IrqLineStatus {
+    pub const fn trigger_bits(&self) -> u32 {
+        self.bits & Self::IRQ_TYPE_SENSE_MASK.bits
+    }
+
+    pub fn trigger_type(&self) -> Self {
+        *self & Self::IRQ_TYPE_SENSE_MASK
+    }
+
+    pub fn is_level_type(&self) -> bool {
+        self.contains(Self::IRQ_LEVEL)
+    }
+
+    /// 是否为高电平触发
+    ///
+    /// ## 返回
+    ///
+    /// - 如果不是电平触发类型,则返回None
+    /// - 如果是电平触发类型,则返回Some(bool),当为true时表示高电平触发
+    pub fn is_level_high(&self) -> Option<bool> {
+        if !self.is_level_type() {
+            return None;
+        }
+        return Some(self.contains(Self::IRQ_TYPE_LEVEL_HIGH));
+    }
 }
 bitflags! {
     /// 中断状态(存储在IrqCommonData)
     ///
     /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#227
     pub struct IrqStatus: u32 {
+        const IRQD_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
+        const IRQD_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
+        const IRQD_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
+        const IRQD_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
+        const IRQD_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
+
         /// 触发类型位的掩码
         const IRQD_TRIGGER_MASK = 0xf;
         /// 亲和性设置待处理
@@ -261,7 +448,7 @@ bitflags! {
         const IRQD_MANAGED_SHUTDOWN = 1 << 23;
         /// IRQ只允许单个亲和性目标
         const IRQD_SINGLE_TARGET = 1 << 24;
-        /// 预期的触发器已设置
+        /// 默认的触发器已设置
         const IRQD_DEFAULT_TRIGGER_SET = 1 << 25;
         /// 可以使用保留模式
         const IRQD_CAN_RESERVE = 1 << 26;
@@ -294,6 +481,14 @@ impl IrqStatus {
         self.contains(Self::IRQD_AFFINITY_SET)
     }
 
+    pub fn masked(&self) -> bool {
+        self.contains(Self::IRQD_IRQ_MASKED)
+    }
+
+    pub fn disabled(&self) -> bool {
+        self.contains(Self::IRQD_IRQ_DISABLED)
+    }
+
     pub fn mark_affinity_set(&mut self) {
         self.insert(Self::IRQD_AFFINITY_SET);
     }
@@ -353,14 +548,6 @@ impl IrqStatus {
         self.contains(Self::IRQD_MOVE_PCNTXT)
     }
 
-    pub const fn is_irq_disabled(&self) -> bool {
-        self.contains(Self::IRQD_IRQ_DISABLED)
-    }
-
-    pub const fn is_irq_masked(&self) -> bool {
-        self.contains(Self::IRQD_IRQ_MASKED)
-    }
-
     pub const fn is_irq_in_progress(&self) -> bool {
         self.contains(Self::IRQD_IRQ_INPROGRESS)
     }
@@ -377,7 +564,7 @@ impl IrqStatus {
         self.insert(Self::IRQD_FORWARDED_TO_VCPU);
     }
 
-    pub const fn is_affinity_managed(&self) -> bool {
+    pub const fn affinity_managed(&self) -> bool {
         self.contains(Self::IRQD_AFFINITY_MANAGED)
     }
 
@@ -432,4 +619,8 @@ impl IrqStatus {
     pub const fn is_affinity_on_activate(&self) -> bool {
         self.contains(Self::IRQD_AFFINITY_ON_ACTIVATE)
     }
+
+    pub const fn started(&self) -> bool {
+        self.contains(Self::IRQD_IRQ_STARTED)
+    }
 }

+ 454 - 28
kernel/src/exception/irqdesc.rs

@@ -1,4 +1,8 @@
-use core::{any::Any, fmt::Debug};
+use core::{
+    any::Any,
+    fmt::Debug,
+    sync::atomic::{AtomicI64, Ordering},
+};
 
 use alloc::{
     collections::{btree_map, BTreeMap},
@@ -9,7 +13,7 @@ use alloc::{
 use system_error::SystemError;
 
 use crate::{
-    arch::CurrentIrqArch,
+    arch::{interrupt::TrapFrame, CurrentIrqArch},
     driver::base::{
         device::DeviceId,
         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
@@ -17,23 +21,48 @@ use crate::{
     },
     filesystem::kernfs::KernFSInode,
     libs::{
-        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        mutex::{Mutex, MutexGuard},
+        rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
         spinlock::{SpinLock, SpinLockGuard},
     },
     process::ProcessControlBlock,
+    sched::completion::Completion,
 };
 
 use super::{
     dummychip::no_irq_chip,
     handle::bad_irq_handler,
-    irqdata::{IrqCommonData, IrqData, IrqStatus},
+    irqdata::{IrqCommonData, IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
     sysfs::{irq_sysfs_del, IrqKObjType},
     HardwareIrqNumber, InterruptArch, IrqNumber,
 };
 
 /// 中断流处理程序
-pub trait IrqFlowHandler: Debug + Send + Sync {
-    fn handle(&self, irq_desc: &Arc<IrqDesc>);
+pub trait IrqFlowHandler: Debug + Send + Sync + Any {
+    fn handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame);
+}
+
+/// 中断处理程序
+pub trait IrqHandler: Debug + Send + Sync + Any {
+    fn handle(
+        &self,
+        irq: IrqNumber,
+        static_data: Option<&dyn IrqHandlerData>,
+        dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError>;
+}
+
+/// 中断处理函数返回值
+///
+/// 用于指示中断处理函数是否处理了中断
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum IrqReturn {
+    /// 中断未被处理
+    NotHandled,
+    /// 中断已被处理
+    Handled,
+    /// 中断已被处理,并且需要唤醒中断线程
+    WakeThread,
 }
 
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
@@ -41,9 +70,12 @@ pub trait IrqFlowHandler: Debug + Send + Sync {
 pub struct IrqDesc {
     inner: SpinLock<InnerIrqDesc>,
 
-    handler: SpinLock<Option<&'static dyn IrqFlowHandler>>,
-
+    handler: RwLock<Option<&'static dyn IrqFlowHandler>>,
+    /// 一个用于串行化 request_irq()和free_irq() 的互斥锁
+    request_mutex: Mutex<()>,
     kobj_state: LockedKObjectState,
+    /// 当前描述符内正在运行的中断线程数
+    threads_active: AtomicI64,
 }
 
 impl IrqDesc {
@@ -59,13 +91,14 @@ impl IrqDesc {
         ));
 
         irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
-        common_data.irqd_set(IrqStatus::IRQD_IRQ_MASKED);
+        common_data.insert_status(IrqStatus::IRQD_IRQ_MASKED);
 
         let irq_desc = IrqDesc {
             inner: SpinLock::new(InnerIrqDesc {
                 common_data,
                 irq_data,
                 desc_internal_state: IrqDescState::empty(),
+                line_status: IrqLineStatus::empty(),
                 actions: Vec::new(),
                 name,
                 parent_irq: None,
@@ -75,8 +108,10 @@ impl IrqDesc {
                 kset: None,
                 parent_kobj: None,
             }),
-            handler: SpinLock::new(None),
+            request_mutex: Mutex::new(()),
+            handler: RwLock::new(None),
             kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
+            threads_active: AtomicI64::new(0),
         };
 
         irq_desc.set_handler(bad_irq_handler());
@@ -85,12 +120,36 @@ impl IrqDesc {
         return Arc::new(irq_desc);
     }
 
+    /// 返回当前活跃的中断线程数量
+    #[allow(dead_code)]
+    pub fn threads_active(&self) -> i64 {
+        self.threads_active.load(Ordering::SeqCst)
+    }
+
+    /// 增加当前活跃的中断线程数量, 返回增加前的值
+    pub fn inc_threads_active(&self) -> i64 {
+        self.threads_active.fetch_add(1, Ordering::SeqCst)
+    }
+
+    /// 减少当前活跃的中断线程数量, 返回减少前的值
+    #[allow(dead_code)]
+    pub fn dec_threads_active(&self) -> i64 {
+        self.threads_active.fetch_sub(1, Ordering::SeqCst)
+    }
+
     pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
-        let mut guard = self.handler.lock_irqsave();
+        self.chip_bus_lock();
+        let mut guard = self.handler.write_irqsave();
         *guard = Some(handler);
+        self.chip_bus_sync_unlock();
     }
 
-    fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
+    pub fn handler(&self) -> Option<&'static dyn IrqFlowHandler> {
+        let guard = self.handler.read_irqsave();
+        *guard
+    }
+
+    pub fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
         self.inner.lock_irqsave()
     }
 
@@ -98,6 +157,11 @@ impl IrqDesc {
         self.inner().actions.clone()
     }
 
+    /// 对中断请求过程加锁
+    pub fn request_mutex_lock(&self) -> MutexGuard<()> {
+        self.request_mutex.lock()
+    }
+
     pub fn irq(&self) -> IrqNumber {
         self.inner().irq_data.irq()
     }
@@ -133,11 +197,115 @@ impl IrqDesc {
     pub fn name(&self) -> Option<String> {
         self.inner().name.clone()
     }
+
+    pub fn can_request(&self) -> bool {
+        self.inner().can_request()
+    }
+
+    #[allow(dead_code)]
+    pub fn set_norequest(&self) {
+        self.inner().set_norequest();
+    }
+
+    #[allow(dead_code)]
+    pub fn clear_norequest(&self) {
+        self.inner().clear_norequest();
+    }
+
+    pub fn nested_thread(&self) -> bool {
+        self.inner().nested_thread()
+    }
+
+    /// 中断是否可以线程化
+    pub fn can_thread(&self) -> bool {
+        !self
+            .inner()
+            .line_status
+            .contains(IrqLineStatus::IRQ_NOTHREAD)
+    }
+
+    pub fn chip_bus_lock(&self) {
+        let irq_data = self.inner().irq_data.clone();
+        irq_data
+            .chip_info_read_irqsave()
+            .chip()
+            .irq_bus_lock(&irq_data)
+            .ok();
+    }
+
+    /// 同步释放低速总线锁
+    ///
+    /// ## 锁
+    ///
+    /// 进入此函数时,必须持有低速总线锁,并且desc的inner锁和irqdata的inner锁
+    ///     必须已经释放。否则将死锁。
+    pub fn chip_bus_sync_unlock(&self) {
+        let irq_data = self.inner().irq_data.clone();
+        irq_data
+            .chip_info_write_irqsave()
+            .chip()
+            .irq_bus_sync_unlock(&irq_data)
+            .ok();
+    }
+
+    pub fn modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus) {
+        let mut desc_guard = self.inner();
+        desc_guard.line_status.remove(clear);
+        desc_guard.line_status.insert(set);
+
+        let mut trigger = desc_guard.common_data().trigger_type();
+
+        desc_guard.common_data().clear_status(
+            IrqStatus::IRQD_NO_BALANCING
+                | IrqStatus::IRQD_PER_CPU
+                | IrqStatus::IRQD_TRIGGER_MASK
+                | IrqStatus::IRQD_LEVEL
+                | IrqStatus::IRQD_MOVE_PCNTXT,
+        );
+
+        if desc_guard
+            .line_status
+            .contains(IrqLineStatus::IRQ_NO_BALANCING)
+        {
+            desc_guard
+                .common_data()
+                .insert_status(IrqStatus::IRQD_NO_BALANCING);
+        }
+
+        if desc_guard.line_status.contains(IrqLineStatus::IRQ_PER_CPU) {
+            desc_guard
+                .common_data()
+                .insert_status(IrqStatus::IRQD_PER_CPU);
+        }
+
+        if desc_guard
+            .line_status
+            .contains(IrqLineStatus::IRQ_MOVE_PCNTXT)
+        {
+            desc_guard
+                .common_data()
+                .insert_status(IrqStatus::IRQD_MOVE_PCNTXT);
+        }
+
+        if desc_guard.line_status.is_level_type() {
+            desc_guard
+                .common_data()
+                .insert_status(IrqStatus::IRQD_LEVEL);
+        }
+
+        let tmp = desc_guard.line_status.trigger_type();
+
+        if tmp != IrqLineStatus::IRQ_TYPE_NONE {
+            trigger = tmp;
+        }
+
+        desc_guard.common_data().set_trigger_type(trigger);
+    }
 }
 
 #[allow(dead_code)]
 #[derive(Debug)]
-struct InnerIrqDesc {
+pub struct InnerIrqDesc {
     /// per irq and chip data passed down to chip functions
     common_data: Arc<IrqCommonData>,
     irq_data: Arc<IrqData>,
@@ -149,10 +317,134 @@ struct InnerIrqDesc {
     /// nested wake enables
     wake_depth: u32,
     desc_internal_state: IrqDescState,
+    /// 中断线的状态
+    line_status: IrqLineStatus,
 
     kern_inode: Option<Arc<KernFSInode>>,
     kset: Option<Arc<KSet>>,
     parent_kobj: Option<Weak<dyn KObject>>,
+    // wait_for_threads: EventWaitQueue
+}
+
+impl InnerIrqDesc {
+    pub fn name(&self) -> Option<&String> {
+        self.name.as_ref()
+    }
+
+    pub fn can_request(&self) -> bool {
+        !self.line_status.contains(IrqLineStatus::IRQ_NOREQUEST)
+    }
+
+    #[allow(dead_code)]
+    pub fn set_norequest(&mut self) {
+        self.line_status.insert(IrqLineStatus::IRQ_NOREQUEST);
+    }
+
+    #[allow(dead_code)]
+    pub fn clear_norequest(&mut self) {
+        self.line_status.remove(IrqLineStatus::IRQ_NOREQUEST);
+    }
+
+    pub fn nested_thread(&self) -> bool {
+        self.line_status.contains(IrqLineStatus::IRQ_NESTED_THREAD)
+    }
+
+    pub fn line_status_set_per_cpu(&mut self) {
+        self.line_status.insert(IrqLineStatus::IRQ_PER_CPU);
+    }
+
+    #[allow(dead_code)]
+    pub fn line_status_clear_per_cpu(&mut self) {
+        self.line_status.remove(IrqLineStatus::IRQ_PER_CPU);
+    }
+
+    #[allow(dead_code)]
+    pub fn line_status(&self) -> &IrqLineStatus {
+        &self.line_status
+    }
+
+    pub fn line_status_set_no_debug(&mut self) {
+        self.line_status.insert(IrqLineStatus::IRQ_NO_BALANCING);
+    }
+
+    #[allow(dead_code)]
+    pub fn line_status_clear_no_debug(&mut self) {
+        self.line_status.remove(IrqLineStatus::IRQ_NO_BALANCING);
+    }
+
+    pub fn can_autoenable(&self) -> bool {
+        !self.line_status.contains(IrqLineStatus::IRQ_NOAUTOEN)
+    }
+
+    pub fn can_thread(&self) -> bool {
+        !self.line_status.contains(IrqLineStatus::IRQ_NOTHREAD)
+    }
+
+    /// 中断是否可以设置CPU亲和性
+    pub fn can_set_affinity(&self) -> bool {
+        if self.common_data.status().can_balance() == false
+            || self
+                .irq_data()
+                .chip_info_read_irqsave()
+                .chip()
+                .can_set_affinity()
+                == false
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    pub fn actions(&self) -> &Vec<Arc<IrqAction>> {
+        &self.actions
+    }
+
+    pub fn add_action(&mut self, action: Arc<IrqAction>) {
+        self.actions.push(action);
+    }
+
+    pub fn internal_state(&self) -> &IrqDescState {
+        &self.desc_internal_state
+    }
+
+    pub(super) fn internal_state_mut(&mut self) -> &mut IrqDescState {
+        &mut self.desc_internal_state
+    }
+
+    pub fn irq_data(&self) -> &Arc<IrqData> {
+        &self.irq_data
+    }
+
+    pub fn common_data(&self) -> &Arc<IrqCommonData> {
+        &self.common_data
+    }
+
+    pub fn depth(&self) -> u32 {
+        self.depth
+    }
+
+    pub fn wake_depth(&self) -> u32 {
+        self.wake_depth
+    }
+
+    pub fn set_depth(&mut self, depth: u32) {
+        self.depth = depth;
+    }
+
+    pub fn set_trigger_type(&mut self, trigger: IrqLineStatus) {
+        self.line_status.remove(IrqLineStatus::IRQ_TYPE_SENSE_MASK);
+        self.line_status
+            .insert(trigger & IrqLineStatus::IRQ_TYPE_SENSE_MASK);
+    }
+
+    pub fn clear_level(&mut self) {
+        self.line_status.remove(IrqLineStatus::IRQ_LEVEL);
+    }
+
+    pub fn set_level(&mut self) {
+        self.line_status.insert(IrqLineStatus::IRQ_LEVEL);
+    }
 }
 
 impl KObject for IrqDesc {
@@ -211,7 +503,7 @@ impl KObject for IrqDesc {
 
 bitflags! {
     /// Bit masks for desc->desc_internal_state
-    struct IrqDescState: u32 {
+    pub struct IrqDescState: u32 {
         /// autodetection in progress
         const IRQS_AUTODETECT = 0x00000001;
         /// was disabled due to spurious interrupt detection
@@ -241,6 +533,8 @@ bitflags! {
 #[derive(Debug)]
 pub struct IrqAction {
     inner: SpinLock<InnerIrqAction>,
+    /// 用于等待线程被创建的完成量
+    thread_completion: Completion,
 }
 
 impl IrqAction {
@@ -248,42 +542,45 @@ impl IrqAction {
     pub fn new(
         irq: IrqNumber,
         name: String,
-        handler: Option<&'static dyn IrqFlowHandler>,
+        handler: Option<&'static dyn IrqHandler>,
+        thread_fn: Option<&'static dyn IrqHandler>,
     ) -> Arc<Self> {
-        let action = IrqAction {
+        let action: IrqAction = IrqAction {
             inner: SpinLock::new(InnerIrqAction {
                 dev_id: None,
                 handler,
-                thread_fn: None,
+                thread_fn,
                 thread: None,
                 secondary: None,
                 irq,
                 flags: IrqHandleFlags::empty(),
                 name,
+                thread_flags: ThreadedHandlerFlags::empty(),
             }),
+            thread_completion: Completion::new(),
         };
 
         return Arc::new(action);
     }
 
-    pub fn name(&self) -> String {
-        self.inner().name.clone()
+    pub fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
+        self.inner.lock_irqsave()
     }
 
-    fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
-        self.inner.lock_irqsave()
+    pub fn thread_completion(&self) -> &Completion {
+        &self.thread_completion
     }
 }
 
 #[allow(dead_code)]
 #[derive(Debug)]
-struct InnerIrqAction {
+pub struct InnerIrqAction {
     /// cookie to identify the device
-    dev_id: Option<DeviceId>,
+    dev_id: Option<Arc<DeviceId>>,
     /// 中断处理程序
-    handler: Option<&'static dyn IrqFlowHandler>,
+    handler: Option<&'static dyn IrqHandler>,
     /// interrupt handler function for threaded interrupts
-    thread_fn: Option<&'static dyn IrqFlowHandler>,
+    thread_fn: Option<&'static dyn IrqHandler>,
     /// thread pointer for threaded interrupts
     thread: Option<Arc<ProcessControlBlock>>,
     /// pointer to secondary irqaction (force threading)
@@ -291,14 +588,122 @@ struct InnerIrqAction {
     /// 中断号
     irq: IrqNumber,
     flags: IrqHandleFlags,
+    /// 中断线程的标志
+    thread_flags: ThreadedHandlerFlags,
     /// name of the device
     name: String,
 }
 
+impl InnerIrqAction {
+    pub fn dev_id(&self) -> &Option<Arc<DeviceId>> {
+        &self.dev_id
+    }
+
+    pub fn dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>> {
+        &mut self.dev_id
+    }
+
+    pub fn handler(&self) -> Option<&'static dyn IrqHandler> {
+        self.handler
+    }
+
+    pub fn set_handler(&mut self, handler: Option<&'static dyn IrqHandler>) {
+        self.handler = handler;
+    }
+
+    pub fn thread_fn(&self) -> Option<&'static dyn IrqHandler> {
+        self.thread_fn
+    }
+
+    pub fn thread(&self) -> Option<Arc<ProcessControlBlock>> {
+        self.thread.clone()
+    }
+
+    pub fn set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>) {
+        self.thread = thread;
+    }
+
+    #[allow(dead_code)]
+    pub fn thread_flags(&self) -> &ThreadedHandlerFlags {
+        &self.thread_flags
+    }
+
+    pub fn thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags {
+        &mut self.thread_flags
+    }
+
+    pub fn secondary(&self) -> Option<Arc<IrqAction>> {
+        self.secondary.clone()
+    }
+
+    #[allow(dead_code)]
+    pub fn irq(&self) -> IrqNumber {
+        self.irq
+    }
+
+    #[allow(dead_code)]
+    pub fn set_irq(&mut self, irq: IrqNumber) {
+        self.irq = irq;
+    }
+
+    pub fn flags(&self) -> &IrqHandleFlags {
+        &self.flags
+    }
+
+    pub fn flags_mut(&mut self) -> &mut IrqHandleFlags {
+        &mut self.flags
+    }
+
+    pub fn name(&self) -> &String {
+        &self.name
+    }
+}
+
+bitflags! {
+    /// 这些标志由线程处理程序使用
+    pub struct ThreadedHandlerFlags: u32 {
+        /// IRQTF_RUNTHREAD - 表示应运行中断处理程序线程
+        const IRQTF_RUNTHREAD = 1 << 0;
+        /// IRQTF_WARNED - 已打印警告 "IRQ_WAKE_THREAD w/o thread_fn"
+        const IRQTF_WARNED = 1 << 1;
+        /// IRQTF_AFFINITY - 请求irq线程调整亲和性
+        const IRQTF_AFFINITY = 1 << 2;
+        /// IRQTF_FORCED_THREAD - irq操作被强制线程化
+        const IRQTF_FORCED_THREAD = 1 << 3;
+        /// IRQTF_READY - 表示irq线程已准备就绪
+        const IRQTF_READY = 1 << 4;
+    }
+}
+
+/// Implements the `ThreadedHandlerFlags` structure.
+impl ThreadedHandlerFlags {
+    /// 在 `ThreadedHandlerFlags` 结构中测试并设置特定的位。
+    ///
+    /// # 参数
+    ///
+    /// * `bit` - 要测试并设置的位。
+    ///
+    /// # 返回
+    ///
+    /// 如果操作前该位已被设置,则返回 `true`,否则返回 `false`。
+    pub fn test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool {
+        let res = (self.bits & bit.bits) != 0;
+        self.bits |= bit.bits;
+        return res;
+    }
+}
+
 // 定义IrqFlags位标志
 bitflags! {
     /// 这些标志仅由内核在中断处理例程中使用。
     pub struct IrqHandleFlags: u32 {
+
+        const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
+        const IRQF_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
+        const IRQF_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
+        const IRQF_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
+        const IRQF_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
+        const IRQF_TRIGGER_MASK = Self::IRQF_TRIGGER_HIGH.bits | Self::IRQF_TRIGGER_LOW.bits | Self::IRQF_TRIGGER_RISING.bits | Self::IRQF_TRIGGER_FALLING.bits;
         /// IRQF_SHARED - 允许多个设备共享中断
         const IRQF_SHARED = 0x00000080;
         /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
@@ -331,6 +736,28 @@ bitflags! {
     }
 }
 
+impl IrqHandleFlags {
+    /// 检查是否指定了触发类型
+    #[inline(always)]
+    pub fn trigger_type_specified(&self) -> bool {
+        (self.bits & Self::IRQF_TRIGGER_MASK.bits) != 0
+    }
+
+    /// 插入触发类型
+    pub fn insert_trigger_type(&mut self, trigger: IrqLineStatus) {
+        self.bits |= trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits;
+    }
+
+    #[allow(dead_code)]
+    pub fn remove_trigger_type(&mut self, trigger: IrqLineStatus) {
+        self.bits &= !(trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits);
+    }
+
+    pub fn trigger_type(&self) -> IrqLineStatus {
+        IrqLineStatus::from_bits_truncate(self.bits & IrqHandleFlags::IRQF_TRIGGER_MASK.bits)
+    }
+}
+
 #[inline(never)]
 pub(super) fn early_irq_init() -> Result<(), SystemError> {
     let irqcnt = CurrentIrqArch::probe_total_irq_num();
@@ -351,11 +778,11 @@ static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
 
 /// 获取中断描述符管理器的引用
 #[inline(always)]
-pub(super) fn irq_desc_manager() -> &'static IrqDescManager {
+pub fn irq_desc_manager() -> &'static IrqDescManager {
     return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
 }
 
-pub(super) struct IrqDescManager {
+pub struct IrqDescManager {
     irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
 }
 
@@ -367,7 +794,6 @@ impl IrqDescManager {
     }
 
     /// 查找中断描述符
-    #[allow(dead_code)]
     pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
         self.irq_descs.get(&irq).map(|desc| desc.clone())
     }

+ 333 - 9
kernel/src/exception/irqdomain.rs

@@ -1,7 +1,7 @@
 use core::fmt::Debug;
 
 use alloc::{
-    string::String,
+    string::{String, ToString},
     sync::{Arc, Weak},
     vec::Vec,
 };
@@ -10,14 +10,274 @@ use system_error::SystemError;
 
 use crate::{
     driver::{base::device::Device, open_firmware::device_node::DeviceNode},
+    exception::{irqdata::IrqLineStatus, irqdesc::irq_desc_manager, manage::irq_manager},
     libs::{rwlock::RwLock, spinlock::SpinLock},
 };
 
 use super::{
     irqchip::{IrqChipGeneric, IrqGcFlags},
+    irqdata::IrqData,
     HardwareIrqNumber, IrqNumber,
 };
 
+static mut IRQ_DOMAIN_MANAGER: Option<Arc<IrqDomainManager>> = None;
+
+/// 获取中断域管理器的引用
+#[inline(always)]
+pub fn irq_domain_manager() -> &'static Arc<IrqDomainManager> {
+    unsafe { IRQ_DOMAIN_MANAGER.as_ref().unwrap() }
+}
+
+pub(super) fn irq_domain_manager_init() {
+    unsafe {
+        IRQ_DOMAIN_MANAGER = Some(Arc::new(IrqDomainManager::new()));
+    }
+}
+/// 中断域管理器
+pub struct IrqDomainManager {
+    domains: SpinLock<Vec<Arc<IrqDomain>>>,
+    inner: RwLock<InnerIrqDomainManager>,
+}
+
+impl IrqDomainManager {
+    pub fn new() -> IrqDomainManager {
+        IrqDomainManager {
+            domains: SpinLock::new(Vec::new()),
+            inner: RwLock::new(InnerIrqDomainManager {
+                default_domain: None,
+            }),
+        }
+    }
+
+    /// 创建一个新的irqdomain, 并将其添加到irqdomain管理器中
+    ///
+    /// ## 参数
+    ///
+    /// - `name` - 中断域的名字
+    /// - `ops` - 中断域的操作
+    /// - `first_irq` - 起始软件中断号
+    /// - `first_hwirq` - 起始硬件中断号
+    /// - `irq_size` - 中断号的数量
+    ///
+    /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdomain.c?fi=__irq_domain_add#139
+    pub fn create_and_add(
+        &self,
+        name: String,
+        ops: &'static dyn IrqDomainOps,
+        first_irq: IrqNumber,
+        first_hwirq: HardwareIrqNumber,
+        irq_size: u32,
+    ) -> Option<Arc<IrqDomain>> {
+        let domain = IrqDomain::new(
+            None,
+            Some(name),
+            ops,
+            IrqDomainFlags::NAME_ALLOCATED,
+            IrqDomainBusToken::Any,
+            first_irq + irq_size,
+            first_hwirq + irq_size,
+        )?;
+
+        self.add_domain(domain.clone());
+
+        self.domain_associate_many(&domain, first_irq, first_hwirq, irq_size);
+
+        return Some(domain);
+    }
+
+    fn add_domain(&self, domain: Arc<IrqDomain>) {
+        self.domains.lock_irqsave().push(domain);
+    }
+
+    #[allow(dead_code)]
+    pub fn remove_domain(&self, domain: &Arc<IrqDomain>) {
+        let mut domains = self.domains.lock_irqsave();
+        let index = domains
+            .iter()
+            .position(|x| Arc::ptr_eq(x, domain))
+            .expect("domain not found");
+        domains.remove(index);
+    }
+
+    /// 获取默认的中断域
+    #[allow(dead_code)]
+    pub fn default_domain(&self) -> Option<Arc<IrqDomain>> {
+        self.inner.read().default_domain.clone()
+    }
+
+    /// 设置默认的中断域
+    ///
+    /// 在创建IRQ映射的时候,如果没有指定中断域,就会使用默认的中断域
+    pub fn set_default_domain(&self, domain: Arc<IrqDomain>) {
+        self.inner.write_irqsave().default_domain = Some(domain);
+    }
+
+    /// 将指定范围的硬件中断号与软件中断号一一对应的关联起来
+    ///
+    /// ## 参数
+    ///
+    /// - `domain` - 中断域
+    /// - `first_irq` - 起始软件中断号
+    /// - `first_hwirq` - 起始硬件中断号
+    /// - `count` - 数量
+    pub fn domain_associate_many(
+        &self,
+        domain: &Arc<IrqDomain>,
+        first_irq: IrqNumber,
+        first_hwirq: HardwareIrqNumber,
+        count: u32,
+    ) {
+        for i in 0..count {
+            if let Err(e) = self.domain_associate(domain, first_irq + i, first_hwirq + i) {
+                kwarn!("domain associate failed: {:?}, domain '{:?}' didn't like hwirq {} to virq {} mapping.", e, domain.name(), (first_hwirq + i).data(), (first_irq + i).data());
+            }
+        }
+    }
+
+    /// 将一个硬件中断号与一个软件中断号关联起来
+    ///
+    /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdomain.c#562
+    pub fn domain_associate(
+        &self,
+        domain: &Arc<IrqDomain>,
+        irq: IrqNumber,
+        hwirq: HardwareIrqNumber,
+    ) -> Result<(), SystemError> {
+        if hwirq >= domain.revmap.read_irqsave().hwirq_max {
+            kwarn!(
+                "hwirq {} is out of range for domain {:?}",
+                hwirq.data(),
+                domain.name()
+            );
+            return Err(SystemError::EINVAL);
+        }
+        let irq_data = irq_desc_manager()
+            .lookup(irq)
+            .ok_or_else(|| {
+                kwarn!("irq_desc not found for irq {}", irq.data());
+                SystemError::EINVAL
+            })?
+            .irq_data();
+        if irq_data.domain().is_some() {
+            kwarn!(
+                "irq {} is already associated with domain {:?}",
+                irq.data(),
+                irq_data.domain().unwrap().name()
+            );
+            return Err(SystemError::EINVAL);
+        }
+
+        let mut irq_data_guard = irq_data.inner();
+        irq_data_guard.set_hwirq(hwirq);
+        irq_data_guard.set_domain(Some(domain.clone()));
+        drop(irq_data_guard);
+        let r = domain.ops.map(&domain, hwirq, irq);
+        if let Err(e) = r {
+            if e != SystemError::ENOSYS {
+                if e != SystemError::EPERM {
+                    kinfo!("domain associate failed: {:?}, domain '{:?}' didn't like hwirq {} to virq {} mapping.", e, domain.name(), hwirq.data(), irq.data());
+                }
+                let mut irq_data_guard = irq_data.inner();
+                irq_data_guard.set_domain(None);
+                irq_data_guard.set_hwirq(HardwareIrqNumber::new(0));
+                return Err(e);
+            }
+        }
+
+        if domain.name().is_none() {
+            let chip = irq_data.chip_info_read_irqsave().chip();
+            domain.set_name(chip.name().to_string());
+        }
+
+        self.irq_domain_set_mapping(&domain, hwirq, irq_data);
+
+        irq_manager().irq_clear_status_flags(irq, IrqLineStatus::IRQ_NOREQUEST)?;
+
+        return Ok(());
+    }
+
+    fn irq_domain_set_mapping(
+        &self,
+        domain: &Arc<IrqDomain>,
+        hwirq: HardwareIrqNumber,
+        irq_data: Arc<IrqData>,
+    ) {
+        if domain.no_map() {
+            return;
+        }
+
+        domain.revmap.write_irqsave().insert(hwirq, irq_data);
+    }
+    /// 递归调用 domain_ops->activate 以激活中断
+    ///
+    /// ## 参数
+    ///
+    /// - irq_data: 与中断关联的最外层 irq_data
+    /// - reserve: 如果为true,则仅预留一个中断向量,而不是分配一个
+    ///
+    /// 这是调用 domain_ops->activate 以编程中断控制器的第二步,以便中断实际上可以被传递。
+    pub fn activate_irq(&self, irq_data: &Arc<IrqData>, reserve: bool) -> Result<(), SystemError> {
+        let mut r = Ok(());
+        if !irq_data.common_data().status().is_activated() {
+            r = self.do_activate_irq(Some(irq_data.clone()), reserve);
+        }
+
+        if !r.is_ok() {
+            irq_data.common_data().status().set_activated();
+        }
+
+        return r;
+    }
+
+    #[inline(never)]
+    fn do_activate_irq(
+        &self,
+        irq_data: Option<Arc<IrqData>>,
+        reserve: bool,
+    ) -> Result<(), SystemError> {
+        let mut r = Ok(());
+
+        if irq_data.is_some() && irq_data.as_ref().unwrap().domain().is_some() {
+            let domain = irq_data.as_ref().unwrap().domain().unwrap();
+
+            let irq_data = irq_data.unwrap();
+
+            let parent_data = irq_data.parent_data().map(|x| x.upgrade()).flatten();
+            if let Some(parent_data) = parent_data.clone() {
+                r = self.do_activate_irq(Some(parent_data), reserve);
+            }
+
+            if r.is_err() {
+                let tmpr = domain.ops.activate(&domain, &irq_data, reserve);
+                if let Err(e) = tmpr {
+                    if e != SystemError::ENOSYS && parent_data.is_some() {
+                        self.do_deactivate_irq(parent_data);
+                    }
+                }
+            }
+        }
+
+        return r;
+    }
+
+    fn do_deactivate_irq(&self, irq_data: Option<Arc<IrqData>>) {
+        if let Some(irq_data) = irq_data {
+            if let Some(domain) = irq_data.domain() {
+                domain.ops.deactivate(&domain, &irq_data);
+                let pp = irq_data.parent_data().map(|x| x.upgrade()).flatten();
+
+                if pp.is_some() {
+                    self.do_deactivate_irq(pp);
+                }
+            }
+        }
+    }
+}
+
+struct InnerIrqDomainManager {
+    default_domain: Option<Arc<IrqDomain>>,
+}
+
 /// 中断域
 ///
 /// 用于把硬件中断号翻译为软件中断号的映射的对象
@@ -28,7 +288,7 @@ use super::{
 pub struct IrqDomain {
     /// 中断域的名字 (二选一)
     name: Option<&'static str>,
-    allocated_name: Option<String>,
+    allocated_name: SpinLock<Option<String>>,
     /// 中断域的操作
     ops: &'static dyn IrqDomainOps,
     inner: SpinLock<InnerIrqDomain>,
@@ -63,6 +323,8 @@ impl IrqDomain {
         ops: &'static dyn IrqDomainOps,
         flags: IrqDomainFlags,
         bus_token: IrqDomainBusToken,
+        irq_max: IrqNumber,
+        hwirq_max: HardwareIrqNumber,
     ) -> Option<Arc<Self>> {
         if name.is_none() && allocated_name.is_none() {
             return None;
@@ -70,7 +332,7 @@ impl IrqDomain {
 
         let x = IrqDomain {
             name,
-            allocated_name,
+            allocated_name: SpinLock::new(allocated_name),
             ops,
             inner: SpinLock::new(InnerIrqDomain {
                 flags,
@@ -82,20 +344,67 @@ impl IrqDomain {
             }),
             revmap: RwLock::new(IrqDomainRevMap {
                 map: HashMap::new(),
-                hwirq_max: HardwareIrqNumber::new(0),
+                hwirq_max,
+                irq_max,
             }),
         };
 
         return Some(Arc::new(x));
     }
+
+    /// 中断域是否不对中断号进行转换
+    pub fn no_map(&self) -> bool {
+        self.inner
+            .lock_irqsave()
+            .flags
+            .contains(IrqDomainFlags::NO_MAP)
+    }
+
+    #[allow(dead_code)]
+    fn set_hwirq_max(&self, hwirq_max: HardwareIrqNumber) {
+        self.revmap.write_irqsave().hwirq_max = hwirq_max;
+    }
+
+    pub fn name(&self) -> Option<String> {
+        if let Some(name) = self.name {
+            return Some(name.to_string());
+        }
+        return self.allocated_name.lock_irqsave().clone();
+    }
+
+    pub fn set_name(&self, name: String) {
+        *self.allocated_name.lock_irqsave() = Some(name);
+    }
+
+    /// The number of mapped interrupts
+    pub fn map_count(&self) -> u32 {
+        self.revmap.read().map.len() as u32
+    }
 }
 
 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdomain.h#190
 #[allow(dead_code)]
 #[derive(Debug)]
 struct IrqDomainRevMap {
-    map: HashMap<HardwareIrqNumber, IrqNumber>,
+    map: HashMap<HardwareIrqNumber, Arc<IrqData>>,
     hwirq_max: HardwareIrqNumber,
+    irq_max: IrqNumber,
+}
+
+impl IrqDomainRevMap {
+    fn insert(&mut self, hwirq: HardwareIrqNumber, irq_data: Arc<IrqData>) {
+        self.map.insert(hwirq, irq_data);
+    }
+
+    #[allow(dead_code)]
+    fn remove(&mut self, hwirq: HardwareIrqNumber) {
+        self.map.remove(&hwirq);
+    }
+
+    #[allow(dead_code)]
+    fn lookup(&self, hwirq: HardwareIrqNumber) -> Option<Arc<IrqData>> {
+        self.map.get(&hwirq).cloned()
+    }
 }
 
 bitflags! {
@@ -156,15 +465,30 @@ pub trait IrqDomainOps: Debug + Send + Sync {
 
     /// 创建或更新一个虚拟中断号与一个硬件中断号之间的映射。
     /// 对于给定的映射,这只会被调用一次。
+    ///
+    /// 如果没有实现这个方法,那么就会返回`ENOSYS`
     fn map(
         &self,
-        irq_domain: &Arc<IrqDomain>,
-        hwirq: HardwareIrqNumber,
-        virq: IrqNumber,
-    ) -> Result<(), SystemError>;
+        _irq_domain: &Arc<IrqDomain>,
+        _hwirq: HardwareIrqNumber,
+        _virq: IrqNumber,
+    ) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
 
     /// 删除一个虚拟中断号与一个硬件中断号之间的映射。
     fn unmap(&self, irq_domain: &Arc<IrqDomain>, virq: IrqNumber);
+
+    fn activate(
+        &self,
+        _domain: &Arc<IrqDomain>,
+        _irq_data: &Arc<IrqData>,
+        _reserve: bool,
+    ) -> Result<(), SystemError> {
+        Err(SystemError::ENOSYS)
+    }
+
+    fn deactivate(&self, _domain: &Arc<IrqDomain>, _irq_data: &Arc<IrqData>) {}
 }
 
 #[allow(dead_code)]

+ 1093 - 0
kernel/src/exception/manage.rs

@@ -0,0 +1,1093 @@
+use core::ops::{BitXor, Deref, DerefMut};
+
+use alloc::{string::String, sync::Arc};
+
+use system_error::SystemError;
+
+use crate::{
+    driver::base::device::DeviceId,
+    exception::{
+        irqchip::IrqChipSetMaskResult,
+        irqdesc::{irq_desc_manager, InnerIrqDesc, IrqAction},
+    },
+    libs::{cpumask::CpuMask, spinlock::SpinLockGuard},
+    process::{kthread::KernelThreadMechanism, ProcessManager},
+    smp::cpu::ProcessorId,
+};
+
+use super::{
+    dummychip::no_irq_chip,
+    irqchip::IrqChipFlags,
+    irqdata::{IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
+    irqdesc::{InnerIrqAction, IrqDesc, IrqDescState, IrqHandleFlags, IrqHandler, IrqReturn},
+    irqdomain::irq_domain_manager,
+    IrqNumber,
+};
+
+lazy_static! {
+    /// 默认的中断亲和性
+    static ref IRQ_DEFAULT_AFFINITY: CpuMask = {
+        let mut mask = CpuMask::new();
+        // 默认情况下,中断处理程序将在第一个处理器上运行
+        mask.set(ProcessorId::new(0), true);
+        mask
+    };
+}
+
+pub fn irq_manager() -> &'static IrqManager {
+    &IrqManager
+}
+
+/// 中断管理器
+pub struct IrqManager;
+
+impl IrqManager {
+    pub const IRQ_RESEND: bool = true;
+    #[allow(dead_code)]
+    pub const IRQ_NORESEND: bool = false;
+    #[allow(dead_code)]
+    pub const IRQ_START_FORCE: bool = true;
+    pub const IRQ_START_COND: bool = false;
+
+    /// 在中断线上添加一个处理函数
+    ///
+    /// ## 参数
+    ///
+    /// - irq: 虚拟中断号(中断线号)
+    /// - name: 生成该中断的设备名称
+    /// - handler: 中断处理函数
+    /// - flags: 中断处理标志
+    /// - dev_id: 一个用于标识设备的cookie
+    pub fn request_irq(
+        &self,
+        irq: IrqNumber,
+        name: String,
+        handler: &'static dyn IrqHandler,
+        flags: IrqHandleFlags,
+        dev_id: Option<Arc<DeviceId>>,
+    ) -> Result<(), SystemError> {
+        return self.request_threaded_irq(irq, Some(handler), None, flags, name, dev_id);
+    }
+
+    /// 在中断线上添加一个处理函数(可以是线程化的中断)
+    ///
+    /// ## 参数
+    ///
+    /// - irq: 虚拟中断号
+    /// - handler: 当中断发生时将被调用的函数,是
+    ///     线程化中断的初级处理程序。如果handler为`None`并且thread_fn不为`None`,
+    ///    将安装默认的初级处理程序
+    /// - thread_fn: 在中断处理程序线程中调用的函数. 如果为`None`,则不会创建irq线程
+    /// - flags: 中断处理标志
+    ///     - IRQF_SHARED: 中断是共享的
+    ///     - IRQF_TRIGGER*: 指定中断触发方式
+    ///     - IRQF_ONESHOT: 在thread_fn中运行时,中断线被遮蔽
+    /// - dev_name: 生成该中断的设备名称
+    /// - dev_id: 一个用于标识设备的cookie
+    ///
+    /// ## 说明
+    ///
+    /// 此调用分配中断资源并启用中断线和IRQ处理。
+    /// 从这一点开始,您的处理程序函数可能会被调用。
+    /// 因此,您必须确保首先初始化您的硬件,
+    /// 并确保以正确的顺序设置中断处理程序。
+    ///
+    /// 如果您想为您的设备设置线程化中断处理程序
+    /// 则需要提供@handler和@thread_fn。@handler仍然
+    /// 在硬中断上下文中调用,并且必须检查
+    /// 中断是否来自设备。如果是,它需要禁用设备上的中断
+    /// 并返回IRQ_WAKE_THREAD,这将唤醒处理程序线程并运行
+    /// @thread_fn。这种拆分处理程序设计是为了支持
+    /// 共享中断。
+    ///
+    /// dev_id必须是全局唯一的。通常使用设备数据结构的地址或者uuid
+    /// 作为cookie。由于处理程序接收这个值,因此使用它是有意义的。
+    ///
+    /// 如果您的中断是共享的,您必须传递一个非NULL的dev_id
+    /// 因为当释放中断时需要它。
+    pub fn request_threaded_irq(
+        &self,
+        irq: IrqNumber,
+        mut handler: Option<&'static dyn IrqHandler>,
+        thread_fn: Option<&'static dyn IrqHandler>,
+        flags: IrqHandleFlags,
+        dev_name: String,
+        dev_id: Option<Arc<DeviceId>>,
+    ) -> Result<(), SystemError> {
+        if irq == IrqNumber::IRQ_NOTCONNECTED {
+            return Err(SystemError::ENOTCONN);
+        }
+
+        // 逻辑检查:共享中断必须传入一个真正的设备ID,
+        // 否则后来我们将难以确定哪个中断是哪个(会搞乱中断释放逻辑等)。
+        // 此外,共享中断与禁用自动使能不相符。 共享中断可能在仍然禁用时请求它,然后永远等待中断。
+        // 另外,IRQF_COND_SUSPEND 仅适用于共享中断,并且它不能与 IRQF_NO_SUSPEND 同时设置。
+
+        if ((flags.contains(IrqHandleFlags::IRQF_SHARED)) && dev_id.is_none())
+            || ((flags.contains(IrqHandleFlags::IRQF_SHARED))
+                && (flags.contains(IrqHandleFlags::IRQF_NO_AUTOEN)))
+            || (!(flags.contains(IrqHandleFlags::IRQF_SHARED))
+                && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
+            || ((flags.contains(IrqHandleFlags::IRQF_NO_SUSPEND))
+                && (flags.contains(IrqHandleFlags::IRQF_COND_SUSPEND)))
+        {
+            return Err(SystemError::EINVAL);
+        }
+        let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
+        if !desc.can_request() {
+            kwarn!("desc {} can not request", desc.irq().data());
+            return Err(SystemError::EINVAL);
+        }
+
+        if handler.is_none() {
+            if thread_fn.is_none() {
+                // 不允许中断处理函数和线程处理函数都为空
+                return Err(SystemError::EINVAL);
+            }
+
+            // 如果中断处理函数为空,线程处理函数不为空,则使用默认的中断处理函数
+            handler = Some(&DefaultPrimaryIrqHandler);
+        }
+
+        let irqaction = IrqAction::new(irq, dev_name, handler, thread_fn);
+
+        let mut action_guard = irqaction.inner();
+        *action_guard.flags_mut() = flags;
+        *action_guard.dev_id_mut() = dev_id;
+        drop(action_guard);
+
+        return self.inner_setup_irq(irq, irqaction, desc);
+    }
+
+    /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1497
+    #[inline(never)]
+    fn inner_setup_irq(
+        &self,
+        irq: IrqNumber,
+        action: Arc<IrqAction>,
+        desc: Arc<IrqDesc>,
+    ) -> Result<(), SystemError> {
+        // ==== 定义错误处理函数 ====
+        let err_out_thread =
+            |e: SystemError, mut action_guard: SpinLockGuard<'_, InnerIrqAction>| -> SystemError {
+                if let Some(thread_pcb) = action_guard.thread() {
+                    action_guard.set_thread(None);
+                    KernelThreadMechanism::stop(&thread_pcb).ok();
+                }
+
+                if let Some(secondary) = action_guard.secondary() {
+                    let mut secondary_guard = secondary.inner();
+                    if let Some(thread_pcb) = secondary_guard.thread() {
+                        secondary_guard.set_thread(None);
+                        KernelThreadMechanism::stop(&thread_pcb).ok();
+                    }
+                }
+                return e;
+            };
+
+        let err_out_bus_unlock = |e: SystemError,
+                                  desc: Arc<IrqDesc>,
+                                  req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
+                                  action_guard: SpinLockGuard<'_, InnerIrqAction>|
+         -> SystemError {
+            desc.chip_bus_sync_unlock();
+            drop(req_mutex_guard);
+            return err_out_thread(e, action_guard);
+        };
+
+        let err_out_unlock = |e: SystemError,
+                              desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
+                              desc: Arc<IrqDesc>,
+                              req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>,
+                              action_guard: SpinLockGuard<'_, InnerIrqAction>|
+         -> SystemError {
+            drop(desc_guard);
+            return err_out_bus_unlock(e, desc, req_mutex_guard, action_guard);
+        };
+
+        let err_out_mismatch = |old_action_guard: SpinLockGuard<'_, InnerIrqAction>,
+                                desc_guard: SpinLockGuard<'_, InnerIrqDesc>,
+                                action_guard: SpinLockGuard<'_, InnerIrqAction>,
+                                desc: Arc<IrqDesc>,
+                                req_mutex_guard: crate::libs::mutex::MutexGuard<'_, ()>|
+         -> SystemError {
+            if !action_guard
+                .flags()
+                .contains(IrqHandleFlags::IRQF_PROBE_SHARED)
+            {
+                kerror!("Flags mismatch for irq {} (name: {}, flags: {:?}). old action name: {}, old flags: {:?}", irq.data(), action_guard.name(), action_guard.flags(), old_action_guard.name(), old_action_guard.flags());
+            }
+            return err_out_unlock(
+                SystemError::EBUSY,
+                desc_guard,
+                desc,
+                req_mutex_guard,
+                action_guard,
+            );
+        };
+
+        // ===== 代码开始 =====
+
+        if Arc::ptr_eq(
+            &desc.irq_data().chip_info_read_irqsave().chip(),
+            &no_irq_chip(),
+        ) {
+            return Err(SystemError::ENOSYS);
+        }
+
+        let mut action_guard = action.inner();
+        if !action_guard.flags().trigger_type_specified() {
+            // 如果没有指定触发类型,则使用默认的触发类型
+            action_guard
+                .flags_mut()
+                .insert_trigger_type(desc.irq_data().common_data().trigger_type())
+        }
+
+        let nested = desc.nested_thread();
+
+        if nested {
+            if action_guard.thread_fn().is_none() {
+                return Err(SystemError::EINVAL);
+            }
+
+            action_guard.set_handler(Some(&IrqNestedPrimaryHandler));
+        } else {
+            if desc.can_thread() {
+                self.setup_forced_threading(action_guard.deref_mut())?;
+            }
+        }
+
+        // 如果具有中断线程处理程序,并且中断不是嵌套的,则设置中断线程
+        if action_guard.thread_fn().is_some() && !nested {
+            self.setup_irq_thread(irq, action_guard.deref(), false)?;
+
+            if let Some(secondary) = action_guard.secondary() {
+                let secondary_guard = secondary.inner();
+                if let Err(e) = self.setup_irq_thread(irq, secondary_guard.deref(), true) {
+                    return Err(err_out_thread(e, action_guard));
+                }
+            }
+        }
+
+        // Drivers are often written to work w/o knowledge about the
+        // underlying irq chip implementation, so a request for a
+        // threaded irq without a primary hard irq context handler
+        // requires the ONESHOT flag to be set. Some irq chips like
+        // MSI based interrupts are per se one shot safe. Check the
+        // chip flags, so we can avoid the unmask dance at the end of
+        // the threaded handler for those.
+
+        if desc
+            .irq_data()
+            .chip_info_read_irqsave()
+            .chip()
+            .flags()
+            .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
+        {
+            *action_guard.flags_mut() &= !IrqHandleFlags::IRQF_ONESHOT;
+        }
+
+        // Protects against a concurrent __free_irq() call which might wait
+        // for synchronize_hardirq() to complete without holding the optional
+        // chip bus lock and desc->lock. Also protects against handing out
+        // a recycled oneshot thread_mask bit while it's still in use by
+        // its previous owner.
+        let req_mutex_guard = desc.request_mutex_lock();
+
+        // Acquire bus lock as the irq_request_resources() callback below
+        // might rely on the serialization or the magic power management
+        // functions which are abusing the irq_bus_lock() callback,
+        desc.chip_bus_lock();
+
+        // 如果当前中断线上还没有irqaction, 则先为中断线申请资源
+        if desc.actions().is_empty() {
+            if let Err(e) = self.irq_request_resources(desc.clone()) {
+                kerror!(
+                    "Failed to request resources for {} (irq {}) on irqchip {}, error {:?}",
+                    action_guard.name(),
+                    irq.data(),
+                    desc.irq_data().chip_info_read_irqsave().chip().name(),
+                    e
+                );
+                return Err(err_out_bus_unlock(
+                    e,
+                    desc.clone(),
+                    req_mutex_guard,
+                    action_guard,
+                ));
+            }
+        }
+
+        let mut desc_inner_guard: SpinLockGuard<'_, InnerIrqDesc> = desc.inner();
+
+        // 标记当前irq是否是共享的
+        let mut irq_shared = false;
+        if desc_inner_guard.actions().is_empty() == false {
+            // 除非双方都同意并且是相同类型(级别、边沿、极性),否则不能共享中断。
+            // 因此,两个标志字段都必须设置IRQF_SHARED,并且设置触发类型的位必须匹配。
+            // 另外,所有各方都必须就ONESHOT达成一致。
+            // NMI用途的中断线不能共享。
+            if desc_inner_guard
+                .internal_state()
+                .contains(IrqDescState::IRQS_NMI)
+            {
+                kerror!(
+                    "Invalid attempt to share NMI for {} (irq {}) on irqchip {}",
+                    action_guard.name(),
+                    irq.data(),
+                    desc_inner_guard
+                        .irq_data()
+                        .chip_info_read_irqsave()
+                        .chip()
+                        .name()
+                );
+                return Err(err_out_unlock(
+                    SystemError::EINVAL,
+                    desc_inner_guard,
+                    desc.clone(),
+                    req_mutex_guard,
+                    action_guard,
+                ));
+            }
+
+            let irq_data = desc_inner_guard.irq_data();
+
+            let old_trigger_type: super::irqdata::IrqLineStatus;
+            let status = irq_data.common_data().status();
+            if status.trigger_type_was_set() {
+                old_trigger_type = status.trigger_type();
+            } else {
+                old_trigger_type = action_guard.flags().trigger_type();
+                irq_data.common_data().set_trigger_type(old_trigger_type);
+            }
+
+            let old = &desc_inner_guard.actions()[0].clone();
+            let old_guard = old.inner();
+
+            if ((old_guard
+                .flags()
+                .intersection(*action_guard.flags())
+                .contains(IrqHandleFlags::IRQF_SHARED))
+                == false)
+                || (old_trigger_type != (action_guard.flags().trigger_type()))
+                || ((old_guard.flags().bitxor(*action_guard.flags()))
+                    .contains(IrqHandleFlags::IRQF_ONESHOT))
+            {
+                return Err(err_out_mismatch(
+                    old_guard,
+                    desc_inner_guard,
+                    action_guard,
+                    desc.clone(),
+                    req_mutex_guard,
+                ));
+            }
+
+            // all handlers must agree on per-cpuness
+            if *old_guard.flags() & IrqHandleFlags::IRQF_PERCPU
+                != *action_guard.flags() & IrqHandleFlags::IRQF_PERCPU
+            {
+                return Err(err_out_mismatch(
+                    old_guard,
+                    desc_inner_guard,
+                    action_guard,
+                    desc.clone(),
+                    req_mutex_guard,
+                ));
+            }
+
+            irq_shared = true;
+        }
+
+        if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
+            // todo: oneshot
+        } else if action_guard.handler().is_some_and(|h| {
+            h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id()
+        }) && desc_inner_guard
+            .irq_data()
+            .chip_info_read_irqsave()
+            .chip()
+            .flags()
+            .contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
+            == false
+        {
+            // 请求中断时 hander = NULL,因此我们为其使用默认的主处理程序。
+            // 但它没有设置ONESHOT标志。与电平触发中断结合时,
+            // 这是致命的,因为默认的主处理程序只是唤醒线程,然后重新启用 irq 线路,
+            // 但设备仍然保持电平中断生效。周而复始....
+            // 虽然这对于边缘类型中断来说可行,但我们为了安全起见,不加条件地拒绝,
+            // 因为我们不能确定这个中断实际上具有什么类型。
+            // 由于底层芯片实现可能会覆盖它们,所以类型标志并不可靠.
+
+            kerror!(
+                "Requesting irq {} without a handler, and ONESHOT flags not set for irqaction: {}",
+                irq.data(),
+                action_guard.name()
+            );
+            return Err(err_out_unlock(
+                SystemError::EINVAL,
+                desc_inner_guard,
+                desc.clone(),
+                req_mutex_guard,
+                action_guard,
+            ));
+        }
+
+        // 第一次在当前irqdesc上注册中断处理函数
+        if !irq_shared {
+            // 设置中断触发方式
+            if action_guard.flags().trigger_type_specified() {
+                let trigger_type = action_guard.flags().trigger_type();
+                if let Err(e) =
+                    self.do_set_irq_trigger(desc.clone(), &mut desc_inner_guard, trigger_type)
+                {
+                    return Err(err_out_unlock(
+                        e,
+                        desc_inner_guard,
+                        desc.clone(),
+                        req_mutex_guard,
+                        action_guard,
+                    ));
+                }
+            }
+
+            // 激活中断。这种激活必须独立于IRQ_NOAUTOEN进行*desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_NOREQUEST;uest.
+            if let Err(e) = self.irq_activate(desc.clone(), &mut desc_inner_guard) {
+                return Err(err_out_unlock(
+                    e,
+                    desc_inner_guard,
+                    desc.clone(),
+                    req_mutex_guard,
+                    action_guard,
+                ));
+            }
+
+            *desc_inner_guard.internal_state_mut() &= !(IrqDescState::IRQS_AUTODETECT
+                | IrqDescState::IRQS_SPURIOUS_DISABLED
+                | IrqDescState::IRQS_ONESHOT
+                | IrqDescState::IRQS_WAITING);
+            desc_inner_guard
+                .common_data()
+                .clear_status(IrqStatus::IRQD_IRQ_INPROGRESS);
+
+            if action_guard.flags().contains(IrqHandleFlags::IRQF_PERCPU) {
+                desc_inner_guard
+                    .common_data()
+                    .insert_status(IrqStatus::IRQD_PER_CPU);
+                desc_inner_guard.line_status_set_per_cpu();
+
+                if action_guard.flags().contains(IrqHandleFlags::IRQF_NO_DEBUG) {
+                    desc_inner_guard.line_status_set_no_debug();
+                }
+            }
+
+            if action_guard.flags().contains(IrqHandleFlags::IRQF_ONESHOT) {
+                *desc_inner_guard.internal_state_mut() |= IrqDescState::IRQS_ONESHOT;
+            }
+
+            // 如果有要求的话,则忽略IRQ的均衡。
+            if action_guard
+                .flags()
+                .contains(IrqHandleFlags::IRQF_NOBALANCING)
+            {
+                todo!("IRQF_NO_BALANCING");
+            }
+
+            if !action_guard
+                .flags()
+                .contains(IrqHandleFlags::IRQF_NO_AUTOEN)
+                && desc_inner_guard.can_autoenable()
+            {
+                // 如果没有设置IRQF_NOAUTOEN,则自动使能中断
+                self.irq_startup(
+                    desc.clone(),
+                    &mut desc_inner_guard,
+                    Self::IRQ_RESEND,
+                    Self::IRQ_START_COND,
+                )
+                .ok();
+            } else {
+                // 共享中断与禁用自动使能不太兼容。
+                // 共享中断可能在它仍然被禁用时请求它,然后永远等待中断。
+
+                static mut WARNED: bool = false;
+                if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) {
+                    if unsafe { !WARNED } {
+                        kwarn!(
+                            "Shared interrupt {} for {} requested but not auto enabled",
+                            irq.data(),
+                            action_guard.name()
+                        );
+                        unsafe { WARNED = true };
+                    }
+                }
+
+                desc_inner_guard.set_depth(1);
+            }
+        } else if action_guard.flags().trigger_type_specified() {
+            let new_trigger_type = action_guard.flags().trigger_type();
+            let old_trigger_type = desc_inner_guard.common_data().trigger_type();
+            if new_trigger_type != old_trigger_type {
+                kwarn!("Irq {} uses trigger type: {old_trigger_type:?}, but requested trigger type: {new_trigger_type:?}.", irq.data());
+            }
+        }
+
+        // 在队列末尾添加新的irqaction
+        desc_inner_guard.add_action(action.clone());
+
+        // 检查我们是否曾经通过虚构的中断处理程序禁用过irq。重新启用它并再给它一次机会。
+        if irq_shared
+            && desc_inner_guard
+                .internal_state()
+                .contains(IrqDescState::IRQS_SPURIOUS_DISABLED)
+        {
+            desc_inner_guard
+                .internal_state_mut()
+                .remove(IrqDescState::IRQS_SPURIOUS_DISABLED);
+            self.do_enable_irq(desc.clone(), &mut desc_inner_guard).ok();
+        }
+
+        drop(desc_inner_guard);
+        desc.chip_bus_sync_unlock();
+        drop(req_mutex_guard);
+
+        drop(action_guard);
+        self.wake_up_and_wait_for_irq_thread_ready(&desc, Some(action.clone()));
+        self.wake_up_and_wait_for_irq_thread_ready(&desc, action.inner().secondary());
+        return Ok(());
+    }
+
+    /// 唤醒中断线程并等待中断线程准备好
+    ///
+    /// ## 参数
+    ///
+    /// - desc: 中断描述符
+    /// - action: 要唤醒的中断处理函数
+    ///
+    /// ## 锁
+    ///
+    /// 进入当前函数时,`action`的锁需要被释放
+    fn wake_up_and_wait_for_irq_thread_ready(
+        &self,
+        desc: &Arc<IrqDesc>,
+        action: Option<Arc<IrqAction>>,
+    ) {
+        if action.is_none() {
+            return;
+        }
+
+        let action = action.unwrap();
+
+        let action_guard = action.inner();
+        if action_guard.thread().is_none() {
+            return;
+        }
+
+        ProcessManager::wakeup(&action_guard.thread().unwrap()).ok();
+        drop(action_guard);
+        action
+            .thread_completion()
+            .wait_for_completion()
+            .map_err(|e| {
+                kwarn!(
+                    "Failed to wait for irq thread ready for {} (irq {:?}), error {:?}",
+                    action.inner().name(),
+                    desc.irq_data().irq(),
+                    e
+                );
+            })
+            .ok();
+    }
+
+    pub(super) fn irq_activate(
+        &self,
+        _desc: Arc<IrqDesc>,
+        desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+    ) -> Result<(), SystemError> {
+        let irq_data = desc_inner_guard.irq_data();
+
+        if !desc_inner_guard.common_data().status().affinity_managed() {
+            return irq_domain_manager().activate_irq(irq_data, false);
+        }
+
+        return Ok(());
+    }
+
+    /// 设置CPU亲和性并开启中断
+    pub(super) fn irq_startup(
+        &self,
+        desc: Arc<IrqDesc>,
+        desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+        resend: bool,
+        force: bool,
+    ) -> Result<(), SystemError> {
+        let mut ret = Ok(());
+        let irq_data = desc_inner_guard.irq_data().clone();
+        let affinity = desc_inner_guard.common_data().affinity();
+        desc_inner_guard.set_depth(0);
+
+        if desc_inner_guard.common_data().status().started() {
+            self.irq_enable(desc_inner_guard);
+        } else {
+            match self.__irq_startup_managed(desc_inner_guard, &affinity, force) {
+                IrqStartupResult::Normal => {
+                    if irq_data
+                        .chip_info_read_irqsave()
+                        .chip()
+                        .flags()
+                        .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
+                    {
+                        self.irq_setup_affinity(&desc, desc_inner_guard).ok();
+                    }
+
+                    ret = self.__irq_startup(desc_inner_guard);
+
+                    if !irq_data
+                        .chip_info_read_irqsave()
+                        .chip()
+                        .flags()
+                        .contains(IrqChipFlags::IRQCHIP_AFFINITY_PRE_STARTUP)
+                    {
+                        self.irq_setup_affinity(&desc, desc_inner_guard).ok();
+                    }
+                }
+                IrqStartupResult::Managed => {
+                    self.irq_do_set_affinity(&irq_data, &desc_inner_guard, &affinity, false)
+                        .ok();
+                    ret = self.__irq_startup(desc_inner_guard);
+                }
+                IrqStartupResult::Abort => {
+                    desc_inner_guard
+                        .common_data()
+                        .insert_status(IrqStatus::IRQD_MANAGED_SHUTDOWN);
+                    return Ok(());
+                }
+            }
+        }
+
+        if resend {
+            if let Err(e) = self.irq_check_and_resend(desc_inner_guard, false) {
+                kerror!(
+                    "Failed to check and resend irq {}, error {:?}",
+                    irq_data.irq().data(),
+                    e
+                );
+            }
+        }
+
+        return ret;
+    }
+
+    pub fn irq_enable(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
+        let common_data = desc_inner_guard.common_data();
+        if !common_data.status().disabled() {
+            self.unmask_irq(desc_inner_guard);
+        } else {
+            common_data.clear_disabled();
+
+            let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
+
+            if let Err(e) = chip.irq_enable(&desc_inner_guard.irq_data()) {
+                if e == SystemError::ENOSYS {
+                    self.unmask_irq(desc_inner_guard);
+                }
+                kerror!(
+                    "Failed to enable irq {} (name: {:?}), error {:?}",
+                    desc_inner_guard.irq_data().irq().data(),
+                    desc_inner_guard.name(),
+                    e
+                );
+            } else {
+                common_data.clear_masked();
+            }
+        }
+    }
+
+    /// 自动设置中断的CPU亲和性
+    ///
+    ///  
+    /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c#589
+    pub fn irq_setup_affinity(
+        &self,
+        _desc: &Arc<IrqDesc>,
+        desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+    ) -> Result<(), SystemError> {
+        let common_data = desc_inner_guard.common_data();
+        if !desc_inner_guard.can_set_affinity() {
+            return Ok(());
+        }
+
+        let mut to_set = IRQ_DEFAULT_AFFINITY.clone();
+        if common_data.status().affinity_managed()
+            || common_data.status().contains(IrqStatus::IRQD_AFFINITY_SET)
+        {
+            // FIXME: 要判断affinity跟已上线的CPU是否有交集
+
+            let irq_aff = common_data.affinity();
+            if irq_aff.is_empty() {
+                common_data.clear_status(IrqStatus::IRQD_AFFINITY_SET);
+            } else {
+                to_set = irq_aff;
+            }
+        }
+
+        // FIXME: 求to_set和在线CPU的交集
+
+        return self.irq_do_set_affinity(
+            desc_inner_guard.irq_data(),
+            &desc_inner_guard,
+            &to_set,
+            false,
+        );
+    }
+
+    pub fn irq_do_set_affinity(
+        &self,
+        irq_data: &Arc<IrqData>,
+        desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
+        cpumask: &CpuMask,
+        force: bool,
+    ) -> Result<(), SystemError> {
+        let chip = irq_data.chip_info_read_irqsave().chip();
+        if !chip.can_set_affinity() {
+            return Err(SystemError::EINVAL);
+        }
+
+        // todo: 处理CPU中断隔离相关的逻辑
+
+        let common_data = desc_inner_guard.common_data();
+        let r;
+        if !force && !cpumask.is_empty() {
+            r = chip.irq_set_affinity(irq_data, &cpumask, force);
+        } else if force {
+            r = chip.irq_set_affinity(irq_data, &cpumask, force);
+        } else {
+            return Err(SystemError::EINVAL);
+        }
+
+        let mut ret = Ok(());
+        if let Ok(rs) = r {
+            match rs {
+                IrqChipSetMaskResult::SetMaskOk | IrqChipSetMaskResult::SetMaskOkDone => {
+                    common_data.set_affinity(cpumask.clone());
+                }
+                IrqChipSetMaskResult::SetMaskOkNoChange => {
+
+                    // irq_validate_effective_affinity(data);
+                    // irq_set_thread_affinity(desc);
+                }
+            }
+        } else {
+            ret = Err(r.unwrap_err());
+        }
+
+        return ret;
+    }
+
+    fn __irq_startup(
+        &self,
+        desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
+    ) -> Result<(), SystemError> {
+        let common_data = desc_inner_guard.common_data();
+
+        if let Err(e) = desc_inner_guard
+            .irq_data()
+            .chip_info_read_irqsave()
+            .chip()
+            .irq_startup(desc_inner_guard.irq_data())
+        {
+            if e == SystemError::ENOSYS {
+                self.irq_enable(desc_inner_guard);
+            } else {
+                return Err(e);
+            }
+        } else {
+            common_data.clear_disabled();
+            common_data.clear_masked();
+        }
+
+        common_data.set_started();
+
+        return Ok(());
+    }
+
+    fn __irq_startup_managed(
+        &self,
+        desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
+        _affinity: &CpuMask,
+        _force: bool,
+    ) -> IrqStartupResult {
+        let irq_data = desc_inner_guard.irq_data();
+        let common_data = desc_inner_guard.common_data();
+
+        if !common_data.status().affinity_managed() {
+            return IrqStartupResult::Normal;
+        }
+
+        common_data.clear_managed_shutdown();
+
+        /*
+            - 检查Affinity掩码是否包括所有的在线CPU。如果是,这意味着有代码试图在管理的中断上使用enable_irq(),
+                这可能是非法的。在这种情况下,如果force不是真值,函数会返回IRQ_STARTUP_ABORT,表示中断处理应该被放弃。
+            - 如果Affinity掩码中没有任何在线的CPU,那么中断请求是不可用的,因为没有任何CPU可以处理它。
+                在这种情况下,如果force不是真值,函数同样会返回IRQ_STARTUP_ABORT。
+            - 如果以上条件都不满足,尝试激活中断,并将其设置为管理模式。这是通过调用 `irq_domain_manager().activate_irq()` 函数来实现的。
+                如果这个调用失败,表示有保留的资源无法访问,函数会返回IRQ_STARTUP_ABORT。
+            - 如果一切顺利,函数会返回IRQ_STARTUP_MANAGED,表示中断已经被成功管理并激活。
+        */
+
+        // if (cpumask_any_and(aff, cpu_online_mask) >= nr_cpu_ids) {
+        //     /*
+        //      * Catch code which fiddles with enable_irq() on a managed
+        //      * and potentially shutdown IRQ. Chained interrupt
+        //      * installment or irq auto probing should not happen on
+        //      * managed irqs either.
+        //      */
+        //     if (WARN_ON_ONCE(force))
+        //         return IRQ_STARTUP_ABORT;
+        //     /*
+        //      * The interrupt was requested, but there is no online CPU
+        //      * in it's affinity mask. Put it into managed shutdown
+        //      * state and let the cpu hotplug mechanism start it up once
+        //      * a CPU in the mask becomes available.
+        //      */
+        //     return IRQ_STARTUP_ABORT;
+        // }
+
+        let r = irq_domain_manager().activate_irq(irq_data, false);
+        if r.is_err() {
+            return IrqStartupResult::Abort;
+        }
+
+        return IrqStartupResult::Managed;
+    }
+
+    pub fn do_enable_irq(
+        &self,
+        _desc: Arc<IrqDesc>,
+        _desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+    ) -> Result<(), SystemError> {
+        // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#776
+        todo!("do_enable_irq")
+    }
+
+    #[inline(never)]
+    pub fn do_set_irq_trigger(
+        &self,
+        _desc: Arc<IrqDesc>,
+        desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+        mut trigger_type: IrqLineStatus,
+    ) -> Result<(), SystemError> {
+        let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
+        let mut to_unmask = false;
+
+        if !chip.can_set_flow_type() {
+            // kdebug!(
+            //     "No set_irq_type function for irq {}, chip {}",
+            //     desc_inner_guard.irq_data().irq().data(),
+            //     chip.name()
+            // );
+            return Ok(());
+        }
+
+        if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) {
+            if desc_inner_guard.common_data().status().masked() == false {
+                self.mask_irq(desc_inner_guard.irq_data());
+            }
+            if desc_inner_guard.common_data().status().disabled() == false {
+                to_unmask = true;
+            }
+        }
+
+        trigger_type &= IrqLineStatus::IRQ_TYPE_SENSE_MASK;
+
+        let r = chip.irq_set_type(desc_inner_guard.irq_data(), trigger_type);
+        let ret;
+        if let Ok(rs) = r {
+            match rs {
+                IrqChipSetMaskResult::SetMaskOk | IrqChipSetMaskResult::SetMaskOkDone => {
+                    let common_data = desc_inner_guard.common_data();
+                    common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK);
+                    let mut irqstatus = IrqStatus::empty();
+                    irqstatus.set_trigger_type(trigger_type);
+                    common_data.insert_status(irqstatus);
+                }
+                IrqChipSetMaskResult::SetMaskOkNoChange => {
+                    let flags = desc_inner_guard.common_data().trigger_type();
+                    desc_inner_guard.set_trigger_type(flags);
+                    desc_inner_guard
+                        .common_data()
+                        .clear_status(IrqStatus::IRQD_LEVEL);
+                    desc_inner_guard.clear_level();
+
+                    if (flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() == false {
+                        desc_inner_guard.set_level();
+                        desc_inner_guard
+                            .common_data()
+                            .insert_status(IrqStatus::IRQD_LEVEL);
+                    }
+                }
+            }
+
+            ret = Ok(());
+        } else {
+            kerror!(
+                "Failed to set irq {} trigger type to {:?} on irqchip {}, error {:?}",
+                desc_inner_guard.irq_data().irq().data(),
+                trigger_type,
+                chip.name(),
+                r
+            );
+
+            ret = Err(r.unwrap_err());
+        }
+
+        if to_unmask {
+            self.unmask_irq(desc_inner_guard);
+        }
+        return ret;
+    }
+
+    fn irq_request_resources(&self, desc: Arc<IrqDesc>) -> Result<(), SystemError> {
+        let irq_data = desc.irq_data();
+        let irq_chip = irq_data.chip_info_read_irqsave().chip();
+        irq_chip.irq_request_resources(&irq_data)
+    }
+
+    /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/manage.c?r=&mo=59252&fi=2138#1448
+    fn setup_irq_thread(
+        &self,
+        _irq: IrqNumber,
+        _action: &InnerIrqAction,
+        _secondary: bool,
+    ) -> Result<(), SystemError> {
+        // if secondary {
+        //     KernelThreadMechanism::create(func, name)
+        // }
+
+        todo!("setup_irq_thread")
+    }
+
+    fn setup_forced_threading(&self, _action: &mut InnerIrqAction) -> Result<(), SystemError> {
+        // todo: 处理强制线程化的逻辑,参考linux的`irq_setup_forced_threading()`
+        return Ok(());
+    }
+
+    pub fn irq_clear_status_flags(
+        &self,
+        irq: IrqNumber,
+        status: IrqLineStatus,
+    ) -> Result<(), SystemError> {
+        let desc = irq_desc_manager().lookup(irq).ok_or(SystemError::EINVAL)?;
+        desc.modify_status(status, IrqLineStatus::empty());
+        return Ok(());
+    }
+
+    /// 屏蔽中断
+    pub(super) fn mask_irq(&self, irq_data: &Arc<IrqData>) {
+        if irq_data.common_data().status().masked() {
+            return;
+        }
+
+        let chip = irq_data.chip_info_read_irqsave().chip();
+        let r = chip.irq_mask(irq_data);
+
+        if r.is_ok() {
+            irq_data.common_data().set_masked();
+        }
+    }
+
+    /// 解除屏蔽中断
+    pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
+        if desc_inner_guard.common_data().status().masked() == false {
+            return;
+        }
+
+        let r = desc_inner_guard
+            .irq_data()
+            .chip_info_read_irqsave()
+            .chip()
+            .irq_unmask(&desc_inner_guard.irq_data());
+
+        if let Err(e) = r {
+            if e != SystemError::ENOSYS {
+                kerror!(
+                    "Failed to unmask irq {} on irqchip {}, error {:?}",
+                    desc_inner_guard.irq_data().irq().data(),
+                    desc_inner_guard
+                        .irq_data()
+                        .chip_info_read_irqsave()
+                        .chip()
+                        .name(),
+                    e
+                );
+            }
+        } else {
+            desc_inner_guard
+                .common_data()
+                .clear_status(IrqStatus::IRQD_IRQ_MASKED);
+        }
+    }
+
+    /// 释放使用request_irq分配的中断
+    ///
+    /// ## 参数
+    ///
+    /// - irq: 要释放的中断线
+    /// - dev_id: 要释放的设备身份
+    ///
+    /// ## 返回
+    ///
+    /// 返回传递给request_irq的devname参数
+    ///
+    /// ## 说明
+    ///
+    /// 移除一个中断处理程序。处理程序被移除,如果该中断线不再被任何驱动程序使用,则会被禁用。
+    ///
+    /// 在共享IRQ的情况下,调用者必须确保在调用此功能之前,它在所驱动的卡上禁用了中断。
+    ///
+    /// ## 注意
+    ///
+    /// 此函数不可以在中断上下文中调用。
+    pub fn free_irq(&self, _irq: IrqNumber, _dev_id: Option<Arc<DeviceId>>) {
+        kwarn!("Unimplemented free_irq");
+    }
+}
+
+enum IrqStartupResult {
+    Normal,
+    Managed,
+    Abort,
+}
+/// 默认的初级中断处理函数
+///
+/// 该处理函数仅仅返回`WakeThread`,即唤醒中断线程
+#[derive(Debug)]
+struct DefaultPrimaryIrqHandler;
+
+impl IrqHandler for DefaultPrimaryIrqHandler {
+    fn handle(
+        &self,
+        _irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        return Ok(IrqReturn::WakeThread);
+    }
+}
+
+/// Primary handler for nested threaded interrupts.
+/// Should never be called.
+#[derive(Debug)]
+struct IrqNestedPrimaryHandler;
+
+impl IrqHandler for IrqNestedPrimaryHandler {
+    fn handle(
+        &self,
+        irq: IrqNumber,
+        _static_data: Option<&dyn IrqHandlerData>,
+        _dynamic_data: Option<Arc<dyn IrqHandlerData>>,
+    ) -> Result<IrqReturn, SystemError> {
+        kwarn!("Primary handler called for nested irq {}", irq.data());
+        return Ok(IrqReturn::NotHandled);
+    }
+}

+ 26 - 0
kernel/src/exception/mod.rs

@@ -1,3 +1,5 @@
+use core::ops::Add;
+
 use system_error::SystemError;
 
 use crate::arch::CurrentIrqArch;
@@ -10,7 +12,9 @@ pub mod irqchip;
 pub mod irqdata;
 pub mod irqdesc;
 pub mod irqdomain;
+pub mod manage;
 pub mod msi;
+mod resend;
 pub mod softirq;
 pub mod sysfs;
 
@@ -100,6 +104,28 @@ impl Drop for IrqFlagsGuard {
 // 用于表示软件逻辑视角的中断号,全局唯一
 int_like!(IrqNumber, u32);
 
+impl IrqNumber {
+    /// 如果一个(PCI)设备中断没有被连接,我们将设置irqnumber为IRQ_NOTCONNECTED。
+    /// 这导致request_irq()失败,返回-ENOTCONN,这样我们就可以区分这种情况和其他错误返回。
+    pub const IRQ_NOTCONNECTED: IrqNumber = IrqNumber::new(u32::MAX);
+}
+
 // 硬件中断号
 // 用于表示在某个IrqDomain中的中断号
 int_like!(HardwareIrqNumber, u32);
+
+impl Add<u32> for HardwareIrqNumber {
+    type Output = HardwareIrqNumber;
+
+    fn add(self, rhs: u32) -> HardwareIrqNumber {
+        HardwareIrqNumber::new(self.0 + rhs)
+    }
+}
+
+impl Add<u32> for IrqNumber {
+    type Output = IrqNumber;
+
+    fn add(self, rhs: u32) -> IrqNumber {
+        IrqNumber::new(self.0 + rhs)
+    }
+}

+ 8 - 0
kernel/src/exception/msi.rs

@@ -51,6 +51,14 @@ impl MsiMsg {
     pub const fn address(&self) -> u64 {
         (self.address_hi as u64) << 32 | self.address_lo as u64
     }
+
+    pub const fn new_zeroed() -> Self {
+        MsiMsg {
+            address_lo: 0,
+            address_hi: 0,
+            data: 0,
+        }
+    }
 }
 
 #[allow(dead_code)]

+ 91 - 0
kernel/src/exception/resend.rs

@@ -0,0 +1,91 @@
+use system_error::SystemError;
+
+use crate::{exception::irqdesc::IrqDescState, libs::spinlock::SpinLockGuard};
+
+use super::{irqdesc::InnerIrqDesc, manage::IrqManager};
+
+impl IrqManager {
+    /// 检查状态并重发中断
+    ///
+    /// ## 参数
+    ///
+    /// - `desc_inner_guard`:中断描述符的锁
+    /// - `inject`:是否注入中断
+    pub(super) fn irq_check_and_resend(
+        &self,
+        desc_inner_guard: &mut SpinLockGuard<'_, InnerIrqDesc>,
+        inject: bool,
+    ) -> Result<(), SystemError> {
+        // https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/resend.c?fi=check_irq_resend#106
+
+        /*
+         * 我们不重新发送电平触发类型的中断。电平触发类型的中断在它们仍然活动时由硬件重新发送。
+         * 清除PENDING bit,以避免suspend/resume过程中的混淆。
+         */
+        if desc_inner_guard
+            .common_data()
+            .trigger_type()
+            .is_level_type()
+        {
+            desc_inner_guard
+                .internal_state_mut()
+                .remove(IrqDescState::IRQS_PENDING);
+            return Err(SystemError::EINVAL);
+        }
+
+        if desc_inner_guard
+            .internal_state()
+            .contains(IrqDescState::IRQS_REPLAY)
+        {
+            return Err(SystemError::EBUSY);
+        }
+
+        if desc_inner_guard
+            .internal_state()
+            .contains(IrqDescState::IRQS_PENDING)
+            == false
+            && inject == false
+        {
+            return Ok(());
+        }
+
+        desc_inner_guard
+            .internal_state_mut()
+            .remove(IrqDescState::IRQS_PENDING);
+
+        let mut ret = Ok(());
+        if self.try_retrigger(desc_inner_guard).is_err() {
+            // todo: 支持发送到tasklet
+            ret = Err(SystemError::EINVAL);
+        }
+
+        if ret.is_ok() {
+            desc_inner_guard
+                .internal_state_mut()
+                .insert(IrqDescState::IRQS_REPLAY);
+        }
+
+        return ret;
+    }
+
+    fn try_retrigger(
+        &self,
+        desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>,
+    ) -> Result<(), SystemError> {
+        if let Err(e) = desc_inner_guard
+            .irq_data()
+            .chip_info_read_irqsave()
+            .chip()
+            .retrigger(desc_inner_guard.irq_data())
+        {
+            if e != SystemError::ENOSYS {
+                return Err(e);
+            }
+        } else {
+            return Ok(());
+        }
+
+        // 当前中断控制器不支持重发中断,从父中断控制器重发
+        return self.irq_chip_retrigger_hierarchy(desc_inner_guard.irq_data());
+    }
+}

+ 0 - 25
kernel/src/exception/softirq.h

@@ -1,25 +0,0 @@
-/**
- * @file softirq.h
- * @author fslongjin (longjin@RinGoTek.cn)
- * @brief 软中断
- * @version 0.1
- * @date 2022-04-08
- *
- * @copyright Copyright (c) 2022
- *
- */
-#pragma once
-
-#include <common/glib.h>
-
-// ==================implementation with rust===================
-extern void rs_softirq_init();
-extern void rs_raise_softirq(uint32_t sirq_num);
-extern void rs_unregister_softirq(uint32_t sirq_num);
-extern void rs_do_softirq();
-extern void rs_clear_softirq_pending(uint32_t softirq_num);
-
-// for temporary
-#define MAX_SOFTIRQ_NUM 64
-#define TIMER_SIRQ 0         // 时钟软中断号
-#define VIDEO_REFRESH_SIRQ 1 // 帧缓冲区刷新软中断

+ 16 - 31
kernel/src/exception/softirq.rs

@@ -17,14 +17,14 @@ use crate::{
     libs::rwlock::RwLock,
     mm::percpu::{PerCpu, PerCpuVar},
     process::ProcessManager,
-    smp::core::smp_get_processor_id,
+    smp::{core::smp_get_processor_id, cpu::ProcessorId},
     time::timer::clock,
 };
 
 const MAX_SOFTIRQ_NUM: u64 = 64;
 const MAX_SOFTIRQ_RESTART: i32 = 20;
 
-static mut __CPU_PENDING: Option<Box<[VecStatus; PerCpu::MAX_CPU_NUM]>> = None;
+static mut __CPU_PENDING: Option<Box<[VecStatus; PerCpu::MAX_CPU_NUM as usize]>> = None;
 static mut __SORTIRQ_VECTORS: *mut Softirq = null_mut();
 
 #[no_mangle]
@@ -57,9 +57,9 @@ pub fn softirq_vectors() -> &'static mut Softirq {
 }
 
 #[inline(always)]
-fn cpu_pending(cpu_id: usize) -> &'static mut VecStatus {
+fn cpu_pending(cpu_id: ProcessorId) -> &'static mut VecStatus {
     unsafe {
-        return &mut __CPU_PENDING.as_mut().unwrap()[cpu_id];
+        return &mut __CPU_PENDING.as_mut().unwrap()[cpu_id.data() as usize];
     }
 }
 
@@ -165,7 +165,8 @@ impl Softirq {
 
     /// @brief 解注册软中断向量
     ///
-    /// @param irq_num 中断向量号码   
+    /// @param irq_num 中断向量号码  
+    #[allow(dead_code)]
     pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
         // kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
         let mut table_guard = self.table.write_irqsave();
@@ -176,10 +177,11 @@ impl Softirq {
         // self.running.lock().set(VecStatus::from(softirq_num), false);
         // 将对应CPU的pending置0
         compiler_fence(Ordering::SeqCst);
-        cpu_pending(smp_get_processor_id() as usize).set(VecStatus::from(softirq_num), false);
+        cpu_pending(smp_get_processor_id()).set(VecStatus::from(softirq_num), false);
         compiler_fence(Ordering::SeqCst);
     }
 
+    #[inline(never)]
     pub fn do_softirq(&self) {
         if self.cpu_running_count().get().load(Ordering::SeqCst) >= Self::MAX_RUNNING_PER_CPU {
             // 当前CPU的软中断嵌套层数已经达到最大值,不再执行
@@ -194,8 +196,8 @@ impl Softirq {
         let mut max_restart = MAX_SOFTIRQ_RESTART;
         loop {
             compiler_fence(Ordering::SeqCst);
-            let pending = cpu_pending(cpu_id as usize).bits;
-            cpu_pending(cpu_id as usize).bits = 0;
+            let pending = cpu_pending(cpu_id).bits;
+            cpu_pending(cpu_id).bits = 0;
             compiler_fence(Ordering::SeqCst);
 
             unsafe { CurrentIrqArch::interrupt_enable() };
@@ -229,7 +231,7 @@ impl Softirq {
             unsafe { CurrentIrqArch::interrupt_disable() };
             max_restart -= 1;
             compiler_fence(Ordering::SeqCst);
-            if cpu_pending(cpu_id as usize).is_empty() {
+            if cpu_pending(cpu_id).is_empty() {
                 compiler_fence(Ordering::SeqCst);
                 if clock() < end && max_restart > 0 {
                     continue;
@@ -245,7 +247,7 @@ impl Softirq {
 
     pub fn raise_softirq(&self, softirq_num: SoftirqNumber) {
         let guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
-        let processor_id = smp_get_processor_id() as usize;
+        let processor_id = smp_get_processor_id();
 
         cpu_pending(processor_id).insert(VecStatus::from(softirq_num));
 
@@ -254,9 +256,11 @@ impl Softirq {
         drop(guard);
         // kdebug!("raise_softirq exited");
     }
+
+    #[allow(dead_code)]
     pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) {
         compiler_fence(Ordering::SeqCst);
-        cpu_pending(smp_get_processor_id() as usize).remove(VecStatus::from(softirq_num));
+        cpu_pending(smp_get_processor_id()).remove(VecStatus::from(softirq_num));
         compiler_fence(Ordering::SeqCst);
     }
 }
@@ -282,25 +286,6 @@ impl<'a> Drop for RunningCountGuard<'a> {
     }
 }
 
-// ======= 以下为给C提供的接口 =======
-#[no_mangle]
-pub extern "C" fn rs_raise_softirq(softirq_num: u32) {
-    softirq_vectors().raise_softirq(SoftirqNumber::from(softirq_num as u64));
-}
-
-#[no_mangle]
-pub extern "C" fn rs_unregister_softirq(softirq_num: u32) {
-    softirq_vectors().unregister_softirq(SoftirqNumber::from(softirq_num as u64));
-}
-
-#[no_mangle]
-pub extern "C" fn rs_do_softirq() {
+pub fn do_softirq() {
     softirq_vectors().do_softirq();
 }
-
-#[no_mangle]
-pub extern "C" fn rs_clear_softirq_pending(softirq_num: u32) {
-    unsafe {
-        softirq_vectors().clear_softirq_pending(SoftirqNumber::from(softirq_num as u64));
-    }
-}

+ 6 - 3
kernel/src/exception/sysfs.rs

@@ -152,7 +152,8 @@ impl Attribute for AttrChipName {
             .arc_any()
             .downcast::<IrqDesc>()
             .map_err(|_| SystemError::EINVAL)?;
-        let chip = irq_desc.irq_data().chip();
+
+        let chip = irq_desc.irq_data().chip_info_read_irqsave().chip();
         let name = chip.name();
         let len = core::cmp::min(name.len() + 1, buf.len());
         let name = format!("{}\n", name);
@@ -301,9 +302,11 @@ impl Attribute for AttrActions {
 
         for action in actions {
             if len != 0 {
-                len += sysfs_emit_str(&mut buf[len..], &format!(",{}", action.name())).unwrap();
+                len += sysfs_emit_str(&mut buf[len..], &format!(",{}", action.inner().name()))
+                    .unwrap();
             } else {
-                len += sysfs_emit_str(&mut buf[len..], &format!("{}", action.name())).unwrap();
+                len +=
+                    sysfs_emit_str(&mut buf[len..], &format!("{}", action.inner().name())).unwrap();
             }
 
             if len >= buf.len() {

+ 1 - 1
kernel/src/filesystem/procfs/mod.rs

@@ -157,7 +157,7 @@ impl ProcFSInode {
         let state = sched_info_guard.inner_lock_read_irqsave().state();
         let cpu_id = sched_info_guard
             .on_cpu()
-            .map(|cpu| cpu as i32)
+            .map(|cpu| cpu.data() as i32)
             .unwrap_or(-1);
 
         let priority = sched_info_guard.priority();

+ 0 - 29
kernel/src/filesystem/vfs/VFS.h

@@ -1,29 +0,0 @@
-/**
- * @file VFS.h
- * @author fslongjin (longjin@RinGoTek.cn)
- * @brief 虚拟文件系统
- * @version 0.1
- * @date 2022-04-20
- *
- * @copyright Copyright (c) 2022
- *
- */
-
-#pragma once
-
-struct vfs_file_operations_t
-{
-    long (*open)(void *not_used, void *not_used1);
-    long (*close)(void *not_used, void *not_used1);
-    long (*read)(void *not_used1, char *buf, int64_t count, long *position);
-    long (*write)(void *not_used1, char *buf, int64_t count, long *position);
-    long (*lseek)(void *not_used1, long offset, long origin);
-    long (*ioctl)(void *not_used, void *not_used1, uint64_t cmd, uint64_t arg);
-};
-
-/**
- * @brief 初始化vfs
- *
- * @return int 错误码
- */
-extern int vfs_init();

+ 0 - 2
kernel/src/include/bindings/wrapper.h

@@ -36,7 +36,5 @@
 #include <smp/smp.h>
 #include <time/clocksource.h>
 #include <time/sleep.h>
-#include <driver/pci/pci_irq.h>
 #include <common/errno.h>
 #include <common/cpu.h>
-#include <exception/irq.h>

+ 49 - 18
kernel/src/libs/cpumask.rs

@@ -1,7 +1,8 @@
 use bitmap::{traits::BitMapOps, AllocBitmap};
 
-use crate::mm::percpu::PerCpu;
+use crate::{mm::percpu::PerCpu, smp::cpu::ProcessorId};
 
+#[derive(Clone)]
 pub struct CpuMask {
     bmp: AllocBitmap,
 }
@@ -9,40 +10,62 @@ pub struct CpuMask {
 #[allow(dead_code)]
 impl CpuMask {
     pub fn new() -> Self {
-        let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM);
+        let bmp = AllocBitmap::new(PerCpu::MAX_CPU_NUM as usize);
         Self { bmp }
     }
 
     /// 获取CpuMask中的第一个cpu
-    pub fn first(&self) -> Option<usize> {
-        self.bmp.first_index()
+    pub fn first(&self) -> Option<ProcessorId> {
+        self.bmp
+            .first_index()
+            .map(|index| ProcessorId::new(index as u32))
     }
 
     /// 获取CpuMask中第一个未被置位的cpu
-    pub fn first_zero(&self) -> Option<usize> {
-        self.bmp.first_false_index()
+    pub fn first_zero(&self) -> Option<ProcessorId> {
+        self.bmp
+            .first_false_index()
+            .map(|index| ProcessorId::new(index as u32))
     }
 
     /// 获取CpuMask中的最后一个被置位的cpu
-    pub fn last(&self) -> Option<usize> {
-        self.bmp.last_index()
+    pub fn last(&self) -> Option<ProcessorId> {
+        self.bmp
+            .last_index()
+            .map(|index| ProcessorId::new(index as u32))
     }
 
     /// 获取指定cpu之后第一个为1的位的cpu
-    pub fn next_index(&self, cpu: usize) -> Option<usize> {
-        self.bmp.next_index(cpu)
+    pub fn next_index(&self, cpu: ProcessorId) -> Option<ProcessorId> {
+        self.bmp
+            .next_index(cpu.data() as usize)
+            .map(|index| ProcessorId::new(index as u32))
     }
 
     /// 获取指定cpu之后第一个为未被置位的cpu
-    pub fn next_zero_index(&self, cpu: usize) -> Option<usize> {
-        self.bmp.next_false_index(cpu)
+    pub fn next_zero_index(&self, cpu: ProcessorId) -> Option<ProcessorId> {
+        self.bmp
+            .next_false_index(cpu.data() as usize)
+            .map(|index| ProcessorId::new(index as u32))
+    }
+
+    pub fn set(&mut self, cpu: ProcessorId, value: bool) -> Option<bool> {
+        self.bmp.set(cpu.data() as usize, value)
+    }
+
+    pub fn get(&self, cpu: ProcessorId) -> Option<bool> {
+        self.bmp.get(cpu.data() as usize)
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.bmp.is_empty()
     }
 
     /// 迭代所有被置位的cpu
     pub fn iter_cpu(&self) -> CpuMaskIter {
         CpuMaskIter {
             mask: self,
-            index: 0,
+            index: ProcessorId::new(0),
             set: true,
         }
     }
@@ -51,7 +74,7 @@ impl CpuMask {
     pub fn iter_zero_cpu(&self) -> CpuMaskIter {
         CpuMaskIter {
             mask: self,
-            index: 0,
+            index: ProcessorId::new(0),
             set: false,
         }
     }
@@ -59,15 +82,15 @@ impl CpuMask {
 
 pub struct CpuMaskIter<'a> {
     mask: &'a CpuMask,
-    index: usize,
+    index: ProcessorId,
     set: bool,
 }
 
 impl<'a> Iterator for CpuMaskIter<'a> {
-    type Item = usize;
+    type Item = ProcessorId;
 
-    fn next(&mut self) -> Option<Self::Item> {
-        if self.index == 0 {
+    fn next(&mut self) -> Option<ProcessorId> {
+        if self.index.data() == 0 {
             if self.set {
                 self.index = self.mask.first()?;
             } else {
@@ -83,3 +106,11 @@ impl<'a> Iterator for CpuMaskIter<'a> {
         Some(self.index)
     }
 }
+
+impl core::fmt::Debug for CpuMask {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("CpuMask")
+            .field("bmp", &format!("size: {}", self.bmp.size()))
+            .finish()
+    }
+}

+ 1 - 1
kernel/src/libs/int_like.rs

@@ -27,7 +27,7 @@
 #[macro_export]
 macro_rules! int_like {
     ($new_type_name:ident, $backing_type: ident) => {
-        #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
+        #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy, Hash)]
         pub struct $new_type_name($backing_type);
 
         impl $new_type_name {

+ 2 - 2
kernel/src/libs/lib_ui/textui.rs

@@ -1029,7 +1029,7 @@ pub fn textui_putchar(
     if unsafe { TEXTUI_IS_INIT } {
         return textui_framework()
             .current_window
-            .lock()
+            .lock_irqsave()
             .textui_putchar_window(
                 character,
                 fr_color,
@@ -1061,7 +1061,7 @@ pub fn textui_putstr(
         None
     };
 
-    let mut guard = window.as_ref().map(|w| w.lock());
+    let mut guard = window.as_ref().map(|w| w.lock_irqsave());
 
     for character in string.chars() {
         if unsafe { TEXTUI_IS_INIT } {

+ 3 - 1
kernel/src/libs/wait_queue.rs

@@ -1,4 +1,4 @@
-#![allow(dead_code)]
+// #![allow(dead_code)]
 use core::intrinsics::unlikely;
 
 use alloc::{collections::LinkedList, sync::Arc, vec::Vec};
@@ -25,6 +25,7 @@ struct InnerWaitQueue {
 #[derive(Debug)]
 pub struct WaitQueue(SpinLock<InnerWaitQueue>);
 
+#[allow(dead_code)]
 impl WaitQueue {
     pub const INIT: WaitQueue = WaitQueue(SpinLock::new(InnerWaitQueue::INIT));
 
@@ -275,6 +276,7 @@ pub struct EventWaitQueue {
     wait_list: SpinLock<Vec<(u64, Arc<ProcessControlBlock>)>>,
 }
 
+#[allow(dead_code)]
 impl EventWaitQueue {
     pub fn new() -> Self {
         Self {

+ 11 - 8
kernel/src/mm/kernel_mapper.rs

@@ -8,9 +8,11 @@ use crate::{
     },
     exception::InterruptArch,
     libs::align::page_align_up,
-    mm::allocator::page_frame::PageFrameCount,
-    mm::{MMArch, MemoryManagementArch},
-    smp::core::smp_get_processor_id,
+    mm::{allocator::page_frame::PageFrameCount, MMArch, MemoryManagementArch},
+    smp::{
+        core::smp_get_processor_id,
+        cpu::{AtomicProcessorId, ProcessorId},
+    },
 };
 use core::{
     ops::Deref,
@@ -18,10 +20,11 @@ use core::{
 };
 
 /// 标志当前没有处理器持有内核映射器的锁
-/// 之所以需要这个标志,是因为AtomicUsize::new(0)会把0当作一个处理器的id
-const KERNEL_MAPPER_NO_PROCESSOR: usize = !0;
+/// 之所以需要这个标志,是因为 AtomicProcessorId::new(0) 会把0当作一个处理器的id
+const KERNEL_MAPPER_NO_PROCESSOR: ProcessorId = ProcessorId::INVALID;
 /// 当前持有内核映射器锁的处理器
-static KERNEL_MAPPER_LOCK_OWNER: AtomicUsize = AtomicUsize::new(KERNEL_MAPPER_NO_PROCESSOR);
+static KERNEL_MAPPER_LOCK_OWNER: AtomicProcessorId =
+    AtomicProcessorId::new(KERNEL_MAPPER_NO_PROCESSOR);
 /// 内核映射器的锁计数器
 static KERNEL_MAPPER_LOCK_COUNT: AtomicUsize = AtomicUsize::new(0);
 
@@ -33,7 +36,7 @@ pub struct KernelMapper {
 }
 
 impl KernelMapper {
-    fn lock_cpu(cpuid: usize, mapper: PageMapper) -> Self {
+    fn lock_cpu(cpuid: ProcessorId, mapper: PageMapper) -> Self {
         loop {
             match KERNEL_MAPPER_LOCK_OWNER.compare_exchange_weak(
                 KERNEL_MAPPER_NO_PROCESSOR,
@@ -61,7 +64,7 @@ impl KernelMapper {
     /// @brief 锁定内核映射器, 并返回一个内核映射器对象
     #[inline(always)]
     pub fn lock() -> Self {
-        let cpuid = smp_get_processor_id() as usize;
+        let cpuid = smp_get_processor_id();
         let mapper = unsafe { PageMapper::current(PageTableKind::Kernel, LockedFrameAllocator) };
         return Self::lock_cpu(cpuid, mapper);
     }

+ 7 - 7
kernel/src/mm/percpu.rs

@@ -1,4 +1,4 @@
-use core::sync::atomic::AtomicUsize;
+use core::sync::atomic::AtomicU32;
 
 use alloc::vec::Vec;
 
@@ -11,13 +11,13 @@ use crate::{
 ///
 /// todo: 待smp模块重构后,从smp模块获取CPU数量。
 /// 目前由于smp模块初始化时机较晚,导致大部分内核模块无法在早期初始化PerCpu变量。
-const CPU_NUM: AtomicUsize = AtomicUsize::new(PerCpu::MAX_CPU_NUM);
+const CPU_NUM: AtomicU32 = AtomicU32::new(PerCpu::MAX_CPU_NUM);
 
 #[derive(Debug)]
 pub struct PerCpu;
 
 impl PerCpu {
-    pub const MAX_CPU_NUM: usize = 128;
+    pub const MAX_CPU_NUM: u32 = 128;
     /// # 初始化PerCpu
     ///
     /// 该函数应该在内核初始化时调用一次。
@@ -28,7 +28,7 @@ impl PerCpu {
         if CPU_NUM.load(core::sync::atomic::Ordering::SeqCst) != 0 {
             panic!("PerCpu::init() called twice");
         }
-        let cpus = unsafe { smp_get_total_cpu() } as usize;
+        let cpus = unsafe { smp_get_total_cpu() };
         assert!(cpus > 0, "PerCpu::init(): smp_get_total_cpu() returned 0");
         CPU_NUM.store(cpus, core::sync::atomic::Ordering::SeqCst);
     }
@@ -62,7 +62,7 @@ impl<T> PerCpuVar<T> {
             panic!("PerCpu::init() not called");
         }
 
-        if data.len() != cpu_num {
+        if data.len() != cpu_num.try_into().unwrap() {
             return None;
         }
 
@@ -76,12 +76,12 @@ impl<T> PerCpuVar<T> {
 
     pub fn get(&self) -> &T {
         let cpu_id = smp_get_processor_id();
-        &self.inner[cpu_id as usize]
+        &self.inner[cpu_id.data() as usize]
     }
 
     pub fn get_mut(&mut self) -> &mut T {
         let cpu_id = smp_get_processor_id();
-        &mut self.inner[cpu_id as usize]
+        &mut self.inner[cpu_id.data() as usize]
     }
 }
 

+ 1 - 1
kernel/src/process/c_adapter.rs

@@ -18,7 +18,7 @@ unsafe extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize {
 
 #[no_mangle]
 unsafe extern "C" fn rs_current_pcb_cpuid() -> u32 {
-    return smp_get_processor_id();
+    return smp_get_processor_id().data();
 }
 
 #[no_mangle]

+ 4 - 4
kernel/src/process/idle.rs

@@ -8,7 +8,7 @@ use alloc::{sync::Arc, vec::Vec};
 use crate::{
     mm::{percpu::PerCpu, VirtAddr, INITIAL_PROCESS_ADDRESS_SPACE},
     process::KernelStack,
-    smp::core::smp_get_processor_id,
+    smp::{core::smp_get_processor_id, cpu::ProcessorId},
 };
 
 use super::{ProcessControlBlock, ProcessManager};
@@ -27,10 +27,10 @@ impl ProcessManager {
         }
 
         assert!(
-            smp_get_processor_id() == 0,
+            smp_get_processor_id() == ProcessorId::new(0),
             "Idle process must be initialized on the first processor"
         );
-        let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM);
+        let mut v: Vec<Arc<ProcessControlBlock>> = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
 
         for i in 0..PerCpu::MAX_CPU_NUM {
             let kstack = if unlikely(i == 0) {
@@ -57,7 +57,7 @@ impl ProcessManager {
             };
 
             assert!(idle_pcb.sched_info().on_cpu().is_none());
-            idle_pcb.sched_info().set_on_cpu(Some(i as u32));
+            idle_pcb.sched_info().set_on_cpu(Some(ProcessorId::new(i)));
             v.push(idle_pcb);
         }
 

+ 17 - 1
kernel/src/process/kthread.rs

@@ -14,7 +14,7 @@ use system_error::SystemError;
 
 use crate::{
     arch::{sched::sched, CurrentIrqArch},
-    exception::InterruptArch,
+    exception::{irqdesc::IrqAction, InterruptArch},
     init::initial_kthread::initial_kernel_thread,
     kdebug, kinfo,
     libs::{once::Once, spinlock::SpinLock},
@@ -87,15 +87,31 @@ impl KernelThreadPcbPrivate {
 #[allow(dead_code)]
 pub enum KernelThreadClosure {
     UsizeClosure((Box<dyn Fn(usize) -> i32 + Send + Sync>, usize)),
+    StaticUsizeClosure((&'static dyn Fn(usize) -> i32, usize)),
     EmptyClosure((Box<dyn Fn() -> i32 + Send + Sync>, ())),
+    StaticEmptyClosure((&'static dyn Fn() -> i32, ())),
+    IrqThread(
+        (
+            &'static dyn Fn(Arc<IrqAction>) -> Result<(), SystemError>,
+            Arc<IrqAction>,
+        ),
+    ),
     // 添加其他类型入参的闭包,返回值必须是i32
 }
 
+unsafe impl Send for KernelThreadClosure {}
+unsafe impl Sync for KernelThreadClosure {}
+
 impl KernelThreadClosure {
     pub fn run(self) -> i32 {
         match self {
             Self::UsizeClosure((func, arg)) => func(arg),
             Self::EmptyClosure((func, _arg)) => func(),
+            Self::StaticUsizeClosure((func, arg)) => func(arg),
+            Self::StaticEmptyClosure((func, _arg)) => func(),
+            Self::IrqThread((func, arg)) => {
+                func(arg).map(|_| 0).unwrap_or_else(|e| e.to_posix_errno())
+            }
         }
     }
 }

+ 25 - 30
kernel/src/process/mod.rs

@@ -1,9 +1,9 @@
 use core::{
-    hash::{Hash, Hasher},
+    hash::Hash,
     hint::spin_loop,
     intrinsics::{likely, unlikely},
     mem::ManuallyDrop,
-    sync::atomic::{compiler_fence, AtomicBool, AtomicI32, AtomicIsize, AtomicUsize, Ordering},
+    sync::atomic::{compiler_fence, AtomicBool, AtomicIsize, AtomicUsize, Ordering},
 };
 
 use alloc::{
@@ -48,7 +48,10 @@ use crate::{
         core::{sched_enqueue, CPU_EXECUTING},
         SchedPolicy, SchedPriority,
     },
-    smp::kick_cpu,
+    smp::{
+        cpu::{AtomicProcessorId, ProcessorId},
+        kick_cpu,
+    },
     syscall::{user_access::clear_user, Syscall},
 };
 
@@ -446,12 +449,6 @@ pub unsafe extern "C" fn switch_finish_hook() {
 
 int_like!(Pid, AtomicPid, usize, AtomicUsize);
 
-impl Hash for Pid {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.0.hash(state);
-    }
-}
-
 impl Pid {
     pub fn to_string(&self) -> String {
         self.0.to_string()
@@ -1019,10 +1016,10 @@ impl ProcessBasicInfo {
 #[derive(Debug)]
 pub struct ProcessSchedulerInfo {
     /// 当前进程所在的cpu
-    on_cpu: AtomicI32,
+    on_cpu: AtomicProcessorId,
     /// 如果当前进程等待被迁移到另一个cpu核心上(也就是flags中的PF_NEED_MIGRATE被置位),
     /// 该字段存储要被迁移到的目标处理器核心号
-    migrate_to: AtomicI32,
+    migrate_to: AtomicProcessorId,
     inner_locked: RwLock<InnerSchedInfo>,
     /// 进程的调度优先级
     priority: SchedPriority,
@@ -1056,14 +1053,11 @@ impl InnerSchedInfo {
 
 impl ProcessSchedulerInfo {
     #[inline(never)]
-    pub fn new(on_cpu: Option<u32>) -> Self {
-        let cpu_id = match on_cpu {
-            Some(cpu_id) => cpu_id as i32,
-            None => -1,
-        };
+    pub fn new(on_cpu: Option<ProcessorId>) -> Self {
+        let cpu_id = on_cpu.unwrap_or(ProcessorId::INVALID);
         return Self {
-            on_cpu: AtomicI32::new(cpu_id),
-            migrate_to: AtomicI32::new(-1),
+            on_cpu: AtomicProcessorId::new(cpu_id),
+            migrate_to: AtomicProcessorId::new(ProcessorId::INVALID),
             inner_locked: RwLock::new(InnerSchedInfo {
                 state: ProcessState::Blocked(false),
                 sched_policy: SchedPolicy::CFS,
@@ -1074,37 +1068,38 @@ impl ProcessSchedulerInfo {
         };
     }
 
-    pub fn on_cpu(&self) -> Option<u32> {
+    pub fn on_cpu(&self) -> Option<ProcessorId> {
         let on_cpu = self.on_cpu.load(Ordering::SeqCst);
-        if on_cpu == -1 {
+        if on_cpu == ProcessorId::INVALID {
             return None;
         } else {
-            return Some(on_cpu as u32);
+            return Some(on_cpu);
         }
     }
 
-    pub fn set_on_cpu(&self, on_cpu: Option<u32>) {
+    pub fn set_on_cpu(&self, on_cpu: Option<ProcessorId>) {
         if let Some(cpu_id) = on_cpu {
-            self.on_cpu.store(cpu_id as i32, Ordering::SeqCst);
+            self.on_cpu.store(cpu_id, Ordering::SeqCst);
         } else {
-            self.on_cpu.store(-1, Ordering::SeqCst);
+            self.on_cpu.store(ProcessorId::INVALID, Ordering::SeqCst);
         }
     }
 
-    pub fn migrate_to(&self) -> Option<u32> {
+    pub fn migrate_to(&self) -> Option<ProcessorId> {
         let migrate_to = self.migrate_to.load(Ordering::SeqCst);
-        if migrate_to == -1 {
+        if migrate_to == ProcessorId::INVALID {
             return None;
         } else {
-            return Some(migrate_to as u32);
+            return Some(migrate_to);
         }
     }
 
-    pub fn set_migrate_to(&self, migrate_to: Option<u32>) {
+    pub fn set_migrate_to(&self, migrate_to: Option<ProcessorId>) {
         if let Some(data) = migrate_to {
-            self.migrate_to.store(data as i32, Ordering::SeqCst);
+            self.migrate_to.store(data, Ordering::SeqCst);
         } else {
-            self.migrate_to.store(-1, Ordering::SeqCst)
+            self.migrate_to
+                .store(ProcessorId::INVALID, Ordering::SeqCst)
         }
     }
 

+ 0 - 1
kernel/src/process/process.h

@@ -13,7 +13,6 @@
 #include <common/cpu.h>
 #include <common/errno.h>
 #include <common/glib.h>
-#include <filesystem/vfs/VFS.h>
 #include <syscall/syscall.h>
 
 /**

+ 16 - 0
kernel/src/process/process.rs

@@ -8,6 +8,22 @@ use crate::{
     process::{Pid, ProcessManager},
 };
 
+use super::{ProcessFlags, __PROCESS_MANAGEMENT_INIT_DONE};
+
+pub fn current_pcb_flags() -> ProcessFlags {
+    if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
+        return ProcessFlags::empty();
+    }
+    return ProcessManager::current_pcb().flags().clone();
+}
+
+pub fn current_pcb_preempt_count() -> usize {
+    if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } {
+        return 0;
+    }
+    return ProcessManager::current_pcb().preempt_count();
+}
+
 /// @brief 初始化pid=1的进程的stdio
 pub fn stdio_init() -> Result<(), SystemError> {
     if ProcessManager::current_pcb().pid() != Pid(1) {

+ 10 - 7
kernel/src/sched/cfs.rs

@@ -14,7 +14,7 @@ use crate::{
     process::{
         ProcessControlBlock, ProcessFlags, ProcessManager, ProcessSchedulerInfo, ProcessState,
     },
-    smp::core::smp_get_processor_id,
+    smp::{core::smp_get_processor_id, cpu::ProcessorId},
 };
 
 use super::{
@@ -150,7 +150,8 @@ impl SchedulerCFS {
 
     /// @brief 时钟中断到来时,由sched的core模块中的函数,调用本函数,更新CFS进程的可执行时间
     pub fn timer_update_jiffies(&mut self, sched_info: &ProcessSchedulerInfo) {
-        let current_cpu_queue: &mut CFSQueue = self.cpu_queue[smp_get_processor_id() as usize];
+        let current_cpu_queue: &mut CFSQueue =
+            self.cpu_queue[smp_get_processor_id().data() as usize];
         // todo: 引入调度周期以及所有进程的优先权进行计算,然后设置进程的可执行时间
 
         let mut queue = None;
@@ -180,7 +181,7 @@ impl SchedulerCFS {
 
     /// @brief 将进程加入cpu的cfs调度队列,并且重设其虚拟运行时间为当前队列的最小值
     pub fn enqueue_reset_vruntime(&mut self, pcb: Arc<ProcessControlBlock>) {
-        let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap() as usize];
+        let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap().data() as usize];
         let queue = cpu_queue.locked_queue.lock_irqsave();
         if queue.len() > 0 {
             pcb.sched_info()
@@ -197,8 +198,10 @@ impl SchedulerCFS {
         self.cpu_queue[cpu_id].idle_pcb = pcb;
     }
     /// 获取某个cpu的运行队列中的进程数
-    pub fn get_cfs_queue_len(&mut self, cpu_id: u32) -> usize {
-        let queue = self.cpu_queue[cpu_id as usize].locked_queue.lock_irqsave();
+    pub fn get_cfs_queue_len(&mut self, cpu_id: ProcessorId) -> usize {
+        let queue = self.cpu_queue[cpu_id.data() as usize]
+            .locked_queue
+            .lock_irqsave();
         return CFSQueue::get_cfs_queue_size(&queue);
     }
 }
@@ -213,7 +216,7 @@ impl Scheduler for SchedulerCFS {
             .flags()
             .remove(ProcessFlags::NEED_SCHEDULE);
 
-        let current_cpu_id = smp_get_processor_id() as usize;
+        let current_cpu_id = smp_get_processor_id().data() as usize;
 
         let current_cpu_queue: &mut CFSQueue = self.cpu_queue[current_cpu_id];
 
@@ -272,7 +275,7 @@ impl Scheduler for SchedulerCFS {
     }
 
     fn enqueue(&mut self, pcb: Arc<ProcessControlBlock>) {
-        let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap() as usize];
+        let cpu_queue = &mut self.cpu_queue[pcb.sched_info().on_cpu().unwrap().data() as usize];
 
         cpu_queue.enqueue(pcb);
     }

+ 9 - 8
kernel/src/sched/core.rs

@@ -10,7 +10,7 @@ use crate::{
     kinfo,
     mm::percpu::PerCpu,
     process::{AtomicPid, Pid, ProcessControlBlock, ProcessFlags, ProcessManager, ProcessState},
-    smp::core::smp_get_processor_id,
+    smp::{core::smp_get_processor_id, cpu::ProcessorId},
 };
 
 use super::rt::{sched_rt_init, SchedulerRT, __get_rt_scheduler};
@@ -39,23 +39,23 @@ impl CpuExecuting {
     }
 
     #[inline(always)]
-    pub fn set(&self, cpu_id: u32, pid: Pid) {
-        self.data[cpu_id as usize].store(pid, Ordering::SeqCst);
+    pub fn set(&self, cpu_id: ProcessorId, pid: Pid) {
+        self.data[cpu_id.data() as usize].store(pid, Ordering::SeqCst);
     }
 
     #[inline(always)]
-    pub fn get(&self, cpu_id: u32) -> Pid {
-        self.data[cpu_id as usize].load(Ordering::SeqCst)
+    pub fn get(&self, cpu_id: ProcessorId) -> Pid {
+        self.data[cpu_id.data() as usize].load(Ordering::SeqCst)
     }
 }
 
 // 获取某个cpu的负载情况,返回当前负载,cpu_id 是获取负载的cpu的id
 // TODO:将获取负载情况调整为最近一段时间运行进程的数量
-pub fn get_cpu_loads(cpu_id: u32) -> u32 {
+pub fn get_cpu_loads(cpu_id: ProcessorId) -> u32 {
     let cfs_scheduler = __get_cfs_scheduler();
     let rt_scheduler = __get_rt_scheduler();
-    let len_cfs = cfs_scheduler.get_cfs_queue_len(cpu_id as u32);
-    let len_rt = rt_scheduler.rt_queue_len(cpu_id as u32);
+    let len_cfs = cfs_scheduler.get_cfs_queue_len(cpu_id);
+    let len_rt = rt_scheduler.rt_queue_len(cpu_id);
     // let load_rt = rt_scheduler.get_load_list_len(cpu_id);
     // kdebug!("this cpu_id {} is load rt {}", cpu_id, load_rt);
 
@@ -70,6 +70,7 @@ pub fn loads_balance(pcb: Arc<ProcessControlBlock>) {
     let mut min_loads_cpu_id = smp_get_processor_id();
     let mut min_loads = get_cpu_loads(smp_get_processor_id());
     for cpu_id in 0..cpu_num {
+        let cpu_id = ProcessorId::new(cpu_id);
         let tmp_cpu_loads = get_cpu_loads(cpu_id);
         if min_loads - tmp_cpu_loads > 0 {
             min_loads_cpu_id = cpu_id;

Some files were not shown because too many files changed in this diff