Browse Source

使用rust重写了apic的驱动 (#425)

* 使用rust重写了apic的驱动。

* 修正signal和调度器的部分加锁逻辑,增加回退策略。

* 把pcb的flags字段替换为无锁的

* 使用cargo管理apic的编译

* 删除makefile中指定PIC的变量

---------

Co-authored-by: Gou Ngai <[email protected]>
Co-authored-by: 櫻井桃華 <[email protected]>
LoGin 1 year ago
parent
commit
70a4e5550a
63 changed files with 2637 additions and 1366 deletions
  1. 4 0
      .vscode/settings.json
  2. 1 0
      kernel/Cargo.toml
  3. 4 0
      kernel/Makefile
  4. 71 2
      kernel/build.rs
  5. 4 8
      kernel/src/Makefile
  6. 1 1
      kernel/src/arch/Makefile
  7. 1 1
      kernel/src/arch/x86_64/Makefile
  8. 1 1
      kernel/src/arch/x86_64/asm/Makefile
  9. 228 0
      kernel/src/arch/x86_64/driver/apic/apic.c
  10. 1 84
      kernel/src/arch/x86_64/driver/apic/apic.h
  11. 13 45
      kernel/src/arch/x86_64/driver/apic/apic_timer.c
  12. 14 0
      kernel/src/arch/x86_64/driver/apic/apic_timer.h
  13. 257 0
      kernel/src/arch/x86_64/driver/apic/apic_timer.rs
  14. 84 0
      kernel/src/arch/x86_64/driver/apic/c_adapter.rs
  15. 364 0
      kernel/src/arch/x86_64/driver/apic/ioapic.rs
  16. 623 0
      kernel/src/arch/x86_64/driver/apic/mod.rs
  17. 125 0
      kernel/src/arch/x86_64/driver/apic/x2apic.rs
  18. 358 0
      kernel/src/arch/x86_64/driver/apic/xapic.rs
  19. 1 1
      kernel/src/arch/x86_64/driver/hpet.c
  20. 1 0
      kernel/src/arch/x86_64/driver/mod.rs
  21. 15 0
      kernel/src/arch/x86_64/interrupt/c_adapter.rs
  22. 111 34
      kernel/src/arch/x86_64/interrupt/ipi.rs
  23. 1 0
      kernel/src/arch/x86_64/interrupt/mod.rs
  24. 36 21
      kernel/src/arch/x86_64/ipc/signal.rs
  25. 2 36
      kernel/src/arch/x86_64/x86_64_ipi.c
  26. 1 16
      kernel/src/arch/x86_64/x86_64_ipi.h
  27. 1 1
      kernel/src/common/Makefile
  28. 2 2
      kernel/src/driver/Makefile
  29. 1 1
      kernel/src/driver/hid/Makefile
  30. 0 66
      kernel/src/driver/interrupt/8259A/8259A.c
  31. 0 33
      kernel/src/driver/interrupt/8259A/8259A.h
  32. 0 14
      kernel/src/driver/interrupt/Makefile
  33. 0 741
      kernel/src/driver/interrupt/apic/apic.c
  34. 0 2
      kernel/src/driver/interrupt/apic/apic2rust.h
  35. 0 110
      kernel/src/driver/interrupt/apic/apic_timer.h
  36. 1 1
      kernel/src/driver/keyboard/ps2_keyboard.c
  37. 14 14
      kernel/src/driver/mouse/ps2_mouse.c
  38. 2 1
      kernel/src/exception/entry.S
  39. 2 2
      kernel/src/exception/irq.c
  40. 3 1
      kernel/src/exception/irq.h
  41. 0 1
      kernel/src/filesystem/vfs/file.rs
  42. 1 1
      kernel/src/include/bindings/wrapper.h
  43. 1 0
      kernel/src/lib.rs
  44. 1 1
      kernel/src/libs/Makefile
  45. 46 0
      kernel/src/libs/lock_free_flags.rs
  46. 1 0
      kernel/src/libs/mod.rs
  47. 14 0
      kernel/src/libs/rwlock.rs
  48. 3 1
      kernel/src/main.c
  49. 1 1
      kernel/src/process/fork.rs
  50. 2 2
      kernel/src/process/kthread.rs
  51. 47 7
      kernel/src/process/mod.rs
  52. 0 18
      kernel/src/sched/Makefile
  53. 20 6
      kernel/src/sched/cfs.rs
  54. 22 8
      kernel/src/sched/core.rs
  55. 1 42
      kernel/src/sched/sched.h
  56. 79 0
      kernel/src/smp/cpu/c_adapter.rs
  57. 1 0
      kernel/src/smp/cpu/mod.rs
  58. 1 0
      kernel/src/smp/mod.rs
  59. 32 29
      kernel/src/smp/smp.c
  60. 1 1
      kernel/src/syscall/mod.rs
  61. 13 6
      tools/run-qemu.sh
  62. 1 2
      user/apps/shell/cmd.c
  63. 1 1
      user/dadk/config/relibc-0.1.0.dadk

+ 4 - 0
.vscode/settings.json

@@ -183,4 +183,8 @@
         "./kernel/Cargo.toml",
         "./kernel/src/libs/ida/Cargo.toml"
     ],
+    "rust-analyzer.check.overrideCommand": [
+        "make",
+        "check"
+    ],
 }

+ 1 - 0
kernel/Cargo.toml

@@ -21,6 +21,7 @@ backtrace = []
 [dependencies]
 x86 = "0.52.0"
 x86_64 = "0.14.10"
+bit_field = "0.10"
 bitflags = "1.3.2"
 bitfield-struct = "0.5.3"
 virtio-drivers = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/virtio-drivers.git", rev = "f1d1cbb" }

+ 4 - 0
kernel/Makefile

@@ -11,3 +11,7 @@ clean:
 .PHONY: fmt
 fmt:
 	cargo fmt --all $(FMT_CHECK)
+
+
+check:
+	cargo +nightly-2023-01-21 check --workspace --message-format=json --target ./src/arch/x86_64/x86_64-unknown-none.json

+ 71 - 2
kernel/build.rs

@@ -91,7 +91,6 @@ impl CFilesBuilder {
             c.define("__x86_64__", None);
         }
 
-        c.define("PIC", "_INTR_APIC_");
     }
 
     fn setup_global_include_dir(c: &mut Build) {
@@ -105,6 +104,76 @@ impl CFilesBuilder {
 
     /// 设置需要编译的文件
     fn setup_files(c: &mut Build) {
-        c.file("src/arch/x86_64/driver/hpet.c");
+        let mut files = Vec::new();
+
+        #[cfg(target_arch = "x86_64")]
+        Self::setup_files_x86_64(&mut files);
+
+        Self::set_rerun_if_files_changed(&files);
+        c.files(files.as_slice());
+    }
+
+    /// 设置x86_64架构下需要编译的C文件
+    fn setup_files_x86_64(files: &mut Vec<PathBuf>) {
+        files.push(PathBuf::from("src/arch/x86_64/driver/hpet.c"));
+        // 获取`kernel/src/arch/x86_64/driver/apic`下的所有C文件
+        files.append(&mut FileUtils::list_all_files(
+            &PathBuf::from("src/arch/x86_64/driver/apic"),
+            Some("c"),
+            true,
+        ));
+    }
+
+    /// 设置Cargo对文件更改的监听
+    fn set_rerun_if_files_changed(files: &Vec<PathBuf>) {
+        for f in files {
+            println!("cargo:rerun-if-changed={}", f.to_str().unwrap());
+        }
+    }
+}
+
+struct FileUtils;
+
+impl FileUtils {
+    /// 列出指定目录下的所有文件
+    ///
+    /// ## 参数
+    ///
+    /// - `path` - 指定的目录
+    /// - `ext_name` - 文件的扩展名,如果为None,则列出所有文件
+    /// - `recursive` - 是否递归列出所有文件
+    pub fn list_all_files(path: &PathBuf, ext_name: Option<&str>, recursive: bool) -> Vec<PathBuf> {
+        let mut queue: Vec<PathBuf> = Vec::new();
+        let mut result = Vec::new();
+        queue.push(path.clone());
+
+        while !queue.is_empty() {
+            let path = queue.pop().unwrap();
+            let d = std::fs::read_dir(path);
+            if d.is_err() {
+                continue;
+            }
+            let d = d.unwrap();
+
+            d.for_each(|ent| {
+                if let Ok(ent) = ent {
+                    if let Ok(file_type) = ent.file_type() {
+                        if file_type.is_file() {
+                            if let Some(e) = ext_name {
+                                if let Some(ext) = ent.path().extension() {
+                                    if ext == e {
+                                        result.push(ent.path());
+                                    }
+                                }
+                            }
+                        } else if file_type.is_dir() && recursive {
+                            queue.push(ent.path());
+                        }
+                    }
+                }
+            });
+        }
+
+        return result;
     }
 }

+ 4 - 8
kernel/src/Makefile

@@ -8,9 +8,6 @@ lib_patterns := *.a
 LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
 
 
-# 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
-PIC := _INTR_APIC_
-
 # unwind/backtrace related
 UNWIND_ENABLE ?= yes
 CFLAGS_UNWIND =
@@ -22,14 +19,14 @@ ifeq ($(UNWIND_ENABLE), yes)
     RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld 
 endif
 
-CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -D $(PIC) -I $(shell pwd) -I $(shell pwd)/include -I $(shell pwd)/arch/x86_64/include
+CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -I $(shell pwd) -I $(shell pwd)/include -I $(shell pwd)/arch/x86_64/include
 
 export ASFLAGS := --64
 
 LD_LIST := head.o
 
 
-kernel_subdirs := common driver debug arch exception smp sched syscall ktest libs time
+kernel_subdirs := common driver debug arch exception smp syscall ktest libs time
 
 
 head.o: head.S
@@ -43,9 +40,8 @@ main.o: main.c
 	$(CC) $(CFLAGS) -c main.c  -o main.o
 
 kernel_rust:
-	rustup default nightly
-
 	RUSTFLAGS="$(RUSTFLAGS_UNWIND)" cargo +nightly-2023-01-21 build --release --target ./arch/x86_64/x86_64-unknown-none.json
+
 all: kernel
 
 	@echo "Linking kernel..."
@@ -78,7 +74,7 @@ ECHO:
 
 $(kernel_subdirs): ECHO
 
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)" kernel_root_path="$(shell pwd)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)"  kernel_root_path="$(shell pwd)"
 
 kernel: head.o main.o $(kernel_subdirs) kernel_rust
 	

+ 1 - 1
kernel/src/arch/Makefile

@@ -9,7 +9,7 @@ all:
 	@list='$(kernel_arch_subdirs)'; for subdir in $$list; do \
     		echo "make all in $$subdir";\
     		cd $$subdir;\
-    		$(MAKE) all CFLAGS="$(CFLAGS)" PIC="$(PIC)";\
+    		$(MAKE) all CFLAGS="$(CFLAGS)" ;\
     		cd ..;\
 	done
 

+ 1 - 1
kernel/src/arch/x86_64/Makefile

@@ -13,7 +13,7 @@ $(kernel_arch_x86_64_objs): ECHO
 	$(CC) $(CFLAGS) -c $@ -o [email protected]
 
 $(kernel_arch_x86_64_subdirs): ECHO
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 all: $(kernel_arch_x86_64_objs) $(kernel_arch_x86_64_subdirs)
 

+ 1 - 1
kernel/src/arch/x86_64/asm/Makefile

@@ -13,7 +13,7 @@ $(kernel_arch_x86_64_asm_objs): ECHO
 	$(CC) $(CFLAGS) -c $@ -o [email protected]
 
 # $(kernel_arch_x86_64_asm_subdirs): ECHO
-# 	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+# 	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 all: $(kernel_arch_x86_64_asm_objs)
 

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

@@ -0,0 +1,228 @@
+#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/gate.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 初始化apic控制器
+ *
+ */
+int apic_init()
+{
+    cli();
+    kinfo("Initializing APIC...");
+    // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
+    for (int i = 32; i <= 57; ++i)
+        set_intr_gate(i, 0, interrupt_table[i - 32]);
+
+    // 设置local apic中断门
+    for (int i = 150; i < 160; ++i)
+        set_intr_gate(i, 0, local_apic_interrupt_table[i - 150]);
+
+    // 初始化BSP的APIC
+    rs_apic_init_bsp();
+
+    kinfo("APIC initialized.");
+    // sti();
+    return 0;
+}
+/**
+ * @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

+ 1 - 84
kernel/src/driver/interrupt/apic/apic.h → kernel/src/arch/x86_64/driver/apic/apic.h

@@ -8,12 +8,6 @@
 #pragma GCC push_options
 #pragma GCC optimize("O0")
 
-#define APIC_SUCCESS 0
-#define APIC_E_NOTFOUND 1
-
-#define APIC_IO_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + IO_APIC_MAPPING_OFFSET
-#define APIC_LOCAL_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + LOCAL_APIC_MAPPING_OFFSET
-
 // 当前apic启用状态标志
 extern uint8_t __apic_enable_state;
 #define APIC_XAPIC_ENABLED 0
@@ -113,36 +107,6 @@ struct apic_LVT
 
 } __attribute((packed)); // 取消结构体的align
 
-/*
-    ICR
-*/
-
-struct INT_CMD_REG
-{
-    unsigned int vector : 8, // 0~7
-        deliver_mode : 3,    // 8~10
-        dest_mode : 1,       // 11
-        deliver_status : 1,  // 12
-        res_1 : 1,           // 13
-        level : 1,           // 14
-        trigger : 1,         // 15
-        res_2 : 2,           // 16~17
-        dest_shorthand : 2,  // 18~19
-        res_3 : 12;          // 20~31
-
-    union
-    {
-        struct
-        {
-            unsigned int res_4 : 24, // 32~55
-                dest_field : 8;      // 56~63
-        } apic_destination;
-
-        unsigned int x2apic_destination; // 32~63
-    } destination;
-
-} __attribute__((packed));
-
 /**
  * @brief I/O APIC 的中断定向寄存器的结构体
  *
@@ -243,18 +207,6 @@ struct apic_IO_APIC_RTE_entry
 #define POLARITY_HIGH 0
 #define POLARITY_LOW 1
 
-struct apic_IO_APIC_map
-{
-    // 间接访问寄存器的物理基地址
-    uint addr_phys;
-    // 索引寄存器虚拟地址
-    unsigned char *virtual_index_addr;
-    // 数据寄存器虚拟地址
-    uint *virtual_data_addr;
-    // EOI寄存器虚拟地址
-    uint *virtual_EOI_addr;
-} apic_ioapic_map;
-
 /**
  * @brief 中断服务程序
  *
@@ -262,28 +214,7 @@ struct apic_IO_APIC_map
  * @param number 中断向量号
  */
 void do_IRQ(struct pt_regs *rsp, ul number);
-
-/**
- * @brief 读取RTE寄存器
- *
- * @param index 索引值
- * @return ul
- */
-ul apic_ioapic_read_rte(unsigned char index);
-
-/**
- * @brief 写入RTE寄存器
- *
- * @param index 索引值
- * @param value 要写入的值
- */
-void apic_ioapic_write_rte(unsigned char index, ul value);
-
-/**
- * @brief 初始化AP处理器的Local apic
- *
- */
-void apic_init_ap_core_local_apic();
+void rs_apic_init_ap();
 
 /**
  * @brief 初始化apic控制器
@@ -291,22 +222,11 @@ void apic_init_ap_core_local_apic();
  */
 int apic_init();
 
-/**
- * @brief 读取指定类型的 Interrupt Control Structure
- *
- * @param type ics的类型
- * @param ret_vaddr 对应的ICS的虚拟地址数组
- * @param total 返回数组的元素总个数
- * @return uint
- */
-uint apic_get_ics(const uint type, ul ret_vaddr[], uint *total);
-
 // =========== 中断控制操作接口 ============
 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_level_ack(ul irq_num); // ioapic电平触发 应答
 void apic_ioapic_edge_ack(ul irq_num);  // ioapic边沿触发 应答
 
 // void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答
@@ -329,7 +249,4 @@ void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答
 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);
 
-uint32_t apic_get_local_apic_id();
-void apic_write_icr(uint64_t value);
-bool apic_x2apic_enabled();
 #pragma GCC pop_options

+ 13 - 45
kernel/src/driver/interrupt/apic/apic_timer.c → kernel/src/arch/x86_64/driver/apic/apic_timer.c

@@ -4,15 +4,15 @@
 #include <process/process.h>
 #include <sched/sched.h>
 
-// #pragma GCC push_options
-// #pragma GCC optimize("O0")
-uint64_t apic_timer_ticks_result = 0;
-static spinlock_t apic_timer_init_lock = {1};
+
 // bsp 是否已经完成apic时钟初始化
 static bool bsp_initialized = false;
 
-extern uint64_t rs_get_cycles();
-extern uint64_t rs_tsc_get_cpu_khz();
+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时钟
@@ -30,19 +30,12 @@ void apic_timer_ap_core_init()
 
 void apic_timer_enable(uint64_t irq_num)
 {
-    // 启动apic定时器
-    io_mfence();
-    uint64_t val = apic_timer_get_LVT();
-    io_mfence();
-    val &= (~APIC_LVT_INT_MASKED);
-    io_mfence();
-    apic_timer_write_LVT(val);
-    io_mfence();
+    rs_apic_timer_enable(irq_num);
 }
 
 void apic_timer_disable(uint64_t irq_num)
 {
-    apic_timer_stop();
+    rs_apic_timer_disable(irq_num);
 }
 
 /**
@@ -54,33 +47,14 @@ void apic_timer_disable(uint64_t irq_num)
  */
 uint64_t apic_timer_install(ul irq_num, void *arg)
 {
-    // 设置div16
-    io_mfence();
-    apic_timer_stop();
-    io_mfence();
-    apic_timer_set_div(APIC_TIMER_DIVISOR);
-    io_mfence();
 
-    // 设置初始计数
-
-    uint64_t cpu_khz = rs_tsc_get_cpu_khz();
-    // 疑惑:这里使用khz吗?
-    // 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的
-    // 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑
-    // TODO: 这里需要进一步研究
-    uint64_t init_cnt = cpu_khz * APIC_TIMER_INTERVAL / (1000 * APIC_TIMER_DIVISOR);
-    kdebug("cpu_khz: %ld, init_cnt: %ld", cpu_khz, init_cnt);
-    apic_timer_set_init_cnt(init_cnt);
-    io_mfence();
-    // 填写LVT
-    apic_timer_set_LVT(APIC_TIMER_IRQ_NUM, 1, APIC_LVT_Timer_Periodic);
-    io_mfence();
+    rs_apic_timer_install(irq_num);
+    return 0;
 }
 
 void apic_timer_uninstall(ul irq_num)
 {
-    apic_timer_write_LVT(APIC_LVT_INT_MASKED);
-    io_mfence();
+    rs_apic_timer_uninstall(irq_num);
 }
 
 hardware_intr_controller apic_timer_intr_controller = {
@@ -100,9 +74,7 @@ hardware_intr_controller apic_timer_intr_controller = {
  */
 void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
 {
-    io_mfence();
-    sched_update_jiffies();
-    io_mfence();
+    rs_apic_timer_handle_irq();
 }
 
 /**
@@ -111,9 +83,6 @@ void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
  */
 void apic_timer_init()
 {
-
-    uint64_t flags = 0;
-    spin_lock_irqsave(&apic_timer_init_lock, flags);
     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,
@@ -124,5 +93,4 @@ void apic_timer_init()
         bsp_initialized = true;
     }
     kdebug("apic timer init done for cpu %d", rs_current_pcb_cpuid());
-    spin_unlock_irqrestore(&apic_timer_init_lock, flags);
-}
+}

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

@@ -0,0 +1,14 @@
+#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();

+ 257 - 0
kernel/src/arch/x86_64/driver/apic/apic_timer.rs

@@ -0,0 +1,257 @@
+use core::cell::RefCell;
+
+use crate::arch::driver::tsc::TSCManager;
+use crate::include::bindings::bindings::APIC_TIMER_IRQ_NUM;
+
+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::syscall::SystemError;
+pub use drop;
+use x86::cpuid::cpuid;
+use x86::msr::{wrmsr, IA32_X2APIC_DIV_CONF, IA32_X2APIC_INIT_COUNT};
+
+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];
+
+#[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() }
+}
+
+#[inline(always)]
+pub(super) fn local_apic_timer_instance_mut(
+    cpu_id: u32,
+) -> core::cell::RefMut<'static, LocalApicTimer> {
+    unsafe { LOCAL_APIC_TIMERS[cpu_id as usize].borrow_mut() }
+}
+
+/// 初始化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);
+    local_apic_timer.init(
+        LocalApicTimerMode::Periodic,
+        LocalApicTimer::periodic_default_initial_count(),
+        LocalApicTimer::DIVISOR as u32,
+    );
+    kdebug!("init_bsp_apic_timer done");
+}
+
+fn init_ap_apic_timer() {
+    kdebug!("init_ap_apic_timer");
+    let cpu_id = smp_get_processor_id();
+    assert!(cpu_id != 0);
+
+    let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id);
+    local_apic_timer.init(
+        LocalApicTimerMode::Periodic,
+        LocalApicTimer::periodic_default_initial_count(),
+        LocalApicTimer::DIVISOR as u32,
+    );
+    kdebug!("init_ap_apic_timer done");
+}
+
+pub(super) struct LocalApicTimerIntrController;
+
+impl LocalApicTimerIntrController {
+    pub(super) fn install(&self, _irq_num: u8) {
+        kdebug!("LocalApicTimerIntrController::install");
+        if smp_get_processor_id() == 0 {
+            init_bsp_apic_timer();
+        } else {
+            init_ap_apic_timer();
+        }
+    }
+
+    pub(super) fn uninstall(&self) {
+        let cpu_id = smp_get_processor_id();
+        let local_apic_timer = local_apic_timer_instance(cpu_id);
+        local_apic_timer.stop_current();
+    }
+
+    pub(super) fn enable(&self) {
+        kdebug!("LocalApicTimerIntrController::enable");
+        let cpu_id = smp_get_processor_id();
+        let mut local_apic_timer = local_apic_timer_instance_mut(cpu_id);
+        local_apic_timer.start_current();
+    }
+
+    pub(super) fn disable(&self) {
+        let cpu_id = smp_get_processor_id();
+        let local_apic_timer = local_apic_timer_instance_mut(cpu_id);
+        local_apic_timer.stop_current();
+    }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub struct LocalApicTimer {
+    mode: LocalApicTimerMode,
+    /// IntialCount
+    initial_count: u64,
+    divisor: u32,
+    /// 是否已经触发(oneshot模式)
+    triggered: bool,
+}
+
+#[derive(Debug, Copy, Clone)]
+#[repr(u32)]
+pub enum LocalApicTimerMode {
+    Oneshot = 0,
+    Periodic = 1,
+    Deadline = 2,
+}
+
+impl LocalApicTimer {
+    /// 定时器中断的间隔
+    pub const INTERVAL_MS: u64 = 5;
+    pub const DIVISOR: u64 = 3;
+
+    /// IoApicManager 初值为0或false
+    pub const fn new() -> Self {
+        LocalApicTimer {
+            mode: LocalApicTimerMode::Periodic,
+            initial_count: 0,
+            divisor: 0,
+            triggered: false,
+        }
+    }
+
+    /// 周期模式下的默认初始值
+    pub fn periodic_default_initial_count() -> u64 {
+        let cpu_khz = TSCManager::cpu_khz();
+
+        // 疑惑:这里使用khz吗?
+        // 我觉得应该是hz,但是由于旧的代码是测量出initcnt的,而不是计算的
+        // 然后我发现使用hz会导致计算出来的initcnt太大,导致系统卡顿,而khz的却能跑
+        let count = cpu_khz * Self::INTERVAL_MS / (1000 * Self::DIVISOR);
+        return count;
+    }
+
+    /// Init this manager.
+    ///
+    /// At this time, it does nothing.
+    fn init(&mut self, mode: LocalApicTimerMode, initial_count: u64, divisor: u32) {
+        self.stop_current();
+        self.triggered = false;
+        match mode {
+            LocalApicTimerMode::Periodic => self.install_periodic_mode(initial_count, divisor),
+            LocalApicTimerMode::Oneshot => todo!(),
+            LocalApicTimerMode::Deadline => todo!(),
+        }
+    }
+
+    fn install_periodic_mode(&mut self, initial_count: u64, divisor: u32) {
+        kdebug!(
+            "install_periodic_mode: initial_count = {}, divisor = {}",
+            initial_count,
+            divisor
+        );
+        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);
+    }
+
+    fn setup_lvt(&mut self, vector: u8, mask: bool, mode: LocalApicTimerMode) {
+        let mode: u32 = mode as u32;
+        let data = (mode << 17) | (vector as u32) | (if mask { 1 << 16 } else { 0 });
+        let lvt = LVT::new(LVTRegister::Timer, data).unwrap();
+
+        CurrentApic.set_lvt(lvt);
+    }
+
+    fn set_divisor(&mut self, divisor: u32) {
+        self.divisor = divisor;
+        CurrentApic.set_timer_divisor(divisor as u32);
+    }
+
+    fn set_initial_cnt(&mut self, initial_count: u64) {
+        self.initial_count = initial_count;
+        CurrentApic.set_timer_initial_count(initial_count);
+    }
+
+    fn start_current(&mut self) {
+        let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer);
+        lvt.set_mask(false);
+        CurrentApic.set_lvt(lvt);
+    }
+
+    fn stop_current(&self) {
+        let mut lvt = CurrentApic.read_lvt(LVTRegister::Timer);
+        lvt.set_mask(true);
+        CurrentApic.set_lvt(lvt);
+    }
+
+    /// 检查是否支持TSC-Deadline
+    ///
+    /// 此函数调用cpuid,请避免多次调用此函数。
+    /// 如果支持TSC-Deadline模式,则除非TSC为常数,否则不会启用该模式。
+    #[allow(dead_code)]
+    pub fn is_deadline_mode_supported(&self) -> bool {
+        let res = cpuid!(1);
+        return (res.ecx & (1 << 24)) != 0;
+    }
+
+    pub(super) fn handle_irq() -> Result<(), SystemError> {
+        sched_update_jiffies();
+        return Ok(());
+    }
+}
+
+impl TryFrom<u8> for LocalApicTimerMode {
+    type Error = SystemError;
+
+    fn try_from(value: u8) -> Result<Self, Self::Error> {
+        match value {
+            0b00 => {
+                return Ok(LocalApicTimerMode::Oneshot);
+            }
+            0b01 => {
+                return Ok(LocalApicTimerMode::Periodic);
+            }
+            0b10 => {
+                return Ok(LocalApicTimerMode::Deadline);
+            }
+            _ => {
+                return Err(SystemError::EINVAL);
+            }
+        }
+    }
+}
+
+impl CurrentApic {
+    fn set_timer_divisor(&self, divisor: u32) {
+        if self.x2apic_enabled() {
+            unsafe { wrmsr(IA32_X2APIC_DIV_CONF, divisor.into()) };
+        } else {
+            unsafe {
+                self.write_xapic_register(
+                    XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_CLKDIV,
+                    divisor.into(),
+                )
+            };
+        }
+    }
+
+    fn set_timer_initial_count(&self, initial_count: u64) {
+        if self.x2apic_enabled() {
+            unsafe {
+                wrmsr(IA32_X2APIC_INIT_COUNT.into(), initial_count);
+            }
+        } else {
+            unsafe {
+                self.write_xapic_register(
+                    XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG,
+                    initial_count as u32,
+                )
+            };
+        }
+    }
+}

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

@@ -0,0 +1,84 @@
+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;
+}
+
+#[no_mangle]
+pub extern "C" fn rs_apic_init_ap() -> i32 {
+    if CurrentApic.init_current_cpu() {
+        return 0;
+    }
+
+    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());
+}

+ 364 - 0
kernel/src/arch/x86_64/driver/apic/ioapic.rs

@@ -0,0 +1,364 @@
+use core::ptr::NonNull;
+
+use acpi::madt::Madt;
+use bit_field::BitField;
+use bitflags::bitflags;
+
+use crate::{
+    driver::acpi::acpi_manager,
+    kdebug, kinfo,
+    libs::{
+        once::Once,
+        spinlock::SpinLock,
+        volatile::{volwrite, Volatile},
+    },
+    mm::{
+        mmio_buddy::{mmio_pool, MMIOSpaceGuard},
+        PhysAddr,
+    },
+    syscall::SystemError,
+};
+
+use super::{CurrentApic, LocalAPIC};
+
+static mut __IOAPIC: Option<SpinLock<IoApic>> = None;
+
+#[allow(non_snake_case)]
+fn IOAPIC() -> &'static SpinLock<IoApic> {
+    unsafe { __IOAPIC.as_ref().unwrap() }
+}
+
+#[allow(dead_code)]
+pub struct IoApic {
+    reg: *mut u32,
+    data: *mut u32,
+    virt_eoi: *mut u32,
+    phys_base: PhysAddr,
+    mmio_guard: MMIOSpaceGuard,
+}
+
+impl IoApic {
+    /// IO APIC的中断向量号从32开始
+    pub const VECTOR_BASE: u8 = 32;
+
+    /// Create a new IOAPIC.
+    ///
+    /// # Safety
+    ///
+    /// You must provide a valid address.
+    pub unsafe fn new() -> Self {
+        static INIT_STATE: Once = Once::new();
+        assert!(!INIT_STATE.is_completed());
+
+        let mut result: Option<IoApic> = None;
+        INIT_STATE.call_once(|| {
+            kinfo!("Initializing ioapic...");
+
+            // get ioapic base from acpi
+
+            let madt = acpi_manager()
+                .tables()
+                .unwrap()
+                .find_table::<Madt>()
+                .expect("IoApic::new(): failed to find MADT");
+
+            let io_apic_paddr = madt
+                .entries()
+                .find(|x| {
+                    if let acpi::madt::MadtEntry::IoApic(_x) = x {
+                        return true;
+                    }
+                    return false;
+                })
+                .map(|x| {
+                    if let acpi::madt::MadtEntry::IoApic(x) = x {
+                        Some(x.io_apic_address)
+                    } else {
+                        None
+                    }
+                })
+                .flatten()
+                .unwrap();
+
+            let phys_base = PhysAddr::new(io_apic_paddr as usize);
+
+            let mmio_guard = mmio_pool()
+                .create_mmio(0x1000)
+                .expect("IoApic::new(): failed to create mmio");
+            assert!(
+                mmio_guard.map_phys(phys_base, 0x1000).is_ok(),
+                "IoApic::new(): failed to map phys"
+            );
+            kdebug!("Ioapic map ok");
+            let reg = mmio_guard.vaddr();
+
+            result = Some(IoApic {
+                reg: reg.data() as *mut u32,
+                data: (reg + 0x10).data() as *mut u32,
+                virt_eoi: (reg + 0x40).data() as *mut u32,
+                phys_base,
+                mmio_guard,
+            });
+            kdebug!("IOAPIC: to mask all RTE");
+            // 屏蔽所有的RTE
+            let res_mut = result.as_mut().unwrap();
+            for i in 0..res_mut.supported_interrupts() {
+                res_mut.write_rte(i, 0x20 + i, RedirectionEntry::DISABLED, 0);
+            }
+            kdebug!("Ioapic init done");
+        });
+
+        assert!(
+            result.is_some(),
+            "Failed to init ioapic, maybe this is a double initialization bug?"
+        );
+        return result.unwrap();
+    }
+
+    /// Disable all interrupts.
+    #[allow(dead_code)]
+    pub fn disable_all(&mut self) {
+        // Mark all interrupts edge-triggered, active high, disabled,
+        // and not routed to any CPUs.
+        for i in 0..self.supported_interrupts() {
+            self.disable(i);
+        }
+    }
+
+    unsafe fn read(&mut self, reg: u8) -> u32 {
+        assert!(!(0x3..REG_TABLE).contains(&reg));
+        self.reg.write_volatile(reg as u32);
+        self.data.read_volatile()
+    }
+
+    /// 直接写入REG_TABLE内的寄存器
+    ///
+    /// ## 参数
+    ///
+    /// * `reg` - 寄存器下标
+    /// * `data` - 寄存器数据
+    unsafe fn write(&mut self, reg: u8, data: u32) {
+        // 0x1 & 0x2 are read-only regs
+        assert!(!(0x1..REG_TABLE).contains(&reg));
+        self.reg.write_volatile(reg as u32);
+        self.data.write_volatile(data);
+    }
+
+    fn write_rte(&mut self, rte_index: u8, vector: u8, flags: RedirectionEntry, dest: u8) {
+        unsafe {
+            self.write(REG_TABLE + 2 * rte_index, vector as u32 | flags.bits());
+            self.write(REG_TABLE + 2 * rte_index + 1, (dest as u32) << 24);
+        }
+    }
+
+    /// 标记中断边沿触发、高电平有效、
+    /// 启用并路由到给定的 cpunum,即是是该 cpu 的 APIC ID(不是cpuid)
+    pub fn enable(&mut self, rte_index: u8) {
+        let mut val = unsafe { self.read(REG_TABLE + 2 * rte_index) };
+        val &= !RedirectionEntry::DISABLED.bits();
+        unsafe { self.write(REG_TABLE + 2 * rte_index, val) };
+    }
+
+    pub fn disable(&mut self, rte_index: u8) {
+        let reg = REG_TABLE + 2 * rte_index;
+        let mut val = unsafe { self.read(reg) };
+        val |= RedirectionEntry::DISABLED.bits();
+        unsafe { self.write(reg, val) };
+    }
+
+    /// 安装中断
+    ///
+    /// ## 参数
+    ///
+    /// * `rte_index` - RTE下标
+    /// * `vector` - 中断向量号
+    /// * `dest` - 目标CPU的APIC ID
+    /// * `level_triggered` - 是否为电平触发
+    /// * `active_high` - 是否为高电平有效
+    /// * `dest_logic` - 是否为逻辑模式
+    /// * `mask` - 是否屏蔽
+    pub fn install(
+        &mut self,
+        rte_index: u8,
+        vector: u8,
+        dest: u8,
+        level_triggered: bool,
+        active_high: bool,
+        dest_logic: bool,
+        mut mask: bool,
+    ) -> Result<(), SystemError> {
+        // 重定向表从 REG_TABLE 开始,使用两个寄存器来配置每个中断。
+        // 一对中的第一个(低位)寄存器包含配置位。32bit
+        // 第二个(高)寄存器包含一个位掩码,告诉哪些 CPU 可以服务该中断。
+        //  level_triggered:如果为真,表示中断触发方式为电平触发(level-triggered),则将RedirectionEntry::LEVEL标志位设置在flags中。
+        //  active_high:如果为假,表示中断的极性为低电平有效(active-low),则将RedirectionEntry::ACTIVELOW标志位设置在flags中。
+        //  dest_logic:如果为真,表示中断目标为逻辑模式(logical mode),则将RedirectionEntry::LOGICAL标志位设置在flags中。
+        //  !(0x20..=0xef).contains(&vector):判断中断向量号(vector)是否在范围0x20到0xef之外,如果是,则表示中断无效,将mask标志位设置为真。
+        //  mask:如果为真,表示中断被屏蔽(masked),将RedirectionEntry::DISABLED标志位设置在flags中。
+        let mut flags = RedirectionEntry::NONE;
+        if level_triggered {
+            flags |= RedirectionEntry::LEVEL;
+        }
+        if !active_high {
+            flags |= RedirectionEntry::ACTIVELOW;
+        }
+        if dest_logic {
+            flags |= RedirectionEntry::LOGICAL;
+        }
+        if !(0x20..=0xef).contains(&vector) {
+            mask = true;
+        }
+        if mask {
+            flags |= RedirectionEntry::DISABLED;
+        }
+        self.write_rte(rte_index, vector, flags, dest);
+        return Ok(());
+    }
+
+    /// Get the vector number for the given IRQ.
+    #[allow(dead_code)]
+    pub fn irq_vector(&mut self, irq: u8) -> u8 {
+        unsafe { self.read(REG_TABLE + 2 * irq).get_bits(0..8) as u8 }
+    }
+
+    /// Set the vector number for the given IRQ.
+    #[allow(dead_code)]
+    pub fn set_irq_vector(&mut self, irq: u8, vector: u8) {
+        let mut old = unsafe { self.read(REG_TABLE + 2 * irq) };
+        let old_vector = old.get_bits(0..8);
+        if !(0x20..=0xfe).contains(&old_vector) {
+            old |= RedirectionEntry::DISABLED.bits();
+        }
+        unsafe {
+            self.write(REG_TABLE + 2 * irq, *old.set_bits(0..8, vector as u32));
+        }
+    }
+
+    #[allow(dead_code)]
+    pub fn id(&mut self) -> u8 {
+        unsafe { self.read(REG_ID).get_bits(24..28) as u8 }
+    }
+
+    /// IO APIC Version
+    #[allow(dead_code)]
+    pub fn version(&mut self) -> u8 {
+        unsafe { self.read(REG_VER).get_bits(0..8) as u8 }
+    }
+
+    /// Number of supported interrupts by this IO APIC.
+    ///
+    /// Max Redirection Entry = "how many IRQs can this I/O APIC handle - 1"
+    /// The -1 is silly so we add one back to it.
+    pub fn supported_interrupts(&mut self) -> u8 {
+        unsafe { (self.read(REG_VER).get_bits(16..24) + 1) as u8 }
+    }
+
+    fn vector_rte_index(irq_num: u8) -> u8 {
+        assert!(irq_num >= Self::VECTOR_BASE);
+        irq_num - Self::VECTOR_BASE
+    }
+
+    /// 电平响应
+    #[allow(dead_code)]
+    fn level_ack(&mut self, irq_num: u8) {
+        #[repr(C)]
+        struct LevelAck {
+            virt_eoi: Volatile<u32>,
+        }
+
+        let p = NonNull::new(self.virt_eoi as *mut LevelAck).unwrap();
+
+        unsafe {
+            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
+const REG_ID: u8 = 0x00;
+/// 获取IO APIC Version
+const REG_VER: u8 = 0x01;
+/// Redirection table base
+const REG_TABLE: u8 = 0x10;
+
+bitflags! {
+    /// The redirection table starts at REG_TABLE and uses
+    /// two registers to configure each interrupt.
+    /// The first (low) register in a pair contains configuration bits.
+    /// The second (high) register contains a bitmask telling which
+    /// CPUs can serve that interrupt.
+    struct RedirectionEntry: u32 {
+        /// Interrupt disabled
+        const DISABLED  = 0x00010000;
+        /// Level-triggered (vs edge-)
+        const LEVEL     = 0x00008000;
+        /// Active low (vs high)
+        const ACTIVELOW = 0x00002000;
+        /// Destination is CPU id (vs APIC ID)
+        const LOGICAL   = 0x00000800;
+        /// None
+        const NONE		= 0x00000000;
+    }
+}
+
+pub fn ioapic_init() {
+    kinfo!("Initializing ioapic...");
+    let ioapic = unsafe { IoApic::new() };
+    unsafe {
+        __IOAPIC = Some(SpinLock::new(ioapic));
+    }
+    kinfo!("IO Apic initialized.");
+}
+
+/// 安装中断
+///
+/// ## 参数
+///
+/// * `vector` - 中断向量号
+/// * `dest` - 目标CPU的APIC ID
+/// * `level_triggered` - 是否为电平触发
+/// * `active_high` - 是否为高电平有效
+/// * `dest_logic` - 是否为逻辑模式
+/// * `mask` - 是否屏蔽
+pub(super) fn ioapic_install(
+    vector: u8,
+    dest: u8,
+    level_triggered: bool,
+    active_high: bool,
+    dest_logic: bool,
+) -> Result<(), SystemError> {
+    let rte_index = IoApic::vector_rte_index(vector);
+    return IOAPIC().lock_irqsave().install(
+        rte_index,
+        vector,
+        dest,
+        level_triggered,
+        active_high,
+        dest_logic,
+        true,
+    );
+}
+
+/// 卸载中断
+pub(super) fn ioapic_uninstall(vector: u8) {
+    let rte_index = IoApic::vector_rte_index(vector);
+    IOAPIC().lock_irqsave().disable(rte_index);
+}
+
+/// 使能中断
+pub(super) fn ioapic_enable(vector: u8) {
+    let rte_index = IoApic::vector_rte_index(vector);
+    IOAPIC().lock_irqsave().enable(rte_index);
+}
+
+/// 禁用中断
+pub(super) fn ioapic_disable(vector: u8) {
+    let rte_index = IoApic::vector_rte_index(vector);
+    IOAPIC().lock_irqsave().disable(rte_index);
+}

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

@@ -0,0 +1,623 @@
+use core::sync::atomic::Ordering;
+
+use atomic_enum::atomic_enum;
+use x86::{apic::Icr, msr::IA32_APIC_BASE};
+
+use crate::{
+    arch::{
+        driver::apic::{ioapic::ioapic_init, x2apic::X2Apic, xapic::XApic},
+        io::PortIOArch,
+        CurrentPortIOArch,
+    },
+    kdebug, kinfo,
+    mm::PhysAddr,
+    smp::core::smp_get_processor_id,
+    syscall::SystemError,
+};
+
+use self::{
+    apic_timer::LocalApicTimerMode,
+    xapic::{current_xapic_instance, XApicOffset},
+};
+
+pub mod apic_timer;
+mod c_adapter;
+pub mod ioapic;
+pub mod x2apic;
+pub mod xapic;
+
+/// 当前启用的APIC类型
+#[atomic_enum]
+#[derive(PartialEq, Eq)]
+pub enum LocalApicEnableType {
+    XApic,
+    X2Apic,
+}
+
+static LOCAL_APIC_ENABLE_TYPE: AtomicLocalApicEnableType =
+    AtomicLocalApicEnableType::new(LocalApicEnableType::XApic);
+
+pub trait LocalAPIC {
+    /// @brief 判断当前处理器是否支持这个类型的apic
+    ///
+    /// @return true 当前处理器支持这个类型的apic
+    /// @return false 当前处理器不支持这个类型的apic
+    fn support() -> bool;
+
+    /// @brief 为当前处理器初始化local apic
+    ///
+    /// @return true 初始化成功
+    /// @return false 初始化失败
+    fn init_current_cpu(&mut self) -> bool;
+
+    /// @brief 发送EOI信号(End of interrupt)
+    fn send_eoi(&self);
+
+    /// @brief 获取APIC版本号
+    fn version(&self) -> u8;
+
+    /// @brief 判断当前处理器是否支持EOI广播抑制
+    fn support_eoi_broadcast_suppression(&self) -> bool;
+
+    /// 获取最多支持的LVT寄存器数量
+    fn max_lvt_entry(&self) -> u8;
+
+    /// @brief 获取当前处理器的APIC ID
+    fn id(&self) -> u32;
+
+    /// @brief 设置LVT寄存器
+    ///
+    /// @param register 寄存器
+    /// @param lvt 要被设置成的值
+    fn set_lvt(&mut self, lvt: LVT);
+
+    /// 读取LVT寄存器
+    fn read_lvt(&self, reg: LVTRegister) -> LVT;
+
+    fn mask_all_lvt(&mut self);
+
+    /// 写入ICR寄存器
+    fn write_icr(&self, icr: Icr);
+}
+
+/// @brief 所有LVT寄存器的枚举类型
+#[allow(dead_code)]
+#[repr(u32)]
+#[derive(Debug, Clone, Copy)]
+pub enum LVTRegister {
+    /// CMCI寄存器
+    ///
+    /// 如果支持CMCI功能,那么,当修正的机器错误超过阈值时,Local APIC通过CMCI寄存器的配置,
+    /// 向处理器核心投递中断消息
+    CMCI = 0x82f,
+    /// 定时器寄存器
+    ///
+    /// 当APIC定时器产生中断信号时,Local APIC通过定时器寄存器的设置,向处理器投递中断消息
+    Timer = 0x832,
+    /// 温度传感器寄存器
+    ///
+    /// 当处理器内部的温度传感器产生中断请求信号时,Local APIC会通过温度传感器寄存器的设置,
+    /// 向处理器投递中断消息。
+    Thermal = 0x833,
+    /// 性能监控计数器寄存器
+    ///
+    /// 当性能检测计数器寄存器溢出,产生中断请求时,Local APIC将会根据这个寄存器的配置,
+    /// 向处理器投递中断消息
+    PerformanceMonitor = 0x834,
+    /// 当处理器的LINT0引脚接收到中断请求信号时,Local APIC会根据这个寄存器的配置,
+    /// 向处理器投递中断消息
+    LINT0 = 0x835,
+    /// 当处理器的LINT0引脚接收到中断请求信号时,Local APIC会根据这个寄存器的配置,
+    /// 向处理器投递中断消息
+    LINT1 = 0x836,
+    /// 错误寄存器
+    ///
+    /// 当APIC检测到内部错误而产生中断请求信号时,它将会通过错误寄存器的设置,向处理器投递中断消息
+    ErrorReg = 0x837,
+}
+
+impl Into<u32> for LVTRegister {
+    fn into(self) -> u32 {
+        self as u32
+    }
+}
+
+#[derive(Debug)]
+pub struct LVT {
+    register: LVTRegister,
+    data: u32,
+}
+
+impl LVT {
+    /// 当第16位为1时,表示屏蔽中断
+    pub const MASKED: u32 = 1 << 16;
+
+    pub fn new(register: LVTRegister, data: u32) -> Option<Self> {
+        // vector: u8, mode: DeliveryMode, status: DeliveryStatus
+        let mut result = Self { register, data: 0 };
+        result.set_vector((data & 0xFF) as u8);
+        match result.register {
+            LVTRegister::Timer | LVTRegister::ErrorReg => {}
+            _ => {
+                result
+                    .set_delivery_mode(DeliveryMode::try_from(((data >> 8) & 0b111) as u8).ok()?)
+                    .ok()?;
+            }
+        }
+
+        if let LVTRegister::LINT0 | LVTRegister::LINT1 = result.register {
+            result.set_interrupt_input_pin_polarity((data & (1 << 13)) == 0);
+
+            if data & (1 << 15) != 0 {
+                result.set_trigger_mode(TriggerMode::Level).ok()?;
+            } else {
+                result.set_trigger_mode(TriggerMode::Edge).ok()?;
+            }
+        }
+        result.set_mask((data & (1 << 16)) != 0);
+
+        if let LVTRegister::Timer = result.register {
+            result
+                .set_timer_mode(LocalApicTimerMode::try_from(((data >> 17) & 0b11) as u8).ok()?)
+                .ok()?;
+        }
+
+        return Some(result);
+    }
+
+    /// 获取LVT寄存器的原始值
+    #[allow(dead_code)]
+    pub fn data(&self) -> u32 {
+        return self.data;
+    }
+
+    pub fn register(&self) -> LVTRegister {
+        return self.register;
+    }
+
+    pub fn set_vector(&mut self, vector: u8) {
+        self.data &= !((1 << 8) - 1);
+        self.data |= vector as u32;
+    }
+
+    /// 获取中断向量号
+    #[allow(dead_code)]
+    pub fn vector(&self) -> u8 {
+        return (self.data & 0xFF) as u8;
+    }
+
+    /// 设置中断投递模式
+    ///
+    /// Timer、ErrorReg寄存器不支持这个功能
+    ///
+    /// ## 参数
+    ///
+    /// - `mode`:投递模式
+    pub fn set_delivery_mode(&mut self, mode: DeliveryMode) -> Result<(), SystemError> {
+        match self.register {
+            LVTRegister::Timer | LVTRegister::ErrorReg => {
+                return Err(SystemError::EINVAL);
+            }
+            _ => {}
+        }
+
+        self.data &= 0xFFFF_F8FF;
+        self.data |= ((mode as u32) & 0x7) << 8;
+        return Ok(());
+    }
+
+    /// 获取中断投递模式
+    /// Timer、ErrorReg寄存器不支持这个功能
+    #[allow(dead_code)]
+    pub fn delivery_mode(&self) -> Option<DeliveryMode> {
+        if let LVTRegister::Timer | LVTRegister::ErrorReg = self.register {
+            return None;
+        }
+        return DeliveryMode::try_from(((self.data >> 8) & 0b111) as u8).ok();
+    }
+
+    /// Get the delivery status of the interrupt
+    #[allow(dead_code)]
+    pub fn delivery_status(&self) -> DeliveryStatus {
+        return DeliveryStatus::from(self.data);
+    }
+
+    /// 设置中断输入引脚的极性
+    ///
+    /// ## 参数
+    ///
+    /// - `high`:true表示高电平有效,false表示低电平有效
+    pub fn set_interrupt_input_pin_polarity(&mut self, high: bool) {
+        self.data &= 0xFFFF_DFFF;
+        // 0表示高电平有效,1表示低电平有效
+        if !high {
+            self.data |= 1 << 13;
+        }
+    }
+
+    /// 获取中断输入引脚的极性
+    ///
+    /// true表示高电平有效,false表示低电平有效
+    #[allow(dead_code)]
+    pub fn interrupt_input_pin_polarity(&self) -> bool {
+        return (self.data & (1 << 13)) == 0;
+    }
+
+    /// 设置中断输入引脚的触发模式
+    ///
+    /// 只有LINT0和LINT1寄存器支持这个功能
+    ///
+    /// ## 参数
+    ///
+    /// - `trigger_mode`:触发模式
+    pub fn set_trigger_mode(&mut self, trigger_mode: TriggerMode) -> Result<(), SystemError> {
+        match self.register {
+            LVTRegister::LINT0 | LVTRegister::LINT1 => {
+                self.data &= 0xFFFF_7FFF;
+                if trigger_mode == TriggerMode::Level {
+                    self.data |= 1 << 15;
+                }
+                return Ok(());
+            }
+            _ => {
+                return Err(SystemError::EINVAL);
+            }
+        }
+    }
+
+    /// 获取中断输入引脚的触发模式
+    ///
+    /// 只有LINT0和LINT1寄存器支持这个功能
+    #[allow(dead_code)]
+    pub fn trigger_mode(&self) -> Option<TriggerMode> {
+        match self.register {
+            LVTRegister::LINT0 | LVTRegister::LINT1 => {
+                if self.data & (1 << 15) != 0 {
+                    return Some(TriggerMode::Level);
+                } else {
+                    return Some(TriggerMode::Edge);
+                }
+            }
+            _ => {
+                return None;
+            }
+        }
+    }
+
+    /// 设置是否屏蔽中断
+    ///
+    /// ## 参数
+    ///
+    /// - `mask`:true表示屏蔽中断,false表示不屏蔽中断
+    pub fn set_mask(&mut self, mask: bool) {
+        self.data &= 0xFFFE_FFFF;
+        if mask {
+            self.data |= 1 << 16;
+        }
+    }
+
+    /// Check if the interrupt is masked
+    ///
+    /// true表示屏蔽中断,false表示不屏蔽中断
+    #[allow(dead_code)]
+    pub fn mask(&self) -> bool {
+        return (self.data & (1 << 16)) != 0;
+    }
+
+    /// 设置定时器模式
+    pub fn set_timer_mode(&mut self, mode: LocalApicTimerMode) -> Result<(), SystemError> {
+        match self.register {
+            LVTRegister::Timer => {
+                self.data &= 0xFFF9_FFFF;
+                match mode {
+                    LocalApicTimerMode::Oneshot => {
+                        self.data |= 0b00 << 17;
+                    }
+                    LocalApicTimerMode::Periodic => {
+                        self.data |= 0b01 << 17;
+                    }
+                    LocalApicTimerMode::Deadline => {
+                        self.data |= 0b10 << 17;
+                    }
+                }
+                return Ok(());
+            }
+            _ => {
+                return Err(SystemError::EINVAL);
+            }
+        }
+    }
+
+    /// 获取定时器模式
+    #[allow(dead_code)]
+    pub fn timer_mode(&self) -> Option<LocalApicTimerMode> {
+        if let LVTRegister::Timer = self.register {
+            let mode = (self.data >> 17) & 0b11;
+            match mode {
+                0b00 => {
+                    return Some(LocalApicTimerMode::Oneshot);
+                }
+                0b01 => {
+                    return Some(LocalApicTimerMode::Periodic);
+                }
+                0b10 => {
+                    return Some(LocalApicTimerMode::Deadline);
+                }
+                _ => {
+                    return None;
+                }
+            }
+        }
+        return None;
+    }
+}
+
+/// @brief
+#[allow(dead_code)]
+#[derive(Debug, PartialEq)]
+pub enum DeliveryMode {
+    /// 由LVT寄存器的向量号区域指定中断向量号
+    Fixed = 0b000,
+    /// 通过处理器的SMI信号线,向处理器投递SMI中断请求。
+    /// 由于兼容性的原因,使用此投递模式时,LVT的中断向量号区域必须设置为0。
+    SMI = 0b010,
+    /// 向处理器投递不可屏蔽中断,并忽略向量号区域
+    NMI = 0b100,
+    /// 向处理器投递INIT中断请求,处理器会执行初始化的过程。
+    /// 由于兼容性的原因,使用此投递模式时,LVT的中断向量号区域必须设置为0。
+    /// CMCI、温度传感器、性能监控计数器等寄存器均不支持INIT投递模式
+    INIT = 0b101,
+
+    /// 向目标处理器投递Start-Up IPI。
+    ///
+    /// 这个向量通常由多核引导模块调用(请参阅Intel开发手册Volume3 Section 8.4,
+    /// Multiple-Processor (MP) Initialization)。
+    /// 如果源APIC无法投递这个IPI,它不会自动重发。如果Start-Up IPI未成功投递,
+    /// 则交由软件决定是否在必要时重新投递SIPI
+    StartUp = 0b110,
+
+    /// ExtINT模式可以将类8259A中断控制器产生的中断请求投递到处理器,并接收类
+    /// 8259A中断控制器提供的中断向量号。
+    /// CMCI、温度传感器、性能监控计数器等寄存器均不支持ExtINT投递模式
+    ExtINT = 0b111,
+}
+
+impl TryFrom<u8> for DeliveryMode {
+    type Error = SystemError;
+
+    fn try_from(value: u8) -> Result<Self, Self::Error> {
+        match value {
+            0b000 => {
+                return Ok(DeliveryMode::Fixed);
+            }
+            0b010 => {
+                return Ok(DeliveryMode::SMI);
+            }
+            0b100 => {
+                return Ok(DeliveryMode::NMI);
+            }
+            0b101 => {
+                return Ok(DeliveryMode::INIT);
+            }
+            0b110 => {
+                return Ok(DeliveryMode::StartUp);
+            }
+            0b111 => {
+                return Ok(DeliveryMode::ExtINT);
+            }
+            _ => {
+                return Err(SystemError::EINVAL);
+            }
+        }
+    }
+}
+
+/// @brief 投递状态
+#[derive(Debug)]
+#[allow(dead_code)]
+pub enum DeliveryStatus {
+    /// 空闲态。
+    /// 此状态表明,当前中断源未产生中断,或者产生的中断已经投递到处理器,并被处理器处理。
+    Idle = 0,
+    /// 发送挂起状态。
+    /// 此状态表明,中断源产生的请求已经投递至处理器,但尚未被处理器处理。
+    SendPending = 1,
+}
+
+impl DeliveryStatus {
+    pub fn from(data: u32) -> Self {
+        if data & (1 << 12) == 0 {
+            return DeliveryStatus::Idle;
+        } else {
+            return DeliveryStatus::SendPending;
+        }
+    }
+}
+
+/// IPI Trigger Mode
+#[derive(Debug, Eq, PartialEq)]
+#[repr(u64)]
+pub enum TriggerMode {
+    Edge = 0,
+    Level = 1,
+}
+
+#[derive(Debug)]
+pub struct CurrentApic;
+
+impl CurrentApic {
+    /// x2apic是否启用
+    pub fn x2apic_enabled(&self) -> bool {
+        return LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic;
+    }
+
+    pub(self) unsafe fn write_xapic_register(&self, reg: XApicOffset, value: u32) {
+        current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
+            xapic.write(reg, value);
+        });
+    }
+
+    /// 屏蔽类8259A芯片
+    unsafe fn mask8259a(&self) {
+        CurrentPortIOArch::out8(0x21, 0xff);
+        CurrentPortIOArch::out8(0xa1, 0xff);
+
+        // 写入8259A pic的EOI位
+        CurrentPortIOArch::out8(0x20, 0x20);
+        CurrentPortIOArch::out8(0xa0, 0x20);
+
+        kdebug!("8259A Masked.");
+
+        // enable IMCR
+        CurrentPortIOArch::out8(0x22, 0x70);
+        CurrentPortIOArch::out8(0x23, 0x01);
+    }
+}
+
+impl LocalAPIC for CurrentApic {
+    fn support() -> bool {
+        true
+    }
+
+    fn init_current_cpu(&mut self) -> bool {
+        let cpu_id = smp_get_processor_id();
+        if cpu_id == 0 {
+            unsafe {
+                self.mask8259a();
+            }
+        }
+        kinfo!("Initializing apic for cpu {}", cpu_id);
+        if X2Apic::support() && X2Apic.init_current_cpu() {
+            if cpu_id == 0 {
+                LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::X2Apic, Ordering::SeqCst);
+            }
+            kinfo!("x2APIC initialized for cpu {}", cpu_id);
+        } else {
+            kinfo!("x2APIC not supported or failed to initialize, fallback to xAPIC.");
+            if cpu_id == 0 {
+                LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::XApic, Ordering::SeqCst);
+            }
+            let apic_base =
+                PhysAddr::new(unsafe { x86::msr::rdmsr(IA32_APIC_BASE) as usize & 0xFFFF_0000 });
+            let xapic_instance = unsafe { XApic::new(apic_base) };
+
+            let mut cur = current_xapic_instance().borrow_mut();
+            if cur.is_none() {
+                *cur = Some(xapic_instance);
+            } else {
+                panic!("xapic instance already initialized.");
+            }
+
+            if let Some(xapic) = cur.as_mut() {
+                xapic.init_current_cpu();
+            }
+
+            kinfo!("xAPIC initialized for cpu {}", cpu_id);
+        }
+        if cpu_id == 0 {
+            ioapic_init();
+        }
+        kinfo!("Apic initialized.");
+        return true;
+    }
+
+    fn send_eoi(&self) {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            X2Apic.send_eoi();
+        } else {
+            current_xapic_instance().borrow().as_ref().map(|xapic| {
+                xapic.send_eoi();
+            });
+        }
+    }
+
+    fn version(&self) -> u8 {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            return X2Apic.version();
+        } else {
+            return current_xapic_instance()
+                .borrow()
+                .as_ref()
+                .map(|xapic| xapic.version())
+                .unwrap_or(0);
+        }
+    }
+
+    fn support_eoi_broadcast_suppression(&self) -> bool {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            return X2Apic.support_eoi_broadcast_suppression();
+        } else {
+            return current_xapic_instance()
+                .borrow()
+                .as_ref()
+                .map(|xapic| xapic.support_eoi_broadcast_suppression())
+                .unwrap_or(false);
+        }
+    }
+
+    fn max_lvt_entry(&self) -> u8 {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            return X2Apic.max_lvt_entry();
+        } else {
+            return current_xapic_instance()
+                .borrow()
+                .as_ref()
+                .map(|xapic| xapic.max_lvt_entry())
+                .unwrap_or(0);
+        }
+    }
+
+    fn id(&self) -> u32 {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            return X2Apic.id();
+        } else {
+            return current_xapic_instance()
+                .borrow()
+                .as_ref()
+                .map(|xapic| xapic.id())
+                .unwrap_or(0);
+        }
+    }
+
+    fn set_lvt(&mut self, lvt: LVT) {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            X2Apic.set_lvt(lvt);
+        } else {
+            current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
+                xapic.set_lvt(lvt);
+            });
+        }
+    }
+
+    fn read_lvt(&self, reg: LVTRegister) -> LVT {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            return X2Apic.read_lvt(reg);
+        } else {
+            return current_xapic_instance()
+                .borrow()
+                .as_ref()
+                .map(|xapic| xapic.read_lvt(reg))
+                .expect("xapic instance not initialized.");
+        }
+    }
+
+    fn mask_all_lvt(&mut self) {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            X2Apic.mask_all_lvt();
+        } else {
+            current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
+                xapic.mask_all_lvt();
+            });
+        }
+    }
+
+    fn write_icr(&self, icr: Icr) {
+        if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
+            X2Apic.write_icr(icr);
+        } else {
+            current_xapic_instance().borrow().as_ref().map(|xapic| {
+                xapic.write_icr(icr);
+            });
+        }
+    }
+}

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

@@ -0,0 +1,125 @@
+use x86::msr::{
+    rdmsr, wrmsr, IA32_APIC_BASE, IA32_X2APIC_APICID, IA32_X2APIC_EOI, IA32_X2APIC_SIVR,
+    IA32_X2APIC_VERSION,
+};
+
+use crate::{kdebug, kinfo};
+
+use super::{LVTRegister, LocalAPIC, LVT};
+
+#[derive(Debug)]
+pub struct X2Apic;
+
+impl LocalAPIC for X2Apic {
+    /// @brief 判断处理器是否支持x2APIC
+    fn support() -> bool {
+        return x86::cpuid::CpuId::new()
+            .get_feature_info()
+            .expect("Get cpu feature info failed.")
+            .has_x2apic();
+    }
+    /// @return true -> the function works
+    fn init_current_cpu(&mut self) -> bool {
+        unsafe {
+            // 设置 x2APIC 使能位
+            wrmsr(
+                IA32_APIC_BASE.into(),
+                rdmsr(IA32_APIC_BASE.into()) | 1 << 10,
+            );
+
+            assert!(
+                (rdmsr(IA32_APIC_BASE.into()) & 0xc00) == 0xc00,
+                "x2APIC enable failed."
+            );
+
+            // 设置Spurious-Interrupt Vector Register
+            {
+                let val = if self.support_eoi_broadcast_suppression() {
+                    (1 << 12) | (1 << 8)
+                } else {
+                    1 << 8
+                };
+
+                wrmsr(IA32_X2APIC_SIVR.into(), val);
+
+                assert!(
+                    (rdmsr(IA32_X2APIC_SIVR.into()) & 0x100) == 0x100,
+                    "x2APIC software enable failed."
+                );
+                kinfo!("x2APIC software enabled.");
+
+                if self.support_eoi_broadcast_suppression() {
+                    assert!(
+                        (rdmsr(IA32_X2APIC_SIVR.into()) & 0x1000) == 0x1000,
+                        "x2APIC EOI broadcast suppression enable failed."
+                    );
+                    kinfo!("x2APIC EOI broadcast suppression enabled.");
+                }
+            }
+            kdebug!("x2apic: to mask all lvt");
+            self.mask_all_lvt();
+            kdebug!("x2apic: all lvt masked");
+        }
+        true
+    }
+
+    /// 发送 EOI (End Of Interrupt)
+    fn send_eoi(&self) {
+        unsafe {
+            wrmsr(IA32_X2APIC_EOI.into(), 0);
+        }
+    }
+
+    /// 获取 x2APIC 版本
+    fn version(&self) -> u8 {
+        unsafe { (rdmsr(IA32_X2APIC_VERSION.into()) & 0xff) as u8 }
+    }
+
+    fn support_eoi_broadcast_suppression(&self) -> bool {
+        unsafe { ((rdmsr(IA32_X2APIC_VERSION.into()) >> 24) & 1) == 1 }
+    }
+
+    fn max_lvt_entry(&self) -> u8 {
+        unsafe { ((rdmsr(IA32_X2APIC_VERSION.into()) >> 16) & 0xff) as u8 + 1 }
+    }
+
+    /// 获取 x2APIC 的 APIC ID
+    fn id(&self) -> u32 {
+        unsafe { rdmsr(IA32_X2APIC_APICID.into()) as u32 }
+    }
+
+    /// 设置 Local Vector Table (LVT) 寄存器
+    fn set_lvt(&mut self, lvt: LVT) {
+        unsafe {
+            wrmsr(lvt.register().into(), lvt.data as u64);
+        }
+    }
+
+    fn read_lvt(&self, reg: LVTRegister) -> LVT {
+        unsafe { LVT::new(reg, (rdmsr(reg.into()) & 0xffff_ffff) as u32).unwrap() }
+    }
+
+    fn mask_all_lvt(&mut self) {
+        // self.set_lvt(LVT::new(LVTRegister::CMCI, LVT::MASKED).unwrap());
+        let cpuid = raw_cpuid::CpuId::new();
+        // cpuid.get_performance_monitoring_info();
+        self.set_lvt(LVT::new(LVTRegister::Timer, LVT::MASKED).unwrap());
+
+        if cpuid.get_thermal_power_info().is_some() {
+            self.set_lvt(LVT::new(LVTRegister::Thermal, LVT::MASKED).unwrap());
+        }
+
+        if cpuid.get_performance_monitoring_info().is_some() {
+            self.set_lvt(LVT::new(LVTRegister::PerformanceMonitor, LVT::MASKED).unwrap());
+        }
+
+        self.set_lvt(LVT::new(LVTRegister::LINT0, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::LINT1, LVT::MASKED).unwrap());
+
+        self.set_lvt(LVT::new(LVTRegister::ErrorReg, LVT::MASKED).unwrap());
+    }
+
+    fn write_icr(&self, icr: x86::apic::Icr) {
+        unsafe { wrmsr(0x830, ((icr.upper() as u64) << 32) | icr.lower() as u64) };
+    }
+}

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

@@ -0,0 +1,358 @@
+use core::{
+    cell::RefCell,
+    hint::spin_loop,
+    ptr::{read_volatile, write_volatile},
+};
+
+use crate::{
+    kdebug, kerror, kinfo,
+    mm::{
+        mmio_buddy::{mmio_pool, MMIOSpaceGuard},
+        percpu::PerCpu,
+        PhysAddr, VirtAddr,
+    },
+    smp::core::smp_get_processor_id,
+};
+
+use super::{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];
+
+#[inline(always)]
+pub(super) fn current_xapic_instance() -> &'static RefCell<Option<XApic>> {
+    unsafe { &XAPIC_INSTANCES.as_ref()[smp_get_processor_id() as usize] }
+}
+
+/// TODO:统一变量
+/// @brief local APIC 寄存器地址偏移量
+#[derive(Debug)]
+#[allow(dead_code)]
+#[allow(non_camel_case_types)]
+#[repr(u32)]
+pub enum XApicOffset {
+    // 定义各个寄存器的地址偏移量
+    LOCAL_APIC_OFFSET_Local_APIC_ID = 0x20,
+    LOCAL_APIC_OFFSET_Local_APIC_Version = 0x30,
+    LOCAL_APIC_OFFSET_Local_APIC_TPR = 0x80,
+    LOCAL_APIC_OFFSET_Local_APIC_APR = 0x90,
+    LOCAL_APIC_OFFSET_Local_APIC_PPR = 0xa0,
+    LOCAL_APIC_OFFSET_Local_APIC_EOI = 0xb0,
+    LOCAL_APIC_OFFSET_Local_APIC_RRD = 0xc0,
+    LOCAL_APIC_OFFSET_Local_APIC_LDR = 0xd0,
+    LOCAL_APIC_OFFSET_Local_APIC_DFR = 0xe0,
+    LOCAL_APIC_OFFSET_Local_APIC_SVR = 0xf0,
+
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_31_0 = 0x100, // In-Service Register
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_63_32 = 0x110,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_95_64 = 0x120,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_127_96 = 0x130,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_159_128 = 0x140,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_191_160 = 0x150,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_223_192 = 0x160,
+    LOCAL_APIC_OFFSET_Local_APIC_ISR_255_224 = 0x170,
+
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_31_0 = 0x180, // Trigger Mode Register
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_63_32 = 0x190,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_95_64 = 0x1a0,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_127_96 = 0x1b0,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_159_128 = 0x1c0,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_191_160 = 0x1d0,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_223_192 = 0x1e0,
+    LOCAL_APIC_OFFSET_Local_APIC_TMR_255_224 = 0x1f0,
+
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_31_0 = 0x200, // Interrupt Request Register
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_63_32 = 0x210,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_95_64 = 0x220,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_127_96 = 0x230,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_159_128 = 0x240,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_191_160 = 0x250,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_223_192 = 0x260,
+    LOCAL_APIC_OFFSET_Local_APIC_IRR_255_224 = 0x270,
+
+    LOCAL_APIC_OFFSET_Local_APIC_ESR = 0x280, // Error Status Register
+
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI = 0x2f0, // Corrected Machine Check Interrupt Register
+
+    LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0 = 0x300, // Interrupt Command Register
+    LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32 = 0x310,
+
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER = 0x320,
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL = 0x330,
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR = 0x340,
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0 = 0x350,
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1 = 0x360,
+    LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR = 0x370,
+    // 初始计数寄存器(定时器专用)
+    LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG = 0x380,
+    // 当前计数寄存器(定时器专用)
+    LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG = 0x390,
+    LOCAL_APIC_OFFSET_Local_APIC_CLKDIV = 0x3e0,
+}
+
+impl Into<u32> for XApicOffset {
+    fn into(self) -> u32 {
+        self as u32
+    }
+}
+
+impl From<LVTRegister> for XApicOffset {
+    fn from(lvt: LVTRegister) -> Self {
+        match lvt {
+            LVTRegister::Timer => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER,
+            LVTRegister::Thermal => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL,
+            LVTRegister::PerformanceMonitor => {
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR
+            }
+            LVTRegister::LINT0 => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0,
+            LVTRegister::LINT1 => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1,
+            LVTRegister::ErrorReg => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR,
+            LVTRegister::CMCI => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI,
+        }
+    }
+}
+
+#[derive(Debug)]
+#[allow(dead_code)]
+pub struct XApic {
+    /// 当前xAPIC的寄存器映射的虚拟地址。注意,每个CPU都有自己的xAPIC,所以这个地址是每个CPU都不一样的。
+    apic_vaddr: VirtAddr,
+    /// `apic_vaddr`与映射的空间起始位置之间的偏移量
+    offset: usize,
+    map_guard: MMIOSpaceGuard,
+    xapic_base: PhysAddr,
+}
+
+impl XApic {
+    /// 读取指定寄存器的值
+    #[allow(dead_code)]
+    pub unsafe fn read(&self, reg: XApicOffset) -> u32 {
+        read_volatile((self.apic_vaddr.data() + reg as usize) as *const u32)
+    }
+
+    /// 将指定的值写入寄存器
+    #[allow(dead_code)]
+    pub unsafe fn write(&self, reg: XApicOffset, value: u32) {
+        write_volatile(
+            (self.apic_vaddr.data() + (reg as u32) as usize) as *mut u32,
+            value,
+        );
+        self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID); // 等待写操作完成,通过读取进行同步
+    }
+}
+
+impl XApic {
+    /// 创建新的XAPIC实例
+    ///
+    /// ## 参数
+    ///
+    /// - `xapic_base` - 当前核心的xAPIC的寄存器的物理地址
+    pub unsafe fn new(xapic_base: PhysAddr) -> Self {
+        let offset = xapic_base.data() & 0xffff;
+        let paddr = PhysAddr::new(xapic_base.data() & !0xffff);
+        let g = mmio_pool()
+            .create_mmio(4096)
+            .expect("Fail to create MMIO for XAPIC");
+        g.map_phys(paddr, 4096).expect("Fail to map MMIO for XAPIC");
+        let addr = g.vaddr() + offset;
+
+        kdebug!(
+            "XAPIC: {:#x} -> {:#x}, offset={offset}",
+            xapic_base.data(),
+            addr.data()
+        );
+
+        let r = Self {
+            apic_vaddr: addr,
+            offset,
+            map_guard: g,
+            xapic_base,
+        };
+
+        return r;
+    }
+}
+
+#[allow(dead_code)]
+const X1: u32 = 0x0000000B; // 将除数设置为1,即不除频率
+#[allow(dead_code)]
+const PERIODIC: u32 = 0x00020000; // 周期性模式
+#[allow(dead_code)]
+const ENABLE: u32 = 0x00000100; // 单元使能
+#[allow(dead_code)]
+const MASKED: u32 = 0x00010000; // 中断屏蔽
+const LEVEL: u32 = 0x00008000; // 电平触发
+const BCAST: u32 = 0x00080000; // 发送到所有APIC,包括自己
+const DELIVS: u32 = 0x00001000; // 传递状态
+const INIT: u32 = 0x00000500; // INIT/RESET
+
+//中断请求
+#[allow(dead_code)]
+const T_IRQ0: u32 = 32; // IRQ 0 对应于 T_IRQ 中断
+#[allow(dead_code)]
+const IRQ_TIMER: u32 = 0;
+#[allow(dead_code)]
+const IRQ_KBD: u32 = 1;
+#[allow(dead_code)]
+const IRQ_COM1: u32 = 4;
+#[allow(dead_code)]
+const IRQ_IDE: u32 = 14;
+#[allow(dead_code)]
+const IRQ_ERROR: u32 = 19;
+#[allow(dead_code)]
+const IRQ_SPURIOUS: u32 = 31;
+
+impl LocalAPIC for XApic {
+    /// @brief 判断处理器是否支持apic
+    fn support() -> bool {
+        return x86::cpuid::CpuId::new()
+            .get_feature_info()
+            .expect("Fail to get CPU feature.")
+            .has_apic();
+    }
+
+    /// @return true -> 函数运行成功
+    fn init_current_cpu(&mut self) -> bool {
+        unsafe {
+            // enable xapic
+            x86::msr::wrmsr(x86::msr::APIC_BASE, (self.xapic_base.data() | 0x800) as u64);
+            let val = x86::msr::rdmsr(x86::msr::APIC_BASE);
+            if val & 0x800 != 0x800 {
+                kerror!("xAPIC enable failed: APIC_BASE & 0x800 != 0x800");
+                return false;
+            }
+            // 设置 Spurious Interrupt Vector Register
+            let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into());
+
+            self.write(
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into(),
+                val | ENABLE,
+            );
+
+            let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into());
+            if val & ENABLE == 0 {
+                kerror!("xAPIC software enable failed.");
+
+                return false;
+            } else {
+                kinfo!("xAPIC software enabled.");
+            }
+
+            if val & 0x1000 != 0 {
+                kinfo!("xAPIC EOI broadcast suppression enabled.");
+            }
+
+            self.mask_all_lvt();
+
+            // 清除错误状态寄存器(需要连续写入两次)
+            self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR.into(), 0);
+            self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR.into(), 0);
+
+            // 确认任何未完成的中断
+            self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI.into(), 0);
+
+            // 发送 Init Level De-Assert 信号以同步仲裁ID
+            self.write(
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32.into(),
+                0,
+            );
+            self.write(
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into(),
+                BCAST | INIT | LEVEL,
+            );
+            while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
+            {
+                spin_loop();
+            }
+        }
+
+        true
+    }
+
+    /// 发送 EOI(End Of Interrupt)
+    fn send_eoi(&self) {
+        unsafe {
+            let s = self as *const Self as *mut Self;
+            (*s).write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI.into(), 0);
+        }
+    }
+
+    /// 获取版本号
+    fn version(&self) -> u8 {
+        unsafe {
+            (self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) & 0xff) as u8
+        }
+    }
+
+    fn support_eoi_broadcast_suppression(&self) -> bool {
+        unsafe {
+            ((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) >> 24) & 1) == 1
+        }
+    }
+
+    fn max_lvt_entry(&self) -> u8 {
+        unsafe {
+            ((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) >> 16) & 0xff)
+                as u8
+                + 1
+        }
+    }
+
+    /// 获取ID
+    fn id(&self) -> u32 {
+        unsafe { self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID.into()) >> 24 }
+    }
+
+    /// 设置LVT寄存器的值
+    fn set_lvt(&mut self, lvt: LVT) {
+        unsafe {
+            self.write(lvt.register().into(), lvt.data);
+        }
+    }
+
+    fn read_lvt(&self, reg: LVTRegister) -> LVT {
+        unsafe {
+            LVT::new(
+                reg,
+                self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER.into()),
+            )
+            .unwrap()
+        }
+    }
+
+    fn mask_all_lvt(&mut self) {
+        // self.set_lvt(LVT::new(LVTRegister::CMCI, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::Timer, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::Thermal, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::PerformanceMonitor, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::LINT0, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::LINT1, LVT::MASKED).unwrap());
+        self.set_lvt(LVT::new(LVTRegister::ErrorReg, LVT::MASKED).unwrap());
+    }
+
+    fn write_icr(&self, icr: x86::apic::Icr) {
+        unsafe {
+            // Wait for any previous send to finish
+            while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
+            {
+                spin_loop();
+            }
+
+            self.write(
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32.into(),
+                icr.upper(),
+            );
+            self.write(
+                XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into(),
+                icr.lower(),
+            );
+
+            // Wait for send to finish
+            while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
+            {
+                spin_loop();
+            }
+        }
+    }
+}

+ 1 - 1
kernel/src/arch/x86_64/driver/hpet.c

@@ -1,6 +1,6 @@
 #include <common/glib.h>
 #include <common/kprint.h>
-#include <driver/interrupt/apic/apic.h>
+#include <arch/x86_64/driver/apic/apic.h>
 
 extern void rs_handle_hpet_irq(uint32_t timer_num);
 

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

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

+ 15 - 0
kernel/src/arch/x86_64/interrupt/c_adapter.rs

@@ -0,0 +1,15 @@
+use super::ipi::{ipi_send_smp_init, ipi_send_smp_startup};
+
+#[no_mangle]
+unsafe extern "C" fn rs_ipi_send_smp_init() -> i32 {
+    return ipi_send_smp_init()
+        .map(|_| 0)
+        .unwrap_or_else(|e| e.to_posix_errno());
+}
+
+#[no_mangle]
+unsafe extern "C" fn rs_ipi_send_smp_startup(target_cpu: u32) -> i32 {
+    return ipi_send_smp_startup(target_cpu)
+        .map(|_| 0)
+        .unwrap_or_else(|e| e.to_posix_errno());
+}

+ 111 - 34
kernel/src/arch/x86_64/interrupt/ipi.rs

@@ -1,9 +1,13 @@
-use crate::exception::ipi::{IpiKind, IpiTarget};
+use x86::apic::ApicId;
 
-extern "C" {
-    pub fn apic_write_icr(value: u64);
-    pub fn apic_x2apic_enabled() -> bool;
-}
+use crate::{
+    arch::{
+        driver::apic::{CurrentApic, LocalAPIC},
+        smp::SMP_BOOT_DATA,
+    },
+    exception::ipi::{IpiKind, IpiTarget},
+    syscall::SystemError,
+};
 
 /// IPI的种类(架构相关,指定了向量号)
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
@@ -32,7 +36,7 @@ pub enum ArchIpiTarget {
     /// 除了当前CPU以外的所有CPU
     Other,
     /// 指定的CPU
-    Specified(usize),
+    Specified(x86::apic::ApicId),
 }
 
 impl From<IpiTarget> for ArchIpiTarget {
@@ -41,7 +45,23 @@ impl From<IpiTarget> for ArchIpiTarget {
             IpiTarget::Current => ArchIpiTarget::Current,
             IpiTarget::All => ArchIpiTarget::All,
             IpiTarget::Other => ArchIpiTarget::Other,
-            IpiTarget::Specified(cpu_id) => ArchIpiTarget::Specified(cpu_id),
+            IpiTarget::Specified(cpu_id) => {
+                ArchIpiTarget::Specified(Self::cpu_id_to_apic_id(cpu_id as u32))
+            }
+        }
+    }
+}
+
+impl Into<ApicId> for ArchIpiTarget {
+    fn into(self) -> ApicId {
+        if let ArchIpiTarget::Specified(id) = self {
+            return id;
+        } else {
+            if CurrentApic.x2apic_enabled() {
+                return x86::apic::ApicId::X2Apic(0);
+            } else {
+                return x86::apic::ApicId::XApic(0);
+            }
         }
     }
 }
@@ -55,6 +75,15 @@ impl ArchIpiTarget {
             ArchIpiTarget::Other => 3,
         }
     }
+
+    #[inline(always)]
+    fn cpu_id_to_apic_id(cpu_id: u32) -> x86::apic::ApicId {
+        if CurrentApic.x2apic_enabled() {
+            x86::apic::ApicId::X2Apic(cpu_id as u32)
+        } else {
+            x86::apic::ApicId::XApic(cpu_id as u8)
+        }
+    }
 }
 
 impl Into<x86::apic::DestinationShorthand> for ArchIpiTarget {
@@ -68,21 +97,6 @@ impl Into<x86::apic::DestinationShorthand> for ArchIpiTarget {
     }
 }
 
-impl Into<x86::apic::ApicId> for ArchIpiTarget {
-    fn into(self) -> x86::apic::ApicId {
-        let id = match self {
-            ArchIpiTarget::Specified(cpu_id) => cpu_id,
-            _ => 0,
-        };
-
-        if unsafe { apic_x2apic_enabled() } {
-            return x86::apic::ApicId::X2Apic(id as u32);
-        } else {
-            return x86::apic::ApicId::XApic(id as u8);
-        }
-    }
-}
-
 #[inline(always)]
 pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
     // kdebug!("send_ipi: {:?} {:?}", kind, target);
@@ -91,9 +105,9 @@ pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
     let target = ArchIpiTarget::from(target);
     let shorthand: x86::apic::DestinationShorthand = target.into();
     let destination: x86::apic::ApicId = target.into();
-    if unsafe { apic_x2apic_enabled() } {
+    let icr = if CurrentApic.x2apic_enabled() {
         // kdebug!("send_ipi: x2apic");
-        let icr = x86::apic::Icr::for_x2apic(
+        x86::apic::Icr::for_x2apic(
             ipi_vec,
             destination,
             shorthand,
@@ -102,14 +116,10 @@ pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
             x86::apic::DeliveryStatus::Idle,
             x86::apic::Level::Assert,
             x86::apic::TriggerMode::Edge,
-        );
-
-        unsafe {
-            apic_write_icr(((icr.upper() as u64) << 32) | icr.lower() as u64);
-        }
+        )
     } else {
         // kdebug!("send_ipi: xapic");
-        let icr = x86::apic::Icr::for_xapic(
+        x86::apic::Icr::for_xapic(
             ipi_vec,
             destination,
             shorthand,
@@ -118,10 +128,77 @@ pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
             x86::apic::DeliveryStatus::Idle,
             x86::apic::Level::Assert,
             x86::apic::TriggerMode::Edge,
-        );
+        )
+    };
 
-        unsafe {
-            apic_write_icr(((icr.upper() as u64) << 32) | icr.lower() as u64);
-        }
+    CurrentApic.write_icr(icr);
+}
+
+/// 发送smp初始化IPI
+pub fn ipi_send_smp_init() -> Result<(), SystemError> {
+    let target = ArchIpiTarget::Other;
+    let icr = if CurrentApic.x2apic_enabled() {
+        x86::apic::Icr::for_x2apic(
+            0,
+            target.into(),
+            x86::apic::DestinationShorthand::AllExcludingSelf,
+            x86::apic::DeliveryMode::Init,
+            x86::apic::DestinationMode::Physical,
+            x86::apic::DeliveryStatus::Idle,
+            x86::apic::Level::Deassert,
+            x86::apic::TriggerMode::Edge,
+        )
+    } else {
+        x86::apic::Icr::for_xapic(
+            0,
+            target.into(),
+            x86::apic::DestinationShorthand::AllExcludingSelf,
+            x86::apic::DeliveryMode::Init,
+            x86::apic::DestinationMode::Physical,
+            x86::apic::DeliveryStatus::Idle,
+            x86::apic::Level::Deassert,
+            x86::apic::TriggerMode::Edge,
+        )
+    };
+    CurrentApic.write_icr(icr);
+    return Ok(());
+}
+
+/// 发送smp启动IPI
+///
+/// ## 参数
+///
+/// * `target_cpu` - 目标CPU
+pub fn ipi_send_smp_startup(target_cpu: u32) -> Result<(), SystemError> {
+    if target_cpu as usize >= SMP_BOOT_DATA.cpu_count() {
+        return Err(SystemError::EINVAL);
     }
+    let target: ArchIpiTarget = IpiTarget::Specified(target_cpu as usize).into();
+
+    let icr = if CurrentApic.x2apic_enabled() {
+        x86::apic::Icr::for_x2apic(
+            0x20,
+            target.into(),
+            x86::apic::DestinationShorthand::NoShorthand,
+            x86::apic::DeliveryMode::StartUp,
+            x86::apic::DestinationMode::Physical,
+            x86::apic::DeliveryStatus::Idle,
+            x86::apic::Level::Deassert,
+            x86::apic::TriggerMode::Edge,
+        )
+    } else {
+        x86::apic::Icr::for_xapic(
+            0x20,
+            target.into(),
+            x86::apic::DestinationShorthand::NoShorthand,
+            x86::apic::DeliveryMode::StartUp,
+            x86::apic::DestinationMode::Physical,
+            x86::apic::DeliveryStatus::Idle,
+            x86::apic::Level::Deassert,
+            x86::apic::TriggerMode::Edge,
+        )
+    };
+
+    CurrentApic.write_icr(icr);
+    return Ok(());
 }

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

@@ -1,5 +1,6 @@
 #![allow(dead_code)]
 
+mod c_adapter;
 pub mod ipi;
 
 use core::{

+ 36 - 21
kernel/src/arch/x86_64/ipc/signal.rs

@@ -1,4 +1,4 @@
-use core::{ffi::c_void, mem::size_of};
+use core::{ffi::c_void, intrinsics::unlikely, mem::size_of};
 
 use crate::{
     arch::{
@@ -322,7 +322,7 @@ impl SigContext {
         //TODO 引入线程后补上
         // let current_thread = ProcessManager::current_pcb().thread;
         let pcb = ProcessManager::current_pcb();
-        let mut archinfo_guard = pcb.arch_info();
+        let mut archinfo_guard = pcb.arch_info_irqsave();
         self.oldmask = *mask;
         self.frame = frame.clone();
         // context.trap_num = unsafe { (*current_thread).trap_num };
@@ -368,6 +368,7 @@ pub struct SigStack {
 #[no_mangle]
 unsafe extern "C" fn do_signal(frame: &mut TrapFrame) {
     X86_64SignalArch::do_signal(frame);
+    return;
 }
 
 pub struct X86_64SignalArch;
@@ -377,35 +378,46 @@ impl SignalArch for X86_64SignalArch {
         let pcb = ProcessManager::current_pcb();
         let siginfo = pcb.try_siginfo(5);
 
+        if unlikely(siginfo.is_none()) {
+            return;
+        }
+
+        let siginfo_read_guard = siginfo.unwrap();
+
         // 检查sigpending是否为0
-        if siginfo
-            .map(|s| s.sig_pending().signal().bits() == 0)
-            .unwrap_or(true)
-            || !frame.from_user()
-        {
-            // 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回
-            CurrentIrqArch::interrupt_enable();
+        if siginfo_read_guard.sig_pending().signal().bits() == 0 || !frame.from_user() {
+            // 若没有正在等待处理的信号,或者将要返回到的是内核态,则返回
             return;
         }
 
-        // 做完上面的检查后,开中断
-        CurrentIrqArch::interrupt_enable();
         let pcb = ProcessManager::current_pcb();
-        let sig_guard = pcb.sig_struct();
+
         let mut sig_number: Signal;
         let mut info: Option<SigInfo>;
         let mut sigaction: Sigaction;
-        let reader = pcb.sig_info();
-        let sig_block: SigSet = reader.sig_block().clone();
-        drop(reader);
+        let sig_block: SigSet = siginfo_read_guard.sig_block().clone();
+        drop(siginfo_read_guard);
+
+        let sig_guard = pcb.try_sig_struct_irq(5);
+        if unlikely(sig_guard.is_none()) {
+            return;
+        }
+        let siginfo_mut = pcb.try_siginfo_mut(5);
+        if unlikely(siginfo_mut.is_none()) {
+            return;
+        }
+
+        let sig_guard = sig_guard.unwrap();
+        let mut siginfo_mut_guard = siginfo_mut.unwrap();
         loop {
-            (sig_number, info) = pcb.sig_info_mut().dequeue_signal(&sig_block);
+            (sig_number, info) = siginfo_mut_guard.dequeue_signal(&sig_block);
             // 如果信号非法,则直接返回
             if sig_number == Signal::INVALID {
                 return;
             }
 
             sigaction = sig_guard.handlers[sig_number as usize - 1];
+
             match sigaction.action() {
                 SigactionType::SaHandler(action_type) => match action_type {
                     SaHandlerType::SigError => {
@@ -425,12 +437,14 @@ impl SignalArch for X86_64SignalArch {
             }
             // 如果当前动作是忽略这个信号,就继续循环。
         }
-        // 所有的信号都处理完了
-        let reader = pcb.sig_info();
-        let oldset = reader.sig_block().clone();
+
+        let oldset = siginfo_mut_guard.sig_block().clone();
         //避免死锁
-        drop(reader);
+        drop(siginfo_mut_guard);
         drop(sig_guard);
+
+        // 做完上面的检查后,开中断
+        CurrentIrqArch::interrupt_enable();
         let res: Result<i32, SystemError> =
             handle_signal(sig_number, &mut sigaction, &info.unwrap(), &oldset, frame);
         if res.is_err() {
@@ -564,7 +578,8 @@ fn setup_frame(
     let frame: *mut SigFrame = get_stack(&trap_frame, size_of::<SigFrame>());
     // kdebug!("frame=0x{:016x}", frame as usize);
     // 要求这个frame的地址位于用户空间,因此进行校验
-    let r = UserBufferWriter::new(frame, size_of::<SigFrame>(), true);
+    let r: Result<UserBufferWriter<'_>, SystemError> =
+        UserBufferWriter::new(frame, size_of::<SigFrame>(), true);
     if r.is_err() {
         // 如果地址区域位于内核空间,则直接报错
         // todo: 生成一个sigsegv

+ 2 - 36
kernel/src/arch/x86_64/x86_64_ipi.c

@@ -1,39 +1,5 @@
 #include "x86_64_ipi.h"
-#include <driver/interrupt/apic/apic.h>
-
-void ipi_send_IPI(uint32_t dest_mode, uint32_t deliver_status, uint32_t level, uint32_t trigger,
-                  uint32_t vector, uint32_t deliver_mode, uint32_t dest_shorthand, uint32_t destination)
-{
-    struct INT_CMD_REG icr_entry;
-    icr_entry.dest_mode = dest_mode;
-    icr_entry.deliver_status = deliver_status;
-    icr_entry.res_1 = 0;
-    icr_entry.level = level;
-    icr_entry.trigger = trigger;
-    icr_entry.res_2 = 0;
-    icr_entry.res_3 = 0;
-
-    icr_entry.vector = vector;
-    icr_entry.deliver_mode = deliver_mode;
-    icr_entry.dest_shorthand = dest_shorthand;
-
-    // x2APIC下,ICR寄存器地址为0x830
-    // xAPIC下则为0xfee00300(31-0) 0xfee00310 (63-32)
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED) // x2APIC
-    {
-        icr_entry.destination.x2apic_destination = destination;
-        wrmsr(0x830, *(unsigned long *)&icr_entry); // 发送ipi
-    }
-    else // xAPIC
-    {
-
-        icr_entry.destination.apic_destination.dest_field = destination & 0xff;
-        icr_entry.destination.apic_destination.res_4 = 0;
-        // 先向高32bit写数据,然后再向低32bit写数据,不能调转
-        *(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + 0x310) = (uint32_t)(((*(ul *)&icr_entry) >> 32) & 0xffffffff);
-        *(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + 0x300) = (uint32_t)((*(ul *)&icr_entry) & 0xffffffff);
-    }
-}
+#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),
@@ -46,4 +12,4 @@ int ipi_regiserIPI(uint64_t irq_num, void *arg,
     p->flags = 0;
     p->handler = handler;
     return 0;
-}
+} 

+ 1 - 16
kernel/src/arch/x86_64/x86_64_ipi.h

@@ -12,22 +12,7 @@
 #pragma once
 
 #include <common/kprint.h>
-#include <driver/interrupt/apic/apic.h>
-
-/**
- * @brief 发送ipi消息
- *
- * @param dest_mode 目标模式
- * @param deliver_status 投递模式
- * @param level 信号驱动电平
- * @param trigger 触发模式
- * @param vector 中断向量
- * @param deliver_mode 投递模式
- * @param dest_shorthand 投递目标速记值
- * @param destination 投递目标
- */
-void ipi_send_IPI(uint32_t dest_mode, uint32_t deliver_status, uint32_t level, uint32_t trigger,
-                  uint32_t vector, uint32_t deliver_mode, uint32_t dest_shorthand,  uint32_t destination);
+#include <arch/x86_64/driver/apic/apic.h>
 
 /**
  * @brief ipi中断处理注册函数

+ 1 - 1
kernel/src/common/Makefile

@@ -8,7 +8,7 @@ ECHO:
 
 $(kernel_common_subdirs): ECHO
 
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 all:  $(kernel_common_subdirs)
 

+ 2 - 2
kernel/src/driver/Makefile

@@ -1,14 +1,14 @@
 
 CFLAGS += -I .
 
-kernel_driver_subdirs:=interrupt pci acpi disk keyboard mouse multiboot2 timers hid 
+kernel_driver_subdirs:=pci acpi disk keyboard mouse multiboot2 timers hid 
 
 ECHO:
 	@echo "$@"
 
 $(kernel_driver_subdirs): ECHO
 
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 all: $(kernel_driver_subdirs)
 

+ 1 - 1
kernel/src/driver/hid/Makefile

@@ -9,7 +9,7 @@ ECHO:
 	@echo "$@"
 
 $(kernel_driver_hid_subdirs): ECHO
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 $(kernel_driver_hid_objs): ECHO
 	$(CC) $(CFLAGS) -c $@ -o [email protected]

+ 0 - 66
kernel/src/driver/interrupt/8259A/8259A.c

@@ -1,66 +0,0 @@
-#include "8259A.h"
-#include <common/printk.h>
-#include <common/kprint.h>
-#include <exception/gate.h>
-
-// 导出定义在irq.c中的中段门表
-extern void (*interrupt_table[24])(void);
-
-void init_8259A()
-{
-    // 初始化中断门, 中断使用第0个ist
-    for(int i=32;i<=55;++i)
-        set_intr_gate(i, 0, interrupt_table[i-32]);
-    kinfo("Initializing 8259A...");
-    
-    // 初始化主芯片
-    io_out8(0x20, 0x11);    // 初始化主芯片的icw1
-    io_out8(0x21, 0x20);    // 设置主芯片的中断向量号为0x20(0x20-0x27)
-    io_out8(0x21, 0x04);    // 设置int2端口级联从芯片
-    io_out8(0x21, 0x01);    // 设置为AEOI模式、FNM、无缓冲
-
-    // 初始化从芯片
-    io_out8(0xa0, 0x11);
-    io_out8(0xa1, 0x28);    // 设置从芯片的中断向量号为0x28(0x28-0x2f)
-    io_out8(0xa1, 0x02);    // 设置从芯片连接到主芯片的int2
-    io_out8(0xa1, 0x01);
-
-
-    // 设置ocw1, 允许所有中断请求
-    io_out8(0x21, 0x00);
-    io_out8(0xa1, 0x00);
-
-    sti();
-
-    kinfo("IRQ circuit 8259A initialized.");
-
-}
-
-/**
- * @brief 中断服务程序
- * 
- * @param rsp 中断栈指针
- * @param number 中断号
- */
-void do_IRQ(struct pt_regs *regs, ul number)
-{
-    unsigned char x;
-    switch (number)
-    {
-    case 0x20:  // 时钟中断信号
-        
-        break;
-    case 0x21:  // 键盘中断
-        
-        x = io_in8(0x60);
-        printk_color(ORANGE, BLACK, "Received key irq, key code:%#018lx\n", x);
-        break;
-    default:
-        break;
-    }
-    if(number!=0x20)
-    printk_color(ORANGE, BLACK, "Received irq:%#018x\n", number);
-
-    // 向主芯片发送中断结束信号
-    io_out8(PIC_master, PIC_EOI);
-}

+ 0 - 33
kernel/src/driver/interrupt/8259A/8259A.h

@@ -1,33 +0,0 @@
-/**
- * @file 8259A.h
- * @author longjin
- * @brief 8259A中断芯片
- * @version 0.1
- * @date 2022-01-29
- * 
- * @copyright Copyright (c) 2022
- * 
- */
-
-#pragma once
-
-#include <common/glib.h>
-#include <exception/irq.h>
-
-#define PIC_EOI		0x20
-#define PIC_master		0x20		/* IO base address for master PIC */
-#define PIC2_slave		0xA0		/* IO base address for slave PIC */
-
-// 初始化8259A芯片的中断服务
-void init_8259A();
-
-/**
- * @brief 中断服务程序
- * 
- * @param rsp 中断栈指针
- * @param number 中断号
- */
-void do_IRQ(struct pt_regs* rsp, ul number);
-
-
-

+ 0 - 14
kernel/src/driver/interrupt/Makefile

@@ -1,14 +0,0 @@
-
-all: pic.o
-
-# 中断处理芯片的驱动程序
-ifeq ($(PIC), _INTR_8259A_)
-pic.o: 8259A/8259A.c
-	$(CC) $(CFLAGS) -c 8259A/8259A.c -o pic.o
-else
-pic.o: apic/apic.c apic_timer.o
-	$(CC) $(CFLAGS) -c apic/apic.c -o pic.o
-
-apic_timer.o: apic/apic_timer.c
-	$(CC) $(CFLAGS) -c apic/apic_timer.c -o apic/apic_timer.o
-endif

+ 0 - 741
kernel/src/driver/interrupt/apic/apic.c

@@ -1,741 +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/gate.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();
-
-static bool flag_support_apic = false;
-static bool flag_support_x2apic = false;
-uint8_t __apic_enable_state = APIC_XAPIC_ENABLED;
-static uint local_apic_version;
-static uint local_apic_max_LVT_entries;
-
-static struct acpi_Multiple_APIC_Description_Table_t *madt;
-static struct acpi_IO_APIC_Structure_t *io_apic_ICS;
-
-static void __local_apic_xapic_init();
-static void __local_apic_x2apic_init();
-
-static __always_inline void __send_eoi()
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-    {
-        __asm__ __volatile__("movq	$0x00,	%%rdx	\n\t"
-                             "movq	$0x00,	%%rax	\n\t"
-                             "movq 	$0x80b,	%%rcx	\n\t"
-                             "wrmsr	\n\t" ::
-                                 : "memory");
-    }
-    else
-    {
-
-        io_mfence();
-        __write4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_EOI, 0);
-        io_mfence();
-    }
-}
-
-/**
- * @brief 初始化io_apic
- *
- */
-void apic_io_apic_init()
-{
-
-    ul madt_addr;
-    acpi_iter_SDT(acpi_get_MADT, &madt_addr);
-    madt = (struct acpi_Multiple_APIC_Description_Table_t *)madt_addr;
-
-    // kdebug("MADT->local intr controller addr=%#018lx", madt->Local_Interrupt_Controller_Address);
-    // kdebug("MADT->length= %d bytes", madt->header.Length);
-    //  寻找io apic的ICS
-    void *ent = (void *)(madt_addr) + sizeof(struct acpi_Multiple_APIC_Description_Table_t);
-    struct apic_Interrupt_Controller_Structure_header_t *header =
-        (struct apic_Interrupt_Controller_Structure_header_t *)ent;
-    while (header->length > 2)
-    {
-        header = (struct apic_Interrupt_Controller_Structure_header_t *)ent;
-        if (header->type == 1)
-        {
-            struct acpi_IO_APIC_Structure_t *t = (struct acpi_IO_APIC_Structure_t *)ent;
-            // kdebug("IO apic addr = %#018lx", t->IO_APIC_Address);
-            io_apic_ICS = t;
-            break;
-        }
-
-        ent += header->length;
-    }
-    // kdebug("Global_System_Interrupt_Base=%d", io_apic_ICS->Global_System_Interrupt_Base);
-
-    apic_ioapic_map.addr_phys = io_apic_ICS->IO_APIC_Address;
-    apic_ioapic_map.virtual_index_addr = (unsigned char *)APIC_IO_APIC_VIRT_BASE_ADDR;
-    apic_ioapic_map.virtual_data_addr = (uint *)(APIC_IO_APIC_VIRT_BASE_ADDR + 0x10);
-    apic_ioapic_map.virtual_EOI_addr = (uint *)(APIC_IO_APIC_VIRT_BASE_ADDR + 0x40);
-
-    // kdebug("(ul)apic_ioapic_map.virtual_index_addr=%#018lx", (ul)apic_ioapic_map.virtual_index_addr);
-    // 填写页表,完成地址映射
-    rs_map_phys((ul)apic_ioapic_map.virtual_index_addr, apic_ioapic_map.addr_phys, PAGE_2M_SIZE,
-                PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
-
-    // 设置IO APIC ID 为0x0f000000
-    *apic_ioapic_map.virtual_index_addr = 0x00;
-    io_mfence();
-    *apic_ioapic_map.virtual_data_addr = 0x0f000000;
-    io_mfence();
-
-    // kdebug("I/O APIC ID:%#010x", ((*apic_ioapic_map.virtual_data_addr) >> 24) & 0xff);
-    io_mfence();
-
-    // 获取IO APIC Version
-    *apic_ioapic_map.virtual_index_addr = 0x01;
-    io_mfence();
-    kdebug("IO APIC Version=%d, Max Redirection Entries=%d", *apic_ioapic_map.virtual_data_addr & 0xff,
-           (((*apic_ioapic_map.virtual_data_addr) >> 16) & 0xff) + 1);
-
-    // 初始化RTE表项,将所有RTE表项屏蔽
-    for (int i = 0x10; i < 0x40; i += 2)
-    {
-        // 以0x20为起始中断向量号,初始化RTE
-        apic_ioapic_write_rte(i, 0x10020 + ((i - 0x10) >> 1));
-    }
-
-    // 不需要手动启动IO APIC,只要初始化了RTE寄存器之后,io apic就会自动启用了。
-    // 而且不是每台电脑都有RCBA寄存器,因此不需要手动启用IO APIC
-}
-
-/**
- * @brief 初始化AP处理器的Local apic
- *
- */
-void apic_init_ap_core_local_apic()
-{
-    kinfo("Initializing AP-core's local apic...");
-    uint eax, edx;
-    // 启用xAPIC 和x2APIC
-    uint64_t ia32_apic_base = rdmsr(0x1b);
-    ia32_apic_base |= (1 << 11);
-    if (flag_support_x2apic) // 如果支持x2apic,则启用
-    {
-        ia32_apic_base |= (1 << 10);
-        wrmsr(0x1b, ia32_apic_base);
-    }
-    ia32_apic_base = rdmsr(0x1b);
-    eax = ia32_apic_base & 0xffffffff;
-
-    // 检测是否成功启用xAPIC和x2APIC
-    if ((eax & 0xc00) == 0xc00)
-        kinfo("xAPIC & x2APIC enabled!");
-    else if ((eax & 0x800) == 0x800)
-        kinfo("Only xAPIC enabled!");
-    else
-        kerror("Both xAPIC and x2APIC are not enabled.");
-
-    // 设置SVR寄存器,开启local APIC、禁止EOI广播
-    if (flag_support_x2apic) // 当前为x2APIC
-        __local_apic_x2apic_init();
-    else // 当前为xapic
-        __local_apic_xapic_init();
-    barrier();
-    kdebug("AP-core's local apic initialized.");
-    barrier();
-}
-
-/**
- * @brief 当前使用xapic来初始化local apic
- *
- */
-static void __local_apic_xapic_init()
-{
-    __apic_enable_state = APIC_XAPIC_ENABLED;
-    // 设置svr的 apic软件使能位
-    uint64_t qword = *(uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
-
-    qword |= (1 << 8);
-    *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR) = qword;
-    qword = *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_SVR);
-    if (qword & 0x100)
-        kinfo("APIC Software Enabled.");
-    if (qword & 0x1000)
-        kinfo("EOI-Broadcast Suppression Enabled.");
-    barrier();
-    // 从  Local APIC Version register 获取Local APIC Version
-    qword = *(volatile uint64_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_Version);
-    qword &= 0xffffffff;
-
-    local_apic_max_LVT_entries = ((qword >> 16) & 0xff) + 1;
-    local_apic_version = qword & 0xff;
-
-    kdebug("local APIC Version:%#010x,Max LVT Entry:%#010x,SVR(Suppress EOI Broadcast):%#04x\t", local_apic_version,
-           local_apic_max_LVT_entries, (qword >> 24) & 0x1);
-
-    if ((qword & 0xff) < 0x10)
-    {
-        kdebug("82489DX discrete APIC");
-    }
-    else if (((qword & 0xff) >= 0x10) && ((qword & 0xff) <= 0x15))
-        kdebug("Integrated APIC.");
-
-    io_mfence();
-    // 如果写入这里的话,在有的机器上面会报错
-    // *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI) = APIC_LVT_INT_MASKED;
-    io_mfence();
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER) = APIC_LVT_INT_MASKED;
-    io_mfence();
-
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL) = APIC_LVT_INT_MASKED;
-    io_mfence();
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR) =
-        APIC_LVT_INT_MASKED;
-    io_mfence();
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0) = APIC_LVT_INT_MASKED;
-    io_mfence();
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1) = APIC_LVT_INT_MASKED;
-    io_mfence();
-    *(volatile uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR) = APIC_LVT_INT_MASKED;
-    io_mfence();
-
-    kdebug("All LVT Masked");
-}
-
-/**
- * @brief 当前使用x2apic来初始化local apic
- *
- */
-static void __local_apic_x2apic_init()
-{
-    __apic_enable_state = APIC_X2APIC_ENABLED;
-    uint32_t eax, edx;
-    __asm__ __volatile__("movq $0x80f, %%rcx    \n\t"
-                         "rdmsr  \n\t"
-                         "bts $8, %%rax  \n\t"
-                         //                         "bts $12, %%rax \n\t"
-                         "movq $0x80f, %%rcx    \n\t"
-                         "wrmsr  \n\t"
-                         "movq $0x80f , %%rcx   \n\t"
-                         "rdmsr \n\t"
-                         : "=a"(eax), "=d"(edx)::"memory");
-    if (eax & 0x100)
-        kinfo("APIC Software Enabled.");
-    if (eax & 0x1000)
-        kinfo("EOI-Broadcast Suppression Enabled.");
-
-    // 获取Local APIC Version
-    // 0x803处是 Local APIC Version register
-    __asm__ __volatile__("movq $0x803, %%rcx    \n\t"
-                         "rdmsr  \n\t"
-                         : "=a"(eax), "=d"(edx)::"memory");
-
-    local_apic_max_LVT_entries = ((eax >> 16) & 0xff) + 1;
-    local_apic_version = eax & 0xff;
-
-    kdebug("local APIC Version:%#010x,Max LVT Entry:%#010x,SVR(Suppress EOI Broadcast):%#04x\t", local_apic_version,
-           local_apic_max_LVT_entries, (eax >> 24) & 0x1);
-
-    if ((eax & 0xff) < 0x10)
-        kdebug("82489DX discrete APIC");
-    else if (((eax & 0xff) >= 0x10) && ((eax & 0xff) <= 0x15))
-        kdebug("Integrated APIC.");
-
-    // 由于尚未配置LVT对应的处理程序,因此先屏蔽所有的LVT
-    __asm__ __volatile__(             // "movq 	$0x82f,	%%rcx	\n\t" // CMCI
-                                      // "wrmsr	\n\t"
-        "movq 	$0x832,	%%rcx	\n\t" // Timer
-        "wrmsr	\n\t"
-        "movq 	$0x833,	%%rcx	\n\t" // Thermal Monitor
-        "wrmsr	\n\t"
-        "movq 	$0x834,	%%rcx	\n\t" // Performance Counter
-        "wrmsr	\n\t"
-        "movq 	$0x835,	%%rcx	\n\t" // LINT0
-        "wrmsr	\n\t"
-        "movq 	$0x836,	%%rcx	\n\t" // LINT1
-        "wrmsr	\n\t"
-        "movq 	$0x837,	%%rcx	\n\t" // Error
-        "wrmsr	\n\t"
-        :
-        : "a"(0x10000), "d"(0x00)
-        : "memory");
-    kdebug("All LVT Masked");
-}
-
-/**
- * @brief 初始化local apic
- *
- */
-void apic_local_apic_init()
-{
-    uint64_t ia32_apic_base = rdmsr(0x1b);
-    // kdebug("apic base=%#018lx", (ia32_apic_base & 0x1FFFFFFFFFF000));
-    // 映射Local APIC 寄存器地址
-    // todo:
-    rs_map_phys(APIC_LOCAL_APIC_VIRT_BASE_ADDR, (ia32_apic_base & 0x1FFFFFFFFFF000), PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
-    uint a, b, c, d;
-
-    cpu_cpuid(1, 0, &a, &b, &c, &d);
-
-    // kdebug("CPUID 0x01, eax:%#010lx, ebx:%#010lx, ecx:%#010lx, edx:%#010lx", a, b, c, d);
-
-    // 判断是否支持APIC和xAPIC
-    if ((1 << 9) & d)
-    {
-        flag_support_apic = true;
-        kdebug("This computer support APIC&xAPIC");
-    }
-    else
-    {
-        flag_support_apic = false;
-        kerror("This computer does not support APIC&xAPIC");
-        while (1)
-            ;
-    }
-
-    // 判断是否支持x2APIC
-    if ((1 << 21) & c)
-    {
-        flag_support_x2apic = true;
-        kdebug("This computer support x2APIC");
-    }
-    else
-    {
-        flag_support_x2apic = false;
-        kwarn("This computer does not support x2APIC");
-    }
-
-    uint eax, edx;
-    // 启用xAPIC 和x2APIC
-    ia32_apic_base = rdmsr(0x1b);
-    ia32_apic_base |= (1 << 11);
-    if (flag_support_x2apic) // 如果支持x2apic,则启用
-    {
-        ia32_apic_base |= (1 << 10);
-        wrmsr(0x1b, ia32_apic_base);
-    }
-    ia32_apic_base = rdmsr(0x1b);
-    eax = ia32_apic_base & 0xffffffff;
-
-    // 检测是否成功启用xAPIC和x2APIC
-    if ((eax & 0xc00) == 0xc00)
-        kinfo("xAPIC & x2APIC enabled!\n");
-    else if ((eax & 0x800) == 0x800)
-        kinfo("Only xAPIC enabled!");
-    else
-        kerror("Both xAPIC and x2APIC are not enabled.");
-
-    // 设置SVR寄存器,开启local APIC、禁止EOI广播
-    if (flag_support_x2apic) // 当前为x2APIC
-        __local_apic_x2apic_init();
-    else // 当前为xapic
-        __local_apic_xapic_init();
-
-    // 获取Local APIC的基础信息 (参见英特尔开发手册Vol3A 10-39)
-    //                          Table 10-6. Local APIC Register Address Map Supported by x2APIC
-    // 获取 Local APIC ID
-    // 0x802处是x2APIC ID 位宽32bits 的 Local APIC ID register
-    /*
-    __asm__ __volatile__("movq $0x802, %%rcx    \n\t"
-                         "rdmsr  \n\t"
-                         : "=a"(eax), "=d"(edx)::"memory");
-    */
-    // kdebug("get Local APIC ID: edx=%#010x, eax=%#010x", edx, eax);
-    // kdebug("local_apic_id=%#018lx", *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ID));
-}
-
-/**
- * @brief 初始化apic控制器
- *
- */
-int apic_init()
-{
-    cli();
-    kinfo("Initializing APIC...");
-    // 初始化中断门, 中断使用rsp0防止在软中断时发生嵌套,然后处理器重新加载导致数据被抹掉
-    for (int i = 32; i <= 57; ++i)
-        set_intr_gate(i, 0, interrupt_table[i - 32]);
-
-    // 设置local apic中断门
-    for (int i = 150; i < 160; ++i)
-        set_intr_gate(i, 0, local_apic_interrupt_table[i - 150]);
-
-    //  屏蔽类8259A芯片
-    io_out8(0x21, 0xff);
-
-    io_out8(0xa1, 0xff);
-
-    // 写入8259A pic的EOI位
-    io_out8(0x20, 0x20);
-    io_out8(0xa0, 0x20);
-
-    kdebug("8259A Masked.");
-
-    // enable IMCR
-    io_out8(0x22, 0x70);
-    io_out8(0x23, 0x01);
-
-    apic_local_apic_init();
-
-    apic_io_apic_init();
-
-    // get RCBA address
-    io_out32(0xcf8, 0x8000f8f0);
-    uint32_t RCBA_phys = io_in32(0xcfc);
-
-    // 获取RCBA寄存器的地址
-    if (RCBA_phys > 0xfec00000 && RCBA_phys < 0xfee00000)
-        RCBA_vaddr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + RCBA_phys;
-    else
-    {
-        RCBA_vaddr = 0;
-        kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys);
-    }
-    kinfo("APIC initialized.");
-    // sti();
-    return 0;
-}
-/**
- * @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
-            __send_eoi();
-    }
-    else if (number >= 200)
-    {
-        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
-            __send_eoi(); // 向EOI寄存器写入0x00表示结束中断
-    }
-    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 (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();
-    }
-}
-
-/**
- * @brief 读取RTE寄存器
- * 由于RTE位宽为64位而IO window寄存器只有32位,因此需要两次读取
- * @param index 索引值
- * @return ul
- */
-ul apic_ioapic_read_rte(unsigned char index)
-{
-    // 由于处理器的乱序执行的问题,需要加入内存屏障以保证结果的正确性。
-    ul ret;
-    // 先读取高32bit
-    *apic_ioapic_map.virtual_index_addr = index + 1;
-    io_mfence();
-
-    ret = *apic_ioapic_map.virtual_data_addr;
-    ret <<= 32;
-    io_mfence();
-
-    // 读取低32bit
-    *apic_ioapic_map.virtual_index_addr = index;
-    io_mfence();
-    ret |= *apic_ioapic_map.virtual_data_addr;
-    io_mfence();
-
-    return ret;
-}
-
-/**
- * @brief 写入RTE寄存器
- *
- * @param index 索引值
- * @param value 要写入的值
- */
-void apic_ioapic_write_rte(unsigned char index, ul value)
-{
-    // 先写入低32bit
-    *apic_ioapic_map.virtual_index_addr = index;
-    io_mfence();
-
-    *apic_ioapic_map.virtual_data_addr = value & 0xffffffff;
-    io_mfence();
-    // 再写入高32bit
-    value >>= 32;
-    io_mfence();
-    *apic_ioapic_map.virtual_index_addr = index + 1;
-    io_mfence();
-    *apic_ioapic_map.virtual_data_addr = value & 0xffffffff;
-    io_mfence();
-}
-
-// =========== 中断控制操作接口 ============
-void apic_ioapic_enable(ul irq_num)
-{
-    ul index = 0x10 + ((irq_num - 32) << 1);
-    ul value = apic_ioapic_read_rte(index);
-    value &= (~0x10000UL);
-    apic_ioapic_write_rte(index, value);
-}
-
-void apic_ioapic_disable(ul irq_num)
-{
-    ul index = 0x10 + ((irq_num - 32) << 1);
-    ul value = apic_ioapic_read_rte(index);
-    value |= (0x10000UL);
-    apic_ioapic_write_rte(index, value);
-}
-
-ul apic_ioapic_install(ul irq_num, void *arg)
-{
-    struct apic_IO_APIC_RTE_entry *entry = (struct apic_IO_APIC_RTE_entry *)arg;
-    // RTE表项值写入对应的RTE寄存器
-    apic_ioapic_write_rte(0x10 + ((irq_num - 32) << 1), *(ul *)entry);
-    return 0;
-}
-
-void apic_ioapic_uninstall(ul irq_num)
-{
-    // 将对应的RTE表项设置为屏蔽状态
-    apic_ioapic_write_rte(0x10 + ((irq_num - 32) << 1), 0x10000UL);
-}
-
-void apic_ioapic_level_ack(ul irq_num) // 电平触发
-{
-    __send_eoi();
-    *apic_ioapic_map.virtual_EOI_addr = irq_num;
-}
-
-void apic_ioapic_edge_ack(ul irq_num) // 边沿触发
-{
-
-    // 向EOI寄存器写入0x00表示结束中断
-    /*
-        uint *eoi = (uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_EOI);
-        *eoi = 0x00;
-
-        */
-    __send_eoi();
-}
-
-/**
- * @brief local apic 边沿触发应答
- *
- * @param irq_num
- */
-
-void apic_local_apic_edge_ack(ul irq_num)
-{
-    // 向EOI寄存器写入0x00表示结束中断
-    __send_eoi();
-}
-
-/**
- * @brief 读取指定类型的 Interrupt Control Structure
- *
- * @param type ics的类型
- * @param ret_vaddr 对应的ICS的虚拟地址数组
- * @param total 返回数组的元素总个数
- * @return uint
- */
-uint apic_get_ics(const uint type, ul ret_vaddr[], uint *total)
-{
-    void *ent = (void *)(madt) + sizeof(struct acpi_Multiple_APIC_Description_Table_t);
-    struct apic_Interrupt_Controller_Structure_header_t *header =
-        (struct apic_Interrupt_Controller_Structure_header_t *)ent;
-    bool flag = false;
-
-    uint cnt = 0;
-
-    while (header->length > 2)
-    {
-        header = (struct apic_Interrupt_Controller_Structure_header_t *)ent;
-        if (header->type == type)
-        {
-            ret_vaddr[cnt++] = (ul)ent;
-            flag = true;
-        }
-        ent += header->length;
-    }
-
-    *total = cnt;
-    if (!flag)
-        return APIC_E_NOTFOUND;
-    else
-        return APIC_SUCCESS;
-}
-
-/**
- * @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;
-    }
-}
-
-/**
- * @brief 获取当前处理器的local apic id
- *
- * @return uint32_t
- */
-uint32_t apic_get_local_apic_id()
-{
-    // 获取Local APIC的基础信息 (参见英特尔开发手册Vol3A 10-39)
-    //                          Table 10-6. Local APIC Register Address Map Supported by x2APIC
-
-    if (flag_support_x2apic)
-    {
-        // 获取 Local APIC ID
-        // 0x802处是x2APIC ID 位宽32bits 的 Local APIC ID register
-        uint32_t x = 0;
-        __asm__ __volatile__("movq $0x802, %%rcx    \n\t"
-                             "rdmsr  \n\t"
-                             : "=a"(x)::"memory");
-        return x;
-    }
-    else
-    {
-        // kdebug("get Local APIC ID: edx=%#010x, eax=%#010x", edx, eax);
-        // kdebug("local_apic_id=%#018lx", );
-
-        uint32_t x = *(uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ID);
-        x = ((x >> 24) & 0xff);
-        return x;
-    }
-}
-
-/**
- * 写入icr寄存器
- *
- * @param value 写入的值
- */
-void apic_write_icr(uint64_t value)
-{
-    if (flag_support_x2apic)
-    {
-        wrmsr(0x830, value);
-    }
-    else
-    {
-        // kdebug("to write icr: %#018lx", value);
-        const uint64_t PENDING = 1UL << 12;
-        while (*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & PENDING)
-            ;
-        // kdebug("write icr: %#018lx", value);
-        *(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32) = (value >> 32) & 0xffffffff;
-        *(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) = value & 0xffffffff;
-
-        while (*(volatile uint32_t *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & PENDING)
-            ;
-        // kdebug("write icr done");
-    }
-}
-
-// 查询是否启用了x2APIC
-bool apic_x2apic_enabled()
-{
-    return flag_support_x2apic;
-}
-#pragma GCC pop_options

+ 0 - 2
kernel/src/driver/interrupt/apic/apic2rust.h

@@ -1,2 +0,0 @@
-#include <common/stddef.h>
-extern uint64_t ioapic_get_base_paddr();

+ 0 - 110
kernel/src/driver/interrupt/apic/apic_timer.h

@@ -1,110 +0,0 @@
-#pragma once
-
-#include <common/unistd.h>
-#include "apic.h"
-
-extern uint64_t apic_timer_ticks_result;
-// 5ms产生一次中断
-#define APIC_TIMER_INTERVAL 5
-#define APIC_TIMER_DIVISOR 3
-
-#define APIC_TIMER_IRQ_NUM 151
-
-#pragma GCC push_options
-#pragma GCC optimize("O0")
-
-/**
- * @brief 设置apic定时器的分频计数
- *
- * @param divider 分频除数
- */
-static __always_inline void apic_timer_set_div(uint64_t divider)
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        wrmsr(0x83e, divider);
-    else
-        __write4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_CLKDIV, divider);
-}
-
-/**
- * @brief 设置apic定时器的初始计数值
- *
- * @param init_cnt 初始计数值
- */
-static __always_inline void apic_timer_set_init_cnt(uint32_t init_cnt)
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        wrmsr(0x838, init_cnt);
-    else
-        __write4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG, init_cnt);
-}
-
-/**
- * @brief 设置apic定时器的lvt,并启动定时器
- *
- * @param vector 中断向量号
- * @param mask 是否屏蔽(1:屏蔽, 0:不屏蔽)
- * @param mode 计时模式
- */
-static __always_inline void apic_timer_set_LVT(uint32_t vector, uint32_t mask, uint32_t mode)
-{
-    register uint32_t val = (mode << 17) | vector | (mask ? (APIC_LVT_INT_MASKED) : 0);
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        wrmsr(0x832, val);
-    else
-        __write4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER, val);
-}
-
-static __always_inline void apic_timer_write_LVT(uint32_t value)
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        wrmsr(0x832, value);
-    else
-        __write4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER, value);
-}
-
-/**
- * @brief 获取apic定时器的LVT的值
- *
- */
-static __always_inline uint32_t apic_timer_get_LVT()
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        return rdmsr(0x832);
-    else
-        return __read4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER);
-}
-
-/**
- * @brief 获取apic定时器当前计数值
- *
- */
-static __always_inline uint32_t apic_timer_get_current()
-{
-    if (CURRENT_APIC_STATE == APIC_X2APIC_ENABLED)
-        return (uint32_t)rdmsr(0x839);
-    else
-        return __read4b(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG);
-}
-
-/**
- * @brief 停止apic定时器
- *
- */
-#define apic_timer_stop()                    \
-    do                                       \
-    {                                        \
-        uint32_t val = apic_timer_get_LVT(); \
-        val |= APIC_LVT_INT_MASKED;          \
-        apic_timer_write_LVT(val);           \
-    } while (0)
-
-/**
- * @brief 初始化local APIC定时器
- *
- */
-void apic_timer_init();
-
-void apic_timer_ap_core_init();
-
-#pragma GCC pop_options

+ 1 - 1
kernel/src/driver/keyboard/ps2_keyboard.c

@@ -1,5 +1,5 @@
 #include "ps2_keyboard.h"
-#include <driver/interrupt/apic/apic.h>
+#include <arch/x86_64/driver/apic/apic.h>
 #include <mm/mm.h>
 #include <mm/slab.h>
 #include <common/printk.h>

+ 14 - 14
kernel/src/driver/mouse/ps2_mouse.c

@@ -1,5 +1,5 @@
 #include "ps2_mouse.h"
-#include <driver/interrupt/apic/apic.h>
+#include <arch/x86_64/driver/apic/apic.h>
 #include <mm/mm.h>
 #include <mm/slab.h>
 #include <common/printk.h>
@@ -209,19 +209,19 @@ void 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处理器
+    // 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, (ul)ps2_mouse_buf_ptr, &ps2_mouse_intr_controller, "ps/2 mouse");

+ 2 - 1
kernel/src/exception/entry.S

@@ -68,7 +68,7 @@ ENTRY(ret_from_intr)
     // 将原本要返回的栈帧的栈指针传入do_signal的第一个参数
     movq %rsp, %rdi
     callq do_signal
-
+    cli
 
 __entry_ret_from_intr_before_gs_check_2:
     push %rcx
@@ -138,6 +138,7 @@ __entry_err_code_after_gs_check_1:
 
     callq *%rdx //调用服务程序 带*号表示调用的是绝对地址
 
+__entry_err_code_to_ret_from_exception:
     jmp ret_from_exception
 
 

+ 2 - 2
kernel/src/exception/irq.c

@@ -5,7 +5,7 @@
 #if _INTR_8259A_
 #include <driver/interrupt/8259A/8259A.h>
 #else
-#include <driver/interrupt/apic/apic.h>
+#include <arch/x86_64/driver/apic/apic.h>
 #endif
 
 #include "gate.h"
@@ -90,7 +90,7 @@ Build_IRQ(0x38);
 Build_IRQ(0x39);
 
 // 初始化中断数组
-void (*interrupt_table[26])(void) = {
+void (*interrupt_table[IRQ_NUM])(void) = {
     IRQ0x20interrupt,
     IRQ0x21interrupt,
     IRQ0x22interrupt,

+ 3 - 1
kernel/src/exception/irq.h

@@ -20,7 +20,7 @@
 #define SMP_IRQ_NUM 10
 #define LOCAL_APIC_IRQ_NUM 50
 
-extern void (*interrupt_table[26])(void);
+extern void (*interrupt_table[IRQ_NUM])(void);
 extern void do_IRQ(struct pt_regs *regs, ul number);
 
 
@@ -108,6 +108,8 @@ extern void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void);
 
 */
 
+#define APIC_TIMER_IRQ_NUM 151
+
 typedef struct hardware_intr_type
 {
     // 使能中断操作接口

+ 0 - 1
kernel/src/filesystem/vfs/file.rs

@@ -159,7 +159,6 @@ impl File {
         if self.offset > self.inode.metadata()?.size as usize {
             return Ok(0);
         }
-
         let len = self
             .inode
             .read_at(self.offset, len, buf, &mut self.private_data)?;

+ 1 - 1
kernel/src/include/bindings/wrapper.h

@@ -43,4 +43,4 @@
 #include <driver/pci/pci_irq.h>
 #include <common/errno.h>
 #include <common/cpu.h>
-#include <driver/interrupt/apic/apic2rust.h>
+#include <exception/irq.h>

+ 1 - 0
kernel/src/lib.rs

@@ -9,6 +9,7 @@
 #![feature(core_intrinsics)]
 #![feature(c_void_variant)]
 #![feature(drain_filter)]
+#![feature(inline_const)]
 #![feature(is_some_and)]
 #![feature(naked_functions)]
 #![feature(panic_info_message)]

+ 1 - 1
kernel/src/libs/Makefile

@@ -9,7 +9,7 @@ ECHO:
 	@echo "$@"
 
 $(kernel_lib_subdirs): ECHO
-	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" 
 
 $(kernel_lib_objs): ECHO
 	$(CC) $(CFLAGS) -c $@ -o [email protected]

+ 46 - 0
kernel/src/libs/lock_free_flags.rs

@@ -0,0 +1,46 @@
+use core::{cell::UnsafeCell, fmt::Debug};
+
+/// 一个无锁的标志位
+///
+/// 可与bitflags配合使用,以实现无锁的标志位
+///
+/// ## Safety
+///
+/// 由于标识位的修改是无锁,且不保证原子性,因此需要使用者自行在别的机制中,确保
+/// 哪怕标识位的值是老的,执行动作也不会有问题(或者有状态恢复机制)。
+pub struct LockFreeFlags<T> {
+    inner: UnsafeCell<T>,
+}
+
+impl<T> LockFreeFlags<T> {
+    pub unsafe fn new(inner: T) -> Self {
+        Self {
+            inner: UnsafeCell::new(inner),
+        }
+    }
+
+    pub fn get_mut(&self) -> &mut T {
+        unsafe { &mut *self.inner.get() }
+    }
+
+    pub fn get(&self) -> &T {
+        unsafe { &*self.inner.get() }
+    }
+}
+
+unsafe impl<T: Sync> Sync for LockFreeFlags<T> {}
+unsafe impl<T: Send> Send for LockFreeFlags<T> {}
+
+impl<T: Clone> Clone for LockFreeFlags<T> {
+    fn clone(&self) -> Self {
+        unsafe { Self::new(self.get().clone()) }
+    }
+}
+
+impl<T: Debug> Debug for LockFreeFlags<T> {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("LockFreeFlags")
+            .field("inner", self.get())
+            .finish()
+    }
+}

+ 1 - 0
kernel/src/libs/mod.rs

@@ -8,6 +8,7 @@ pub mod int_like;
 pub mod keyboard_parser;
 pub mod lazy_init;
 pub mod lib_ui;
+pub mod lock_free_flags;
 pub mod mutex;
 pub mod notifier;
 pub mod once;

+ 14 - 0
kernel/src/libs/rwlock.rs

@@ -265,6 +265,20 @@ impl<T> RwLock<T> {
         return r;
     }
 
+    #[allow(dead_code)]
+    pub fn try_upgradeable_read_irqsave(&self) -> Option<RwLockUpgradableGuard<T>> {
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+        ProcessManager::preempt_disable();
+        let mut r = self.inner_try_upgradeable_read();
+        if r.is_none() {
+            ProcessManager::preempt_enable();
+        } else {
+            r.as_mut().unwrap().irq_guard = Some(irq_guard);
+        }
+
+        return r;
+    }
+
     fn inner_try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>> {
         // 获得UPGRADER守卫不需要查看读者位
         // 如果获得读者锁失败,不需要撤回fetch_or的原子操作

+ 3 - 1
kernel/src/main.c

@@ -28,7 +28,7 @@
 #include "driver/multiboot2/multiboot2.h"
 #include <time/timer.h>
 
-#include <driver/interrupt/apic/apic_timer.h>
+#include <arch/x86_64/driver/apic/apic_timer.h>
 #include <virt/kvm/kvm.h>
 
 extern int rs_driver_init();
@@ -148,6 +148,7 @@ void system_initialize()
 
     rs_pci_init();
 
+
     // 这里必须加内存屏障,否则会出错
     io_mfence();
     smp_init();
@@ -167,6 +168,7 @@ void system_initialize()
     // 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
 
     apic_timer_init();
+    // while(1);
     io_mfence();
     sti();
     while (1)

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

@@ -188,7 +188,7 @@ impl ProcessManager {
         if clone_flags.contains(CloneFlags::CLONE_VM) {
             new_pcb.flags().insert(ProcessFlags::VFORK);
         }
-        *new_pcb.flags.lock() = ProcessManager::current_pcb().flags().clone();
+        *new_pcb.flags.get_mut() = ProcessManager::current_pcb().flags().clone();
         return Ok(());
     }
 

+ 2 - 2
kernel/src/process/kthread.rs

@@ -253,7 +253,7 @@ impl KernelThreadMechanism {
         // 由于当前是pid=0的idle进程,而__inner_create要求当前是kthread,所以先临时设置为kthread
         ProcessManager::current_pcb()
             .flags
-            .lock()
+            .get_mut()
             .insert(ProcessFlags::KTHREAD);
         create_info
             .set_to_mark_sleep(false)
@@ -266,7 +266,7 @@ impl KernelThreadMechanism {
 
         ProcessManager::current_pcb()
             .flags
-            .lock()
+            .get_mut()
             .remove(ProcessFlags::KTHREAD);
         drop(irq_guard);
         kinfo!("Initializing kernel thread mechanism stage1 complete");

+ 47 - 7
kernel/src/process/mod.rs

@@ -34,6 +34,7 @@ use crate::{
             constant::{FutexFlag, FUTEX_BITSET_MATCH_ANY},
             futex::Futex,
         },
+        lock_free_flags::LockFreeFlags,
         rwlock::{RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard},
         spinlock::{SpinLock, SpinLockGuard},
         wait_queue::WaitQueue,
@@ -182,7 +183,7 @@ impl ProcessManager {
         let _guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         let state = pcb.sched_info().state();
         if state.is_blocked() {
-            let mut writer = pcb.sched_info_mut();
+            let mut writer: RwLockWriteGuard<'_, ProcessSchedulerInfo> = pcb.sched_info_mut();
             let state = writer.state();
             if state.is_blocked() {
                 writer.set_state(ProcessState::Runnable);
@@ -505,7 +506,7 @@ pub struct ProcessControlBlock {
     /// 当前进程的自旋锁持有计数
     preempt_count: AtomicUsize,
 
-    flags: SpinLock<ProcessFlags>,
+    flags: LockFreeFlags<ProcessFlags>,
     worker_private: SpinLock<Option<WorkerPrivate>>,
     /// 进程的内核栈
     kernel_stack: RwLock<KernelStack>,
@@ -571,7 +572,7 @@ impl ProcessControlBlock {
 
         let basic_info = ProcessBasicInfo::new(Pid(0), ppid, name, cwd, None);
         let preempt_count = AtomicUsize::new(0);
-        let flags = SpinLock::new(ProcessFlags::empty());
+        let flags = unsafe { LockFreeFlags::new(ProcessFlags::empty()) };
 
         let sched_info = ProcessSchedulerInfo::new(None);
         let arch_info = SpinLock::new(ArchPCBInfo::new(&kstack));
@@ -662,8 +663,8 @@ impl ProcessControlBlock {
     }
 
     #[inline(always)]
-    pub fn flags(&self) -> SpinLockGuard<ProcessFlags> {
-        return self.flags.lock();
+    pub fn flags(&self) -> &mut ProcessFlags {
+        return self.flags.get_mut();
     }
 
     #[inline(always)]
@@ -707,6 +708,17 @@ impl ProcessControlBlock {
         return self.sched_info.read();
     }
 
+    #[inline(always)]
+    pub fn try_sched_info(&self, times: u8) -> Option<RwLockReadGuard<ProcessSchedulerInfo>> {
+        for _ in 0..times {
+            if let Some(r) = self.sched_info.try_read() {
+                return Some(r);
+            }
+        }
+
+        return None;
+    }
+
     #[allow(dead_code)]
     #[inline(always)]
     pub fn sched_info_irqsave(&self) -> RwLockReadGuard<ProcessSchedulerInfo> {
@@ -714,8 +726,16 @@ impl ProcessControlBlock {
     }
 
     #[inline(always)]
-    pub fn sched_info_upgradeable_irqsave(&self) -> RwLockUpgradableGuard<ProcessSchedulerInfo> {
-        return self.sched_info.upgradeable_read();
+    pub fn sched_info_try_upgradeable_irqsave(
+        &self,
+        times: u8,
+    ) -> Option<RwLockUpgradableGuard<ProcessSchedulerInfo>> {
+        for _ in 0..times {
+            if let Some(r) = self.sched_info.try_upgradeable_read_irqsave() {
+                return Some(r);
+            }
+        }
+        return None;
     }
 
     #[inline(always)]
@@ -816,10 +836,30 @@ impl ProcessControlBlock {
         self.sig_info.write()
     }
 
+    pub fn try_siginfo_mut(&self, times: u8) -> Option<RwLockWriteGuard<ProcessSignalInfo>> {
+        for _ in 0..times {
+            if let Some(r) = self.sig_info.try_write() {
+                return Some(r);
+            }
+        }
+
+        return None;
+    }
+
     pub fn sig_struct(&self) -> SpinLockGuard<SignalStruct> {
         self.sig_struct.lock()
     }
 
+    pub fn try_sig_struct_irq(&self, times: u8) -> Option<SpinLockGuard<SignalStruct>> {
+        for _ in 0..times {
+            if let Ok(r) = self.sig_struct.try_lock_irqsave() {
+                return Some(r);
+            }
+        }
+
+        return None;
+    }
+
     pub fn sig_struct_irq(&self) -> SpinLockGuard<SignalStruct> {
         self.sig_struct.lock_irqsave()
     }

+ 0 - 18
kernel/src/sched/Makefile

@@ -1,18 +0,0 @@
-
-CFLAGS += -I .
-
-
-kernel_sched_objs:= $(shell find ./*.c)
-
-ECHO:
-	@echo "$@"
-
-
-$(kernel_sched_objs): ECHO
-	$(CC) $(CFLAGS) -c $@ -o [email protected]
-
-all: $(kernel_sched_objs)
-
-
-clean:
-	echo "Done."

+ 20 - 6
kernel/src/sched/cfs.rs

@@ -9,9 +9,12 @@ use crate::{
     kBUG,
     libs::{
         rbtree::RBTree,
+        rwlock::RwLockReadGuard,
         spinlock::{SpinLock, SpinLockGuard},
     },
-    process::{ProcessControlBlock, ProcessFlags, ProcessManager, ProcessState},
+    process::{
+        ProcessControlBlock, ProcessFlags, ProcessManager, ProcessSchedulerInfo, ProcessState,
+    },
     smp::core::smp_get_processor_id,
 };
 
@@ -142,12 +145,25 @@ impl SchedulerCFS {
     }
 
     /// @brief 时钟中断到来时,由sched的core模块中的函数,调用本函数,更新CFS进程的可执行时间
-    pub fn timer_update_jiffies(&mut self) {
+    pub fn timer_update_jiffies(
+        &mut self,
+        sched_info_guard: &RwLockReadGuard<'_, ProcessSchedulerInfo>,
+    ) {
         let current_cpu_queue: &mut CFSQueue = self.cpu_queue[smp_get_processor_id() as usize];
         // todo: 引入调度周期以及所有进程的优先权进行计算,然后设置进程的可执行时间
 
+        let mut queue = None;
+        for _ in 0..10 {
+            if let Ok(q) = current_cpu_queue.locked_queue.try_lock() {
+                queue = Some(q);
+                break;
+            }
+        }
+        if queue.is_none() {
+            return;
+        }
+        let queue = queue.unwrap();
         // 更新进程的剩余可执行时间
-        let queue = current_cpu_queue.locked_queue.lock();
         current_cpu_queue.cpu_exec_proc_jiffies -= 1;
         // 时间片耗尽,标记需要被调度
         if current_cpu_queue.cpu_exec_proc_jiffies <= 0 {
@@ -158,9 +174,7 @@ impl SchedulerCFS {
         drop(queue);
 
         // 更新当前进程的虚拟运行时间
-        ProcessManager::current_pcb()
-            .sched_info()
-            .increase_virtual_runtime(1);
+        sched_info_guard.increase_virtual_runtime(1);
     }
 
     /// @brief 将进程加入cpu的cfs调度队列,并且重设其虚拟运行时间为当前队列的最小值

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

@@ -1,4 +1,7 @@
-use core::sync::atomic::{compiler_fence, Ordering};
+use core::{
+    intrinsics::unlikely,
+    sync::atomic::{compiler_fence, Ordering},
+};
 
 use alloc::{sync::Arc, vec::Vec};
 
@@ -51,8 +54,8 @@ impl CpuExecuting {
 pub fn get_cpu_loads(cpu_id: u32) -> u32 {
     let cfs_scheduler = __get_cfs_scheduler();
     let rt_scheduler = __get_rt_scheduler();
-    let len_cfs = cfs_scheduler.get_cfs_queue_len(cpu_id);
-    let len_rt = rt_scheduler.rt_queue_len(cpu_id);
+    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 load_rt = rt_scheduler.get_load_list_len(cpu_id);
     // kdebug!("this cpu_id {} is load rt {}", cpu_id, load_rt);
 
@@ -99,7 +102,13 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
     // 当前进程持有锁,不切换,避免死锁
     if ProcessManager::current_pcb().preempt_count() != 0 {
         let binding = ProcessManager::current_pcb();
-        let mut guard = binding.sched_info_upgradeable_irqsave();
+        let guard = binding.sched_info_try_upgradeable_irqsave(5);
+        if unlikely(guard.is_none()) {
+            return None;
+        }
+
+        let mut guard = guard.unwrap();
+
         let state = guard.state();
         if state.is_blocked() {
             // try to upgrade
@@ -118,6 +127,7 @@ pub fn do_sched() -> Option<Arc<ProcessControlBlock>> {
         }
         return None;
     }
+
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
     let cfs_scheduler: &mut SchedulerCFS = __get_cfs_scheduler();
     let rt_scheduler: &mut SchedulerRT = __get_rt_scheduler();
@@ -189,13 +199,17 @@ pub extern "C" fn sched_init() {
 
 /// @brief 当时钟中断到达时,更新时间片
 /// 请注意,该函数只能被时钟中断处理程序调用
-#[allow(dead_code)]
-#[no_mangle]
 pub extern "C" fn sched_update_jiffies() {
-    let policy = ProcessManager::current_pcb().sched_info().policy();
+    let binding = ProcessManager::current_pcb();
+    let guard = binding.try_sched_info(10);
+    if unlikely(guard.is_none()) {
+        return;
+    }
+    let guard = guard.unwrap();
+    let policy = guard.policy();
     match policy {
         SchedPolicy::CFS => {
-            __get_cfs_scheduler().timer_update_jiffies();
+            __get_cfs_scheduler().timer_update_jiffies(&guard);
         }
         SchedPolicy::FIFO | SchedPolicy::RR => {
             __get_rt_scheduler().timer_update_jiffies();

+ 1 - 42
kernel/src/sched/sched.h

@@ -17,48 +17,7 @@
 
 #define IS_VALID_SCHED_POLICY(_policy) ((_policy) > 0 && (_policy) <= SCHED_MAX_POLICY_NUM)
 
-// struct sched_param
-// {
-//     int sched_priority;
-// };
-// struct sched_attr
-// {
-//     uint32_t size;
-
-//     uint32_t sched_policy;
-//     uint64_t sched_flags;
-
-//     /* SCHED_NORMAL, SCHED_BATCH */
-//     int32_t sched_nice;
-
-//     /* SCHED_FIFO, SCHED_RR */
-//     uint32_t sched_priority;
-
-//     /* SCHED_DEADLINE */
-//     uint64_t sched_runtime;
-//     uint64_t sched_deadline;
-//     uint64_t sched_period;
-
-//     /* Utilization hints */
-//     uint32_t sched_util_min;
-//     uint32_t sched_util_max;
-// };
-
-// static int __sched_setscheduler(struct process_control_block *p, const struct sched_attr *attr, bool user, bool pi);
-// static int _sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param,
-//                                bool check);
-// /**
-//  * sched_setscheduler -设置进程的调度策略
-//  * @param p 需要修改的pcb
-//  * @param policy 需要设置的policy
-//  * @param param structure containing the new RT priority. 目前没有用
-//  *
-//  * @return 成功返回0,否则返回对应的错误码
-//  *
-//  */
-// int sched_setscheduler(struct process_control_block *p, int policy, const struct sched_param *param);
-
 // ================= Rust 实现 =============
-extern void sched_update_jiffies();
+
 extern void sched_init();
 extern void sched();

+ 79 - 0
kernel/src/smp/cpu/c_adapter.rs

@@ -0,0 +1,79 @@
+use alloc::vec::Vec;
+use hashbrown::HashSet;
+
+use crate::{driver::acpi::acpi_manager, kdebug};
+
+/// 这是一个临时的函数,用于在acpi、cpu模块被正式实现之前,让原本的C写的smp模块能正常运行
+///
+/// 请注意!这样写会使得smp模块与x86强耦合。正确的做法是:
+/// - 在sysfs中新增acpi firmware
+/// - 在acpi初始化的时候,初始化处理器拓扑信息
+/// - 初始化cpu模块(加入到sysfs,放置在/sys/devices/system下面)
+/// - smp模块从cpu模块处,获取到与架构无关的处理器拓扑信息
+/// - smp根据上述信息,初始化指定的处理器(这部分在arch下面实现)
+///
+/// 但是由于acpi、cpu模块还没有被正式实现,所以暂时使用这个函数来代替,接下来会按照上述步骤进行编写代码
+#[no_mangle]
+unsafe extern "C" fn rs_smp_get_cpus(res: *mut X86CpuInfo) -> usize {
+    let acpi_table = acpi_manager().tables().unwrap();
+    let platform_info = acpi_table
+        .platform_info()
+        .expect("smp_get_cpu_topology(): failed to get platform info");
+    let processor_info = platform_info
+        .processor_info
+        .expect("smp_get_cpu_topology(): failed to get processor info");
+
+    let mut id_set = HashSet::new();
+    let mut cpu_info = processor_info
+        .application_processors
+        .iter()
+        .filter_map(|ap| {
+            if id_set.contains(&ap.local_apic_id) {
+                return None;
+            }
+            let can_boot = ap.state == acpi::platform::ProcessorState::WaitingForSipi;
+            if !can_boot {
+                return None;
+            }
+
+            id_set.insert(ap.local_apic_id);
+            Some(X86CpuInfo::new(
+                ap.local_apic_id,
+                ap.processor_uid,
+                can_boot,
+            ))
+        })
+        .collect::<Vec<_>>();
+
+    let bsp_info = X86CpuInfo::new(
+        processor_info.boot_processor.local_apic_id,
+        processor_info.boot_processor.processor_uid,
+        processor_info.boot_processor.state == acpi::platform::ProcessorState::WaitingForSipi,
+    );
+    cpu_info.push(bsp_info);
+
+    cpu_info.sort_by(|a, b| a.apic_id.cmp(&b.apic_id));
+    kdebug!("cpu_info: {:?}", cpu_info);
+
+    res.copy_from_nonoverlapping(cpu_info.as_ptr(), cpu_info.len());
+    return cpu_info.len();
+}
+
+/// 这个是临时用于传数据给c版本代码的结构体,请勿用作其他用途
+#[repr(C)]
+#[derive(Debug)]
+struct X86CpuInfo {
+    apic_id: u32,
+    core_id: u32,
+    can_boot: core::ffi::c_char,
+}
+
+impl X86CpuInfo {
+    fn new(apic_id: u32, core_id: u32, can_boot: bool) -> Self {
+        Self {
+            apic_id,
+            core_id,
+            can_boot: can_boot as core::ffi::c_char,
+        }
+    }
+}

+ 1 - 0
kernel/src/smp/cpu/mod.rs

@@ -0,0 +1 @@
+mod c_adapter;

+ 1 - 0
kernel/src/smp/mod.rs

@@ -6,6 +6,7 @@ use crate::{
 
 pub mod c_adapter;
 pub mod core;
+pub mod cpu;
 
 pub fn kick_cpu(cpu_id: u32) -> Result<(), SystemError> {
     // todo: 增加对cpu_id的有效性检查

+ 32 - 29
kernel/src/smp/smp.c

@@ -2,7 +2,6 @@
 #include <common/cpu.h>
 #include <common/kprint.h>
 #include <common/spinlock.h>
-#include <driver/interrupt/apic/apic.h>
 #include <exception/gate.h>
 #include <mm/slab.h>
 #include <process/process.h>
@@ -24,7 +23,6 @@ static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struc
 
 static spinlock_t multi_core_starting_lock = {1}; // 多核启动锁
 
-static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX_SUPPORTED_PROCESSOR_NUM];
 static uint32_t total_processor_num = 0;
 static int current_starting_cpu = 0;
 
@@ -32,12 +30,24 @@ int num_cpu_started = 1;
 
 extern void smp_ap_start();
 extern uint64_t rs_get_idle_stack_top(uint32_t cpu_id);
+extern int rs_ipi_send_smp_startup(uint32_t apic_id);
+extern void rs_ipi_send_smp_init();
 extern void rs_init_syscall_64();
 
 // 在head.S中定义的,APU启动时,要加载的页表
 // 由于内存管理模块初始化的时候,重置了页表,因此我们要把当前的页表传给APU
 extern uint64_t __APU_START_CR3;
 
+struct X86CpuInfo
+{
+    uint32_t apic_id;
+    uint32_t core_id;
+    char can_boot;
+};
+
+extern uint64_t rs_smp_get_cpus(struct X86CpuInfo *res);
+static struct X86CpuInfo __cpu_info[MAX_SUPPORTED_PROCESSOR_NUM] = {0};
+
 // kick cpu 功能所使用的中断向量号
 #define KICK_CPU_IRQ_NUM 0xc8
 #define FLUSH_TLB_IRQ_NUM 0xc9
@@ -48,16 +58,8 @@ void smp_init()
     // 设置多核启动时,要加载的页表
     __APU_START_CR3 = (uint64_t)get_CR3();
 
-    ul tmp_vaddr[MAX_SUPPORTED_PROCESSOR_NUM] = {0};
-
-    apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num);
-
     // kdebug("processor num=%d", total_processor_num);
-    for (int i = 0; i < total_processor_num; ++i)
-    {
-        io_mfence();
-        proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
-    }
+    total_processor_num = rs_smp_get_cpus(__cpu_info);
 
     // 将引导程序复制到物理地址0x20000处
     memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start,
@@ -71,7 +73,7 @@ void smp_init()
     io_mfence();
 
     io_mfence();
-    ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x00, ICR_INIT, ICR_ALL_EXCLUDE_Self, 0x00);
+    rs_ipi_send_smp_init();
 
     kdebug("total_processor_num=%d", total_processor_num);
     // 注册接收kick_cpu功能的处理函数。(向量号200)
@@ -85,41 +87,42 @@ void smp_init()
         io_mfence();
 
         // 跳过BSP
-        kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i,
-               proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id,
-               proc_local_apic_structs[i]->flags);
-        if (proc_local_apic_structs[i]->local_apic_id == 0)
+        kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, can_boot=%d", i,
+               __cpu_info[i].core_id, __cpu_info[i].apic_id,
+               __cpu_info[i].can_boot);
+        if (__cpu_info[i].apic_id == 0)
         {
             // --total_processor_num;
             continue;
         }
-        if (!((proc_local_apic_structs[i]->flags & 0x1) || (proc_local_apic_structs[i]->flags & 0x2)))
+        if (__cpu_info[i].can_boot == false)
         {
             // --total_processor_num;
-            kdebug("processor %d cannot be enabled.", proc_local_apic_structs[i]->ACPI_Processor_UID);
+            kdebug("processor %d cannot be enabled.", __cpu_info[i].core_id);
             continue;
         }
         ++core_to_start;
         // continue;
         io_mfence();
-        spin_lock(&multi_core_starting_lock);
-        rs_preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt
-                             // count
-        current_starting_cpu = proc_local_apic_structs[i]->ACPI_Processor_UID;
+        spin_lock_no_preempt(&multi_core_starting_lock);
+        current_starting_cpu = __cpu_info[i].apic_id;
         io_mfence();
         // 为每个AP处理器分配栈空间
         cpu_core_info[current_starting_cpu].stack_start = (uint64_t)rs_get_idle_stack_top(current_starting_cpu);
 
         io_mfence();
 
-        // kdebug("core %d, to send start up", current_starting_cpu);
+        kdebug("core %d, to send start up", __cpu_info[i].apic_id);
         // 连续发送两次start-up IPI
-        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
-                     proc_local_apic_structs[i]->local_apic_id);
+
+        int r = rs_ipi_send_smp_startup(__cpu_info[i].apic_id);
+        if(r){
+            kerror("Failed to send startup ipi to cpu: %d", __cpu_info[i].apic_id);
+        }
+        io_mfence();
+        rs_ipi_send_smp_startup(__cpu_info[i].apic_id);
+
         io_mfence();
-        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
-                     proc_local_apic_structs[i]->local_apic_id);
-        // kdebug("core %d, send start up ok", current_starting_cpu);
     }
     io_mfence();
     while (num_cpu_started != (core_to_start + 1))
@@ -145,7 +148,7 @@ void smp_ap_start_stage2()
     ++num_cpu_started;
     io_mfence();
 
-    apic_init_ap_core_local_apic();
+    rs_apic_init_ap();
 
     // ============ 为ap处理器初始化IDLE进程 =============
 

+ 1 - 1
kernel/src/syscall/mod.rs

@@ -39,6 +39,7 @@ pub mod user_access;
 #[derive(Debug, FromPrimitive, ToPrimitive, PartialEq, Eq, Clone)]
 #[allow(dead_code, non_camel_case_types)]
 pub enum SystemError {
+    /// 操作不被允许 Operation not permitted.
     EPERM = 1,
     /// 没有指定的文件或目录 No such file or directory.
     ENOENT = 2,
@@ -490,7 +491,6 @@ impl Syscall {
                     let open_flags: FileMode = FileMode::from_bits_truncate(flags as u32);
                     Self::open(path, open_flags)
                 };
-
                 res
             }
             SYS_CLOSE => {

+ 13 - 6
tools/run-qemu.sh

@@ -40,10 +40,10 @@ ARCH="x86_64"
 # 请根据自己的需要,在-d 后方加入所需的 trace 事件
 
 # 标准的trace events
-qemu_trace_std=cpu_reset,guest_errors,exec,cpu,trace:virtio*,trace:e1000e_rx*,trace:e1000e_tx*,trace:e1000e_irq*
+qemu_trace_std=cpu_reset,guest_errors,trace:virtio*,trace:e1000e_rx*,trace:e1000e_tx*,trace:e1000e_irq*
 # 调试usb的trace
 qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset,trace:msix_write_config,trace:usb_xhci_irq_msix,trace:usb_xhci_irq_msix_use,trace:usb_xhci_irq_msix_unuse,trace:usb_xhci_irq_msi,trace:usb_xhci_*
-qemu_accel=kvm
+qemu_accel="kvm"
 if [ $(uname) == Darwin ]; then
     qemu_accel=hvf  
 fi
@@ -58,16 +58,23 @@ QEMU_CPU_FEATURES="IvyBridge,apic,x2apic,+fpu,check,+vmx,${allflags}"
 QEMU_RTC_CLOCK="clock=host,base=localtime"
 QEMU_SERIAL="file:../serial_opt.txt"
 QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
+QEMU_ACCELARATE=""
 
+# 如果qemu_accel不为空
+if [ -n "${qemu_accel}" ]; then
+    QEMU_ACCELARATE="-machine accel=${qemu_accel} -enable-kvm "
+fi
 
 # ps: 下面这条使用tap的方式,无法dhcp获取到ip,暂时不知道为什么
-# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 "
-QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 " 
+# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,netdev=nic0 -netdev tap,id=nic0,model=virtio-net-pci,script=qemu/ifup-nat,downscript=qemu/ifdown-nat -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine q35 "
+QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -device virtio-net-pci,vectors=5,netdev=hostnet0,id=net0 -usb -device qemu-xhci,id=xhci,p2=8,p3=4  -machine q35 " 
 # E1000E
-# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel} -machine q35 " 
+# QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -netdev user,id=hostnet0,hostfwd=tcp::12580-:12580 -net nic,model=e1000e,netdev=hostnet0,id=net0 -netdev user,id=hostnet1,hostfwd=tcp::12581-:12581 -device virtio-net-pci,vectors=5,netdev=hostnet1,id=net1 -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine q35 " 
 QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
 
-QEMU_ARGUMENT+="-s -S -enable-kvm -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
+QEMU_ARGUMENT+="-s -S -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
+
+QEMU_ARGUMENT+=" ${QEMU_ACCELARATE} "
 
 if [ $flag_can_run -eq 1 ]; then
   while true;do

+ 1 - 2
user/apps/shell/cmd.c

@@ -540,7 +540,6 @@ int shell_cmd_exec(int argc, char **argv)
             waitpid(pid, &retval, 0);
         else
             printf("[1] %d\n", pid); // 输出子进程的pid
-
         free(argv);
     }
 }
@@ -654,7 +653,7 @@ int parse_command(char *buf, int *argc, char ***argv)
         if (buf[i] != ' ' && (buf[i + 1] == ' ' || buf[i + 1] == '\0'))
             ++(*argc);
     }
-
+    
     // printf("\nargc=%d\n", *argc);
 
     // 为指向每个指令的指针分配空间

+ 1 - 1
user/dadk/config/relibc-0.1.0.dadk

@@ -6,7 +6,7 @@
     "BuildFromSource": {
       "Git": {
         "url": "https://git.mirrors.dragonos.org/DragonOS-Community/relibc.git",
-        "revision": "f797586d73"
+        "revision": "3ef630632f"
       }
     }
   },