Browse Source

重写SMP模块 (#633)

* 修复cpumask的迭代器的错误。

* 能进系统(AP核心还没有初始化自身)

* 初始化ap core

* 修改percpu

* 删除无用的cpu.c

* riscv64编译通过
LoGin 11 months ago
parent
commit
8cb2e9b344
44 changed files with 542 additions and 652 deletions
  1. 1 1
      kernel/src/Makefile
  2. 5 2
      kernel/src/arch/riscv64/smp/mod.rs
  3. 4 0
      kernel/src/arch/riscv64/time.rs
  4. 1 1
      kernel/src/arch/x86_64/asm/apu_boot.S
  5. 0 25
      kernel/src/arch/x86_64/c_adapter.rs
  6. 1 5
      kernel/src/arch/x86_64/cpu.rs
  7. 0 11
      kernel/src/arch/x86_64/init/main.c
  8. 0 7
      kernel/src/arch/x86_64/init/mod.rs
  9. 0 17
      kernel/src/arch/x86_64/interrupt/c_adapter.rs
  10. 1 2
      kernel/src/arch/x86_64/interrupt/ipi.rs
  11. 8 1
      kernel/src/arch/x86_64/interrupt/mod.rs
  12. 0 7
      kernel/src/arch/x86_64/mm/c_adapter.rs
  13. 5 15
      kernel/src/arch/x86_64/mm/mod.rs
  14. 0 1
      kernel/src/arch/x86_64/mod.rs
  15. 138 18
      kernel/src/arch/x86_64/smp/mod.rs
  16. 6 0
      kernel/src/arch/x86_64/time.rs
  17. 0 61
      kernel/src/common/cpu.h
  18. 1 1
      kernel/src/driver/keyboard/ps2_keyboard.rs
  19. 0 1
      kernel/src/driver/tty/virtual_terminal/mod.rs
  20. 5 0
      kernel/src/exception/mod.rs
  21. 0 2
      kernel/src/include/bindings/wrapper.h
  22. 1 5
      kernel/src/init/init.rs
  23. 3 0
      kernel/src/init/initial_kthread.rs
  24. 0 109
      kernel/src/libs/cpu.c
  25. 16 10
      kernel/src/libs/cpumask.rs
  26. 2 2
      kernel/src/libs/wait_queue.rs
  27. 9 9
      kernel/src/mm/mod.rs
  28. 13 8
      kernel/src/mm/percpu.rs
  29. 2 2
      kernel/src/process/idle.rs
  30. 2 2
      kernel/src/process/mod.rs
  31. 0 1
      kernel/src/process/process.h
  32. 2 2
      kernel/src/sched/cfs.rs
  33. 3 3
      kernel/src/sched/rt.rs
  34. 0 8
      kernel/src/smp/Makefile
  35. 0 13
      kernel/src/smp/c_adapter.rs
  36. 0 79
      kernel/src/smp/cpu/c_adapter.rs
  37. 251 5
      kernel/src/smp/cpu/mod.rs
  38. 27 0
      kernel/src/smp/init.rs
  39. 19 5
      kernel/src/smp/mod.rs
  40. 0 182
      kernel/src/smp/smp.c
  41. 0 23
      kernel/src/smp/smp.h
  42. 11 0
      kernel/src/time/mod.rs
  43. 3 6
      kernel/src/time/sleep.rs
  44. 2 0
      kernel/src/time/timer.rs

+ 1 - 1
kernel/src/Makefile

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

+ 5 - 2
kernel/src/arch/riscv64/smp/mod.rs

@@ -1,6 +1,9 @@
 use system_error::SystemError;
 
-use crate::smp::SMPArch;
+use crate::smp::{
+    cpu::{CpuHpCpuState, ProcessorId},
+    SMPArch,
+};
 
 pub struct RiscV64SMPArch;
 
@@ -10,7 +13,7 @@ impl SMPArch for RiscV64SMPArch {
         todo!()
     }
 
-    fn init() -> Result<(), SystemError> {
+    fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError> {
         todo!()
     }
 }

+ 4 - 0
kernel/src/arch/riscv64/time.rs

@@ -5,4 +5,8 @@ impl TimeArch for RiscV64TimeArch {
     fn get_cycles() -> usize {
         riscv::register::cycle::read()
     }
+
+    fn cal_expire_cycles(ns: usize) -> usize {
+        todo!()
+    }
 }

+ 1 - 1
kernel/src/arch/x86_64/asm/apu_boot.S

@@ -20,7 +20,7 @@ _apu_boot_base = .
 
     // 设置栈指针
     movl $(_apu_boot_tmp_stack_end - _apu_boot_base), %esp
-    
+
     // 计算ap处理器引导程序的基地址
     mov %cs, %ax
     movzx %ax, %esi

+ 0 - 25
kernel/src/arch/x86_64/c_adapter.rs

@@ -1,25 +0,0 @@
-use crate::{sched::SchedArch, time::TimeArch};
-
-use super::{driver::tsc::TSCManager, syscall::init_syscall_64, CurrentSchedArch, CurrentTimeArch};
-
-/// 获取当前的时间戳
-#[no_mangle]
-unsafe extern "C" fn rs_get_cycles() -> u64 {
-    return CurrentTimeArch::get_cycles() as u64;
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_tsc_get_cpu_khz() -> u64 {
-    return TSCManager::cpu_khz();
-}
-
-/// syscall指令初始化
-#[no_mangle]
-pub unsafe extern "C" fn rs_init_syscall_64() {
-    init_syscall_64();
-}
-
-#[no_mangle]
-unsafe extern "C" fn rs_init_current_core_sched() {
-    CurrentSchedArch::initial_setup_sched_local();
-}

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

@@ -1,6 +1,6 @@
 use x86::cpuid::{cpuid, CpuIdResult};
 
-use crate::smp::cpu::{ProcessorId, SmpCpuManager};
+use crate::smp::cpu::ProcessorId;
 
 /// 获取当前cpu的apic id
 #[inline]
@@ -16,7 +16,3 @@ pub unsafe fn cpu_reset() -> ! {
     unsafe { x86::io::outb(0x64, 0xfe) };
     loop {}
 }
-
-impl SmpCpuManager {
-    pub fn arch_init(_boot_cpu: ProcessorId) {}
-}

+ 0 - 11
kernel/src/arch/x86_64/init/main.c

@@ -1,11 +0,0 @@
-//
-// Created by longjin on 2022/1/20.
-//
-
-#include <common/cpu.h>
-
-
-void __init_set_cpu_stack_start(uint32_t cpu, uint64_t stack_start)
-{
-  cpu_core_info[cpu].stack_start = stack_start;
-}

+ 0 - 7
kernel/src/arch/x86_64/init/mod.rs

@@ -6,7 +6,6 @@ use x86::dtables::DescriptorTablePointer;
 use crate::{
     arch::{interrupt::trap::arch_trap_init, process::table::TSSManager},
     driver::pci::pci::pci_init,
-    include::bindings::bindings::cpu_init,
     init::init::start_kernel,
     kdebug,
     mm::{MemoryManagementArch, PhysAddr},
@@ -33,7 +32,6 @@ extern "C" {
     fn head_stack_start();
 
     fn multiboot2_init(mb2_info: u64, mb2_magic: u32) -> bool;
-    fn __init_set_cpu_stack_start(cpu: u32, stack_start: u64);
 }
 
 #[no_mangle]
@@ -81,7 +79,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
 
     set_current_core_tss(stack_start, 0);
     unsafe { TSSManager::load_tr() };
-    unsafe { __init_set_cpu_stack_start(0, stack_start as u64) };
     arch_trap_init().expect("arch_trap_init failed");
 
     return Ok(());
@@ -90,10 +87,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
 /// 架构相关的初始化
 #[inline(never)]
 pub fn setup_arch() -> Result<(), SystemError> {
-    unsafe {
-        cpu_init();
-    }
-
     // todo: 将来pci接入设备驱动模型之后,删掉这里。
     pci_init();
     return Ok(());

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

@@ -1,17 +0,0 @@
-use crate::smp::cpu::ProcessorId;
-
-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(ProcessorId::new(target_cpu))
-        .map(|_| 0)
-        .unwrap_or_else(|e| e.to_posix_errno());
-}

+ 1 - 2
kernel/src/arch/x86_64/interrupt/ipi.rs

@@ -160,7 +160,7 @@ pub fn send_ipi(kind: IpiKind, target: IpiTarget) {
 }
 
 /// 发送smp初始化IPI
-pub fn ipi_send_smp_init() -> Result<(), SystemError> {
+pub fn ipi_send_smp_init() {
     let target = ArchIpiTarget::Other;
     let icr = if CurrentApic.x2apic_enabled() {
         x86::apic::Icr::for_x2apic(
@@ -186,7 +186,6 @@ pub fn ipi_send_smp_init() -> Result<(), SystemError> {
         )
     };
     CurrentApic.write_icr(icr);
-    return Ok(());
 }
 
 /// 发送smp启动IPI

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

@@ -1,4 +1,3 @@
-mod c_adapter;
 pub(super) mod entry;
 mod handle;
 pub mod ipi;
@@ -93,6 +92,14 @@ impl InterruptArch for X86_64InterruptArch {
     fn arch_early_irq_init() -> Result<(), SystemError> {
         arch_early_irq_init()
     }
+
+    fn arch_ap_early_irq_init() -> Result<(), SystemError> {
+        if !CurrentApic.init_current_cpu() {
+            return Err(SystemError::ENODEV);
+        }
+
+        Ok(())
+    }
 }
 
 /// 中断栈帧结构体

+ 0 - 7
kernel/src/arch/x86_64/mm/c_adapter.rs

@@ -1,7 +0,0 @@
-use super::LowAddressRemapping;
-
-#[no_mangle]
-unsafe extern "C" fn rs_unmap_at_low_addr() -> usize {
-    LowAddressRemapping::unmap_at_low_address(true);
-    return 0;
-}

+ 5 - 15
kernel/src/arch/x86_64/mm/mod.rs

@@ -1,6 +1,5 @@
 pub mod barrier;
 pub mod bump;
-mod c_adapter;
 
 use alloc::vec::Vec;
 use hashbrown::HashSet;
@@ -159,6 +158,7 @@ impl MemoryManagementArch for X86_64MMArch {
 
         // 初始化内存管理器
         unsafe { allocator_init() };
+
         send_to_default_serial8250_port("x86 64 init done\n\0".as_bytes());
     }
 
@@ -181,11 +181,10 @@ impl MemoryManagementArch for X86_64MMArch {
     unsafe fn table(table_kind: PageTableKind) -> PhysAddr {
         match table_kind {
             PageTableKind::Kernel | PageTableKind::User => {
-                let paddr: usize;
                 compiler_fence(Ordering::SeqCst);
-                asm!("mov {}, cr3", out(reg) paddr, options(nomem, nostack, preserves_flags));
+                let cr3 = x86::controlregs::cr3() as usize;
                 compiler_fence(Ordering::SeqCst);
-                return PhysAddr::new(paddr);
+                return PhysAddr::new(cr3);
             }
             PageTableKind::EPT => {
                 let eptp =
@@ -461,9 +460,6 @@ unsafe fn allocator_init() {
                 flusher.ignore();
             }
         }
-
-        // 添加低地址的映射(在smp完成初始化之前,需要使用低地址的映射.初始化之后需要取消这一段映射)
-        LowAddressRemapping::remap_at_low_address(&mut mapper);
     }
 
     unsafe {
@@ -659,9 +655,7 @@ impl LowAddressRemapping {
     // 映射64M
     const REMAP_SIZE: usize = 64 * 1024 * 1024;
 
-    pub unsafe fn remap_at_low_address(
-        mapper: &mut crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>>,
-    ) {
+    pub unsafe fn remap_at_low_address(mapper: &mut PageMapper) {
         for i in 0..(Self::REMAP_SIZE / MMArch::PAGE_SIZE) {
             let paddr = PhysAddr::new(i * MMArch::PAGE_SIZE);
             let vaddr = VirtAddr::new(i * MMArch::PAGE_SIZE);
@@ -676,14 +670,10 @@ impl LowAddressRemapping {
     }
 
     /// 取消低地址的映射
-    pub unsafe fn unmap_at_low_address(flush: bool) {
-        let mut mapper = KernelMapper::lock();
-        assert!(mapper.as_mut().is_some());
+    pub unsafe fn unmap_at_low_address(mapper: &mut PageMapper, flush: bool) {
         for i in 0..(Self::REMAP_SIZE / MMArch::PAGE_SIZE) {
             let vaddr = VirtAddr::new(i * MMArch::PAGE_SIZE);
             let (_, _, flusher) = mapper
-                .as_mut()
-                .unwrap()
                 .unmap_phys(vaddr, true)
                 .expect("Failed to unmap frame");
             if flush == false {

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

@@ -1,7 +1,6 @@
 #[macro_use]
 pub mod asm;
 mod acpi;
-mod c_adapter;
 pub mod cpu;
 pub mod driver;
 pub mod elf;

+ 138 - 18
kernel/src/arch/x86_64/smp/mod.rs

@@ -1,27 +1,38 @@
 use core::{
     arch::asm,
     hint::spin_loop,
-    sync::atomic::{compiler_fence, AtomicBool, Ordering},
+    sync::atomic::{compiler_fence, fence, AtomicBool, Ordering},
 };
 
 use kdepends::memoffset::offset_of;
 use system_error::SystemError;
 
 use crate::{
-    arch::process::table::TSSManager,
+    arch::{mm::LowAddressRemapping, process::table::TSSManager, MMArch},
     exception::InterruptArch,
-    include::bindings::bindings::{cpu_core_info, smp_init},
     kdebug,
-    libs::rwlock::RwLock,
-    mm::percpu::PerCpu,
+    libs::{cpumask::CpuMask, rwlock::RwLock},
+    mm::{percpu::PerCpu, MemoryManagementArch, PhysAddr, VirtAddr, IDLE_PROCESS_ADDRESS_SPACE},
     process::ProcessManager,
-    smp::{core::smp_get_processor_id, cpu::ProcessorId, SMPArch},
+    smp::{
+        core::smp_get_processor_id,
+        cpu::{smp_cpu_manager, CpuHpCpuState, ProcessorId, SmpCpuManager},
+        init::smp_ap_start_stage2,
+        SMPArch,
+    },
 };
 
-use super::{acpi::early_acpi_boot_init, CurrentIrqArch};
+use super::{
+    acpi::early_acpi_boot_init,
+    interrupt::ipi::{ipi_send_smp_init, ipi_send_smp_startup},
+    CurrentIrqArch,
+};
 
 extern "C" {
-    fn smp_ap_start_stage2();
+    /// AP处理器启动时,会将CR3设置为这个值
+    pub static mut __APU_START_CR3: u64;
+    fn _apu_boot_start();
+    fn _apu_boot_end();
 }
 
 pub(super) static X86_64_SMP_MANAGER: X86_64SmpManager = X86_64SmpManager::new();
@@ -35,7 +46,17 @@ struct ApStartStackInfo {
 #[no_mangle]
 unsafe extern "C" fn smp_ap_start() -> ! {
     CurrentIrqArch::interrupt_disable();
-    let vaddr = cpu_core_info[smp_get_processor_id().data() as usize].stack_start as usize;
+    let vaddr = if let Some(t) = smp_cpu_manager()
+        .cpuhp_state(smp_get_processor_id())
+        .thread()
+    {
+        t.kernel_stack().stack_max_address().data() - 16
+    } else {
+        // 没有设置ap核心的栈,那么就进入死循环。
+        loop {
+            spin_loop();
+        }
+    };
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
     let v = ApStartStackInfo { vaddr };
     smp_init_switch_stack(&v);
@@ -49,7 +70,7 @@ unsafe extern "sysv64" fn smp_init_switch_stack(st: &ApStartStackInfo) -> ! {
         jmp {stage1}
     "), 
         off_rsp = const(offset_of!(ApStartStackInfo, vaddr)),
-        stage1 = sym smp_ap_start_stage1, 
+        stage1 = sym smp_ap_start_stage1,
     options(noreturn));
 }
 
@@ -66,10 +87,9 @@ unsafe extern "C" fn smp_ap_start_stage1() -> ! {
     );
     TSSManager::load_tr();
 
+    CurrentIrqArch::arch_ap_early_irq_init().expect("arch_ap_early_irq_init failed");
+
     smp_ap_start_stage2();
-    loop {
-        spin_loop();
-    }
 }
 
 /// 多核的数据
@@ -141,10 +161,34 @@ impl X86_64SmpManager {
     pub fn build_cpu_map(&self) -> Result<(), SystemError> {
         // 参考:https://code.dragonos.org.cn/xref/linux-6.1.9/arch/ia64/kernel/smpboot.c?fi=smp_build_cpu_map#496
         // todo!("build_cpu_map")
+        unsafe {
+            smp_cpu_manager().set_possible_cpu(ProcessorId::new(0), true);
+            smp_cpu_manager().set_present_cpu(ProcessorId::new(0), true);
+            smp_cpu_manager().set_online_cpu(ProcessorId::new(0));
+        }
+
+        for cpu in 1..SMP_BOOT_DATA.cpu_count() {
+            unsafe {
+                smp_cpu_manager().set_possible_cpu(ProcessorId::new(cpu as u32), true);
+                smp_cpu_manager().set_present_cpu(ProcessorId::new(cpu as u32), true);
+            }
+        }
+
+        print_cpus("possible", smp_cpu_manager().possible_cpus());
+        print_cpus("present", smp_cpu_manager().present_cpus());
         return Ok(());
     }
 }
 
+fn print_cpus(s: &str, mask: &CpuMask) {
+    let mut v = vec![];
+    for cpu in mask.iter_cpu() {
+        v.push(cpu.data());
+    }
+
+    kdebug!("{s}: cpus: {v:?}\n");
+}
+
 pub struct X86_64SMPArch;
 
 impl SMPArch for X86_64SMPArch {
@@ -155,11 +199,87 @@ impl SMPArch for X86_64SMPArch {
         return Ok(());
     }
 
-    #[inline(never)]
-    fn init() -> Result<(), SystemError> {
-        x86::fence::mfence();
-        unsafe { smp_init() };
-        x86::fence::mfence();
+    fn post_init() -> Result<(), SystemError> {
+        // AP核心启动完毕,取消低地址映射
+        unsafe {
+            LowAddressRemapping::unmap_at_low_address(
+                &mut IDLE_PROCESS_ADDRESS_SPACE()
+                    .write_irqsave()
+                    .user_mapper
+                    .utable,
+                true,
+            )
+        }
+        return Ok(());
+    }
+
+    fn start_cpu(cpu_id: ProcessorId, _cpu_hpstate: &CpuHpCpuState) -> Result<(), SystemError> {
+        kdebug!("start_cpu: cpu_id: {:#x}\n", cpu_id.data());
+
+        Self::copy_smp_start_code();
+
+        ipi_send_smp_init();
+        fence(Ordering::SeqCst);
+        ipi_send_smp_startup(cpu_id)?;
+        fence(Ordering::SeqCst);
+        ipi_send_smp_startup(cpu_id)?;
+        fence(Ordering::SeqCst);
+
         return Ok(());
     }
 }
+
+impl X86_64SMPArch {
+    const SMP_CODE_START: usize = 0x20000;
+    /// 复制SMP启动代码到0x20000处
+    fn copy_smp_start_code() -> (VirtAddr, usize) {
+        let apu_boot_size = Self::start_code_size();
+
+        fence(Ordering::SeqCst);
+        unsafe {
+            core::ptr::copy(
+                _apu_boot_start as *const u8,
+                Self::SMP_CODE_START as *mut u8,
+                apu_boot_size,
+            )
+        };
+        fence(Ordering::SeqCst);
+
+        return (VirtAddr::new(Self::SMP_CODE_START), apu_boot_size);
+    }
+
+    fn start_code_size() -> usize {
+        let apu_boot_start = _apu_boot_start as usize;
+        let apu_boot_end = _apu_boot_end as usize;
+        let apu_boot_size = apu_boot_end - apu_boot_start;
+        return apu_boot_size;
+    }
+}
+
+impl SmpCpuManager {
+    pub fn arch_init(_boot_cpu: ProcessorId) {
+        assert!(smp_get_processor_id().data() == 0);
+        // 写入APU_START_CR3,这个值会在AP处理器启动时设置到CR3寄存器
+        let addr = IDLE_PROCESS_ADDRESS_SPACE()
+            .read_irqsave()
+            .user_mapper
+            .utable
+            .table()
+            .phys();
+        let vaddr = unsafe {
+            MMArch::phys_2_virt(PhysAddr::new(&mut __APU_START_CR3 as *mut u64 as usize)).unwrap()
+        };
+        let ptr = vaddr.data() as *mut u64;
+        unsafe { *ptr = addr.data() as u64 };
+
+        // 添加低地址映射
+        unsafe {
+            LowAddressRemapping::remap_at_low_address(
+                &mut IDLE_PROCESS_ADDRESS_SPACE()
+                    .write_irqsave()
+                    .user_mapper
+                    .utable,
+            )
+        };
+    }
+}

+ 6 - 0
kernel/src/arch/x86_64/time.rs

@@ -1,9 +1,15 @@
 use crate::time::TimeArch;
 
+use super::driver::tsc::TSCManager;
+
 pub struct X86_64TimeArch;
 
 impl TimeArch for X86_64TimeArch {
     fn get_cycles() -> usize {
         unsafe { x86::time::rdtsc() as usize }
     }
+
+    fn cal_expire_cycles(ns: usize) -> usize {
+        Self::get_cycles() + ns * TSCManager::cpu_khz() as usize / 1000000
+    }
 }

+ 0 - 61
kernel/src/common/cpu.h

@@ -1,61 +0,0 @@
-#pragma once
-
-#include "glib.h"
-
-#define MAX_CPU_NUM 32 // 操作系统支持的最大处理器数量
-
-// cpu支持的最大cpuid指令的基础主功能号
-extern uint32_t Cpu_cpuid_max_Basic_mop;
-// cpu支持的最大cpuid指令的扩展主功能号
-extern uint32_t Cpu_cpuid_max_Extended_mop;
-// cpu制造商信息
-extern char Cpu_Manufacturer_Name[17];
-// 处理器名称信息
-extern char Cpu_BrandName[49];
-// 处理器家族ID
-extern uint32_t Cpu_Family_ID;
-// 处理器扩展家族ID
-extern uint32_t Cpu_Extended_Family_ID;
-// 处理器模式ID
-extern uint32_t Cpu_Model_ID;
-// 处理器扩展模式ID
-extern uint32_t Cpu_Extended_Model_ID;
-// 处理器步进ID
-extern uint32_t Cpu_Stepping_ID;
-// 处理器类型
-extern uint32_t Cpu_Processor_Type;
-// 处理器支持的最大物理地址可寻址地址线宽度
-extern uint32_t Cpu_max_phys_addrline_size;
-// 处理器支持的最大线性地址可寻址地址线宽度
-extern uint32_t Cpu_max_linear_addrline_size;
-
-// 处理器的tsc频率(单位:hz)(HPET定时器在测定apic频率时,顺便测定了这个值)
-extern uint64_t Cpu_tsc_freq;
-
-/**
- * @brief 执行cpuid指令
- *
- * @param mop 主功能号
- * @param sop 子功能号
- * @param eax 结果的eax值
- * @param ebx 结果的ebx值
- * @param ecx 结果的ecx值
- * @param edx 结果的edx值
- *
- * cpuid指令参考英特尔开发手册卷2A Chapter3 3.2 Instruction
- */
-void cpu_cpuid(uint32_t mop, uint32_t sop, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
-
-/**
- * @brief 初始化获取处理器信息模块
- *
- */
-void cpu_init(void);
-
-struct cpu_core_info_t
-{
-    uint64_t stack_start;     // 栈基地址
-    uint64_t ist_stack_start; // IST栈基地址
-};
-
-extern struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM];

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

@@ -181,7 +181,7 @@ impl IrqHandler for Ps2KeyboardIrqHandler {
         let status = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_STATUS.into()) };
         let status = Ps2StatusRegister::from(status);
         if !status.outbuf_full() {
-            return Ok(IrqReturn::NotHandled);
+            return Ok(IrqReturn::Handled);
         }
 
         let input = unsafe { CurrentPortIOArch::in8(PORT_PS2_KEYBOARD_DATA.into()) };

+ 0 - 1
kernel/src/driver/tty/virtual_terminal/mod.rs

@@ -183,7 +183,6 @@ impl TtyOperation for TtyConsoleDriverInner {
             let mut window_size = window_size.upgrade();
             window_size.col = vc_data.cols as u16;
             window_size.row = vc_data.rows as u16;
-            kerror!("window_size {:?}", *window_size);
         }
 
         if vc_data.utf {

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

@@ -40,6 +40,11 @@ pub trait InterruptArch: Send + Sync {
         Ok(())
     }
 
+    /// ap启动时的中断初始化
+    fn arch_ap_early_irq_init() -> Result<(), SystemError> {
+        Ok(())
+    }
+
     /// 响应未注册的中断
     fn ack_bad_irq(irq: IrqNumber);
 }

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

@@ -25,8 +25,6 @@
 #include <mm/slab.h>
 #include <process/process.h>
 #include <sched/sched.h>
-#include <smp/smp.h>
 #include <time/clocksource.h>
 #include <time/sleep.h>
 #include <common/errno.h>
-#include <common/cpu.h>

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

@@ -59,13 +59,12 @@ fn do_start_kernel() {
     unsafe {
         acpi_init()
     };
-
+    process_init();
     early_smp_init().expect("early smp init failed");
     irq_init().expect("irq init failed");
     setup_arch().expect("setup_arch failed");
     CurrentSMPArch::prepare_cpus().expect("prepare_cpus failed");
 
-    process_init();
     sched_init();
     softirq_init().expect("softirq init failed");
     Syscall::init().expect("syscall init failed");
@@ -74,9 +73,6 @@ fn do_start_kernel() {
     kthread_init();
     clocksource_boot_finish();
 
-    CurrentSMPArch::init().expect("smp init failed");
-    // SMP初始化有可能会开中断,所以这里再次检查中断是否关闭
-    assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
     Futex::init();
 
     setup_arch_post().expect("setup_arch_post failed");

+ 3 - 0
kernel/src/init/initial_kthread.rs

@@ -12,6 +12,7 @@ use crate::{
     kdebug, kerror,
     net::net_core::net_init,
     process::{kthread::KernelThreadMechanism, process::stdio_init},
+    smp::smp_init,
 };
 
 use super::initcall::do_initcalls;
@@ -55,6 +56,8 @@ fn kenrel_init_freeable() -> Result<(), SystemError> {
         panic!("Failed to initialize subsystems: {:?}", err);
     });
 
+    smp_init();
+
     return Ok(());
 }
 

+ 0 - 109
kernel/src/libs/cpu.c

@@ -1,109 +0,0 @@
-#include <common/cpu.h>
-#include <common/kprint.h>
-#include <common/printk.h>
-// #pragma GCC optimize("O0")
-// cpu支持的最大cpuid指令的基础主功能号
-uint Cpu_cpuid_max_Basic_mop;
-// cpu支持的最大cpuid指令的扩展主功能号
-uint Cpu_cpuid_max_Extended_mop;
-// cpu制造商信息
-char Cpu_Manufacturer_Name[17] = {0};
-// 处理器名称信息
-char Cpu_BrandName[49] = {0};
-// 处理器家族ID
-uint Cpu_Family_ID;
-// 处理器扩展家族ID
-uint Cpu_Extended_Family_ID;
-// 处理器模式ID
-uint Cpu_Model_ID;
-// 处理器扩展模式ID
-uint Cpu_Extended_Model_ID;
-// 处理器步进ID
-uint Cpu_Stepping_ID;
-// 处理器类型
-uint Cpu_Processor_Type;
-// 处理器支持的最大物理地址可寻址地址线宽度
-uint Cpu_max_phys_addrline_size;
-// 处理器支持的最大线性地址可寻址地址线宽度
-uint Cpu_max_linear_addrline_size;
-// 处理器的tsc频率(单位:hz)(HPET定时器在测定apic频率时,顺便测定了这个值)
-uint64_t Cpu_tsc_freq = 0;
-
-struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM];
-
-#if ARCH(I386) || ARCH(X86_64)
-
-void cpu_init(void)
-{
-    // 获取处理器制造商信息
-    uint tmp_info[4] = {0};
-    cpu_cpuid(0, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
-
-    // 保存CPU支持的最大cpuid指令主功能号
-    Cpu_cpuid_max_Basic_mop = tmp_info[0];
-    // 保存制造商名称
-    *(uint *)&Cpu_Manufacturer_Name[0] = tmp_info[1];
-    *(uint *)&Cpu_Manufacturer_Name[4] = tmp_info[3];
-    *(uint *)&Cpu_Manufacturer_Name[8] = tmp_info[2];
-    Cpu_Manufacturer_Name[12] = '\0';
-    kinfo("CPU manufacturer: %s", Cpu_Manufacturer_Name);
-
-    // 获取处理器型号信息
-    int count = 0;
-    for (uint i = 0x80000002; i < 0x80000005; ++i)
-    {
-        cpu_cpuid(i, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
-        for (int j = 0; j <= 3; ++j)
-        {
-            *(uint *)&Cpu_BrandName[4 * count] = tmp_info[j];
-            ++count;
-        }
-    }
-    Cpu_BrandName[48] = '\0';
-
-    kinfo("CPU Brand Name: %s", Cpu_BrandName);
-
-    // 使用cpuid主功能号0x01进行查询(未保存ebx ecx edx的信息,具体参见白皮书)
-    cpu_cpuid(1, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
-
-    // EAX中包含 Version Informatin Type,Family,Model,and Stepping ID
-    Cpu_Stepping_ID = tmp_info[0] & 0xf;
-    Cpu_Model_ID = (tmp_info[0] >> 4) & 0xf;
-    Cpu_Family_ID = (tmp_info[0] >> 8) & 0xf;
-    Cpu_Processor_Type = (tmp_info[0] >> 12) & 0x3;
-    // 14-15位保留
-    Cpu_Extended_Model_ID = (tmp_info[0] >> 16) & 0xf;
-    Cpu_Extended_Family_ID = (tmp_info[0] >> 20) & 0xff;
-    // 31-25位保留
-    kinfo("Family ID=%#03lx\t Extended Family ID=%#03lx\t Processor Type=%#03lx\t", Cpu_Family_ID, Cpu_Extended_Family_ID, Cpu_Processor_Type);
-    kinfo("Model ID=%#03lx\t Extended Model ID=%#03lx\tStepping ID=%#03lx\t", Cpu_Model_ID, Cpu_Extended_Model_ID, Cpu_Stepping_ID);
-
-    // 使用0x80000008主功能号,查询处理器支持的最大可寻址地址线宽度
-    cpu_cpuid(0x80000008, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
-    Cpu_max_phys_addrline_size = tmp_info[0] & 0xff;
-    Cpu_max_linear_addrline_size = (tmp_info[0] >> 8) & 0xff;
-
-    kinfo("Cpu_max_phys_addrline_size = %d", Cpu_max_phys_addrline_size);
-    kinfo("Cpu_max_linear_addrline_size = %d", Cpu_max_linear_addrline_size);
-
-    cpu_cpuid(0x80000000, 0, &tmp_info[0], &tmp_info[1], &tmp_info[2], &tmp_info[3]);
-    Cpu_cpuid_max_Extended_mop = tmp_info[0];
-
-    kinfo("Max basic mop=%#05lx", Cpu_cpuid_max_Basic_mop);
-    kinfo("Max extended mop=%#05lx", Cpu_cpuid_max_Extended_mop);
-    return;
-}
-
-void cpu_cpuid(uint32_t mop, uint32_t sop, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
-{
-    // 向eax和ecx分别输入主功能号和子功能号
-    // 结果输出到eax, ebx, ecx, edx
-    __asm__ __volatile__("cpuid \n\t"
-                         : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
-                         : "0"(mop), "2"(sop)
-                         : "memory");
-}
-
-#else
-void cpu_init(void){}
-#endif

+ 16 - 10
kernel/src/libs/cpumask.rs

@@ -65,8 +65,9 @@ impl CpuMask {
     pub fn iter_cpu(&self) -> CpuMaskIter {
         CpuMaskIter {
             mask: self,
-            index: ProcessorId::new(0),
+            index: None,
             set: true,
+            begin: true,
         }
     }
 
@@ -74,36 +75,41 @@ impl CpuMask {
     pub fn iter_zero_cpu(&self) -> CpuMaskIter {
         CpuMaskIter {
             mask: self,
-            index: ProcessorId::new(0),
+            index: None,
             set: false,
+            begin: true,
         }
     }
 }
 
 pub struct CpuMaskIter<'a> {
     mask: &'a CpuMask,
-    index: ProcessorId,
+    index: Option<ProcessorId>,
     set: bool,
+    begin: bool,
 }
 
 impl<'a> Iterator for CpuMaskIter<'a> {
     type Item = ProcessorId;
 
     fn next(&mut self) -> Option<ProcessorId> {
-        if self.index.data() == 0 {
+        if self.index.is_none() && self.begin {
             if self.set {
-                self.index = self.mask.first()?;
+                self.index = self.mask.first();
             } else {
-                self.index = self.mask.first_zero()?;
+                self.index = self.mask.first_zero();
             }
-        }
 
+            self.begin = false;
+        }
+        let result = self.index;
         if self.set {
-            self.index = self.mask.next_index(self.index)?;
+            self.index = self.mask.next_index(self.index?);
         } else {
-            self.index = self.mask.next_zero_index(self.index)?;
+            self.index = self.mask.next_zero_index(self.index?);
         }
-        Some(self.index)
+
+        result
     }
 }
 

+ 2 - 2
kernel/src/libs/wait_queue.rs

@@ -87,7 +87,7 @@ impl WaitQueue {
     }
 
     pub unsafe fn sleep_without_schedule_uninterruptible(&self) {
-        before_sleep_check(0);
+        before_sleep_check(1);
         // 安全检查:确保当前处于中断禁止状态
         assert!(CurrentIrqArch::is_irq_enabled() == false);
         let mut guard: SpinLockGuard<InnerWaitQueue> = self.0.lock();
@@ -264,7 +264,7 @@ fn before_sleep_check(max_preempt: usize) {
     if unlikely(pcb.preempt_count() > max_preempt) {
         kwarn!(
             "Process {:?}: Try to sleep when preempt count is {}",
-            pcb.pid(),
+            pcb.pid().data(),
             pcb.preempt_count()
         );
     }

+ 9 - 9
kernel/src/mm/mod.rs

@@ -33,7 +33,7 @@ pub mod syscall;
 pub mod ucontext;
 
 /// 内核INIT进程的用户地址空间结构体(仅在process_init中初始化)
-static mut __INITIAL_PROCESS_ADDRESS_SPACE: Option<Arc<AddressSpace>> = None;
+static mut __IDLE_PROCESS_ADDRESS_SPACE: Option<Arc<AddressSpace>> = None;
 
 bitflags! {
     /// Virtual memory flags
@@ -74,29 +74,29 @@ bitflags! {
     }
 }
 
-/// 获取内核INIT进程的用户地址空间结构体
+/// 获取内核IDLE进程的用户地址空间结构体
 #[allow(non_snake_case)]
 #[inline(always)]
-pub fn INITIAL_PROCESS_ADDRESS_SPACE() -> Arc<AddressSpace> {
+pub fn IDLE_PROCESS_ADDRESS_SPACE() -> Arc<AddressSpace> {
     unsafe {
-        return __INITIAL_PROCESS_ADDRESS_SPACE
+        return __IDLE_PROCESS_ADDRESS_SPACE
             .as_ref()
-            .expect("INITIAL_PROCESS_ADDRESS_SPACE is null")
+            .expect("IDLE_PROCESS_ADDRESS_SPACE is null")
             .clone();
     }
 }
 
-/// 设置内核INIT进程的用户地址空间结构体全局变量
+/// 设置内核IDLE进程的用户地址空间结构体全局变量
 #[allow(non_snake_case)]
-pub unsafe fn set_INITIAL_PROCESS_ADDRESS_SPACE(address_space: Arc<AddressSpace>) {
+pub unsafe fn set_IDLE_PROCESS_ADDRESS_SPACE(address_space: Arc<AddressSpace>) {
     static INITIALIZED: AtomicBool = AtomicBool::new(false);
     if INITIALIZED
         .compare_exchange(false, true, Ordering::SeqCst, Ordering::Acquire)
         .is_err()
     {
-        panic!("INITIAL_PROCESS_ADDRESS_SPACE is already initialized");
+        panic!("IDLE_PROCESS_ADDRESS_SPACE is already initialized");
     }
-    __INITIAL_PROCESS_ADDRESS_SPACE = Some(address_space);
+    __IDLE_PROCESS_ADDRESS_SPACE = Some(address_space);
 }
 
 /// @brief 将内核空间的虚拟地址转换为物理地址

+ 13 - 8
kernel/src/mm/percpu.rs

@@ -3,9 +3,11 @@ use core::sync::atomic::AtomicU32;
 use alloc::vec::Vec;
 
 use crate::{
-    include::bindings::bindings::smp_get_total_cpu,
     libs::lazy_init::Lazy,
-    smp::{core::smp_get_processor_id, cpu::ProcessorId},
+    smp::{
+        core::smp_get_processor_id,
+        cpu::{smp_cpu_manager, ProcessorId},
+    },
 };
 
 /// 系统中的CPU数量
@@ -29,8 +31,9 @@ impl PerCpu {
         if CPU_NUM.load(core::sync::atomic::Ordering::SeqCst) != 0 {
             panic!("PerCpu::init() called twice");
         }
-        let cpus = unsafe { smp_get_total_cpu() };
-        assert!(cpus > 0, "PerCpu::init(): smp_get_total_cpu() returned 0");
+        let cpus = smp_cpu_manager().present_cpus_count();
+        assert!(cpus > 0, "PerCpu::init(): present_cpus_count() returned 0");
+
         CPU_NUM.store(cpus, core::sync::atomic::Ordering::SeqCst);
     }
 }
@@ -80,17 +83,19 @@ impl<T> PerCpuVar<T> {
         &self.inner[cpu_id.data() as usize]
     }
 
-    pub fn get_mut(&mut self) -> &mut T {
+    pub fn get_mut(&self) -> &mut T {
         let cpu_id = smp_get_processor_id();
-        &mut self.inner[cpu_id.data() as usize]
+        unsafe {
+            &mut (self as *const Self as *mut Self).as_mut().unwrap().inner[cpu_id.data() as usize]
+        }
     }
 
     pub unsafe fn force_get(&self, cpu_id: ProcessorId) -> &T {
         &self.inner[cpu_id.data() as usize]
     }
 
-    pub unsafe fn force_get_mut(&mut self, cpu_id: ProcessorId) -> &mut T {
-        &mut self.inner[cpu_id.data() as usize]
+    pub unsafe fn force_get_mut(&self, cpu_id: ProcessorId) -> &mut T {
+        &mut (self as *const Self as *mut Self).as_mut().unwrap().inner[cpu_id.data() as usize]
     }
 }
 

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

@@ -6,7 +6,7 @@ use core::{
 use alloc::{sync::Arc, vec::Vec};
 
 use crate::{
-    mm::{percpu::PerCpu, VirtAddr, INITIAL_PROCESS_ADDRESS_SPACE},
+    mm::{percpu::PerCpu, VirtAddr, IDLE_PROCESS_ADDRESS_SPACE},
     process::KernelStack,
     smp::{core::smp_get_processor_id, cpu::ProcessorId},
 };
@@ -53,7 +53,7 @@ impl ProcessManager {
             unsafe {
                 idle_pcb
                     .basic_mut()
-                    .set_user_vm(Some(INITIAL_PROCESS_ADDRESS_SPACE()))
+                    .set_user_vm(Some(IDLE_PROCESS_ADDRESS_SPACE()))
             };
 
             assert!(idle_pcb.sched_info().on_cpu().is_none());

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

@@ -41,7 +41,7 @@ use crate::{
         spinlock::{SpinLock, SpinLockGuard},
         wait_queue::WaitQueue,
     },
-    mm::{percpu::PerCpuVar, set_INITIAL_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr},
+    mm::{percpu::PerCpuVar, set_IDLE_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr},
     net::socket::SocketInode,
     sched::{
         completion::Completion,
@@ -109,7 +109,7 @@ impl ProcessManager {
             compiler_fence(Ordering::SeqCst);
             kdebug!("To create address space for INIT process.");
             // test_buddy();
-            set_INITIAL_PROCESS_ADDRESS_SPACE(
+            set_IDLE_PROCESS_ADDRESS_SPACE(
                 AddressSpace::new(true).expect("Failed to create address space for INIT process."),
             );
             kdebug!("INIT process address space created.");

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

@@ -10,7 +10,6 @@
 
 #pragma once
 #include "ptrace.h"
-#include <common/cpu.h>
 #include <common/errno.h>
 #include <common/glib.h>
 #include <syscall/syscall.h>

+ 2 - 2
kernel/src/sched/cfs.rs

@@ -5,12 +5,12 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec};
 use crate::{
     arch::CurrentIrqArch,
     exception::InterruptArch,
-    include::bindings::bindings::MAX_CPU_NUM,
     kBUG,
     libs::{
         rbtree::RBTree,
         spinlock::{SpinLock, SpinLockGuard},
     },
+    mm::percpu::PerCpu,
     process::{
         ProcessControlBlock, ProcessFlags, ProcessManager, ProcessSchedulerInfo, ProcessState,
     },
@@ -122,7 +122,7 @@ impl SchedulerCFS {
         };
 
         // 为每个cpu核心创建队列,进程重构后可以直接初始化Idle_pcb?
-        for i in 0..MAX_CPU_NUM {
+        for i in 0..PerCpu::MAX_CPU_NUM {
             let idle_pcb = ProcessManager::idle_pcb()[i as usize].clone();
             result
                 .cpu_queue

+ 3 - 3
kernel/src/sched/rt.rs

@@ -4,9 +4,9 @@ use alloc::{boxed::Box, collections::LinkedList, sync::Arc, vec::Vec};
 
 use crate::{
     arch::cpu::current_cpu_id,
-    include::bindings::bindings::MAX_CPU_NUM,
     kBUG, kdebug,
     libs::spinlock::SpinLock,
+    mm::percpu::PerCpu,
     process::{ProcessControlBlock, ProcessFlags, ProcessManager},
     smp::cpu::ProcessorId,
 };
@@ -108,7 +108,7 @@ impl SchedulerRT {
         };
 
         // 为每个cpu核心创建队列
-        for cpu_id in 0..MAX_CPU_NUM {
+        for cpu_id in 0..PerCpu::MAX_CPU_NUM {
             result.cpu_queue.push(Vec::new());
             // 每个CPU有MAX_RT_PRIO个优先级队列
             for _ in 0..SchedulerRT::MAX_RT_PRIO {
@@ -116,7 +116,7 @@ impl SchedulerRT {
             }
         }
         // 为每个cpu核心创建负载统计队列
-        for _ in 0..MAX_CPU_NUM {
+        for _ in 0..PerCpu::MAX_CPU_NUM {
             result
                 .load_list
                 .push(Box::leak(Box::new(LinkedList::new())));

+ 0 - 8
kernel/src/smp/Makefile

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

+ 0 - 13
kernel/src/smp/c_adapter.rs

@@ -1,13 +0,0 @@
-use super::{core::smp_get_processor_id, cpu::ProcessorId, kick_cpu};
-
-#[no_mangle]
-pub extern "C" fn rs_kick_cpu(cpu_id: u32) -> usize {
-    return kick_cpu(ProcessorId::new(cpu_id))
-        .map(|_| 0usize)
-        .unwrap_or_else(|e| e.to_posix_errno() as usize);
-}
-
-#[no_mangle]
-pub extern "C" fn rs_current_cpu_id() -> i32 {
-    return smp_get_processor_id().data() as i32;
-}

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

@@ -1,79 +0,0 @@
-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,
-        }
-    }
-}

+ 251 - 5
kernel/src/smp/cpu/mod.rs

@@ -1,8 +1,17 @@
 use core::sync::atomic::AtomicU32;
 
-use crate::libs::cpumask::CpuMask;
+use alloc::{sync::Arc, vec::Vec};
+use system_error::SystemError;
 
-mod c_adapter;
+use crate::{
+    arch::CurrentSMPArch,
+    libs::cpumask::CpuMask,
+    mm::percpu::{PerCpu, PerCpuVar},
+    process::{ProcessControlBlock, ProcessManager},
+    sched::completion::Completion,
+};
+
+use super::{core::smp_get_processor_id, SMPArch};
 
 int_like!(ProcessorId, AtomicProcessorId, u32, AtomicU32);
 
@@ -17,14 +26,81 @@ pub fn smp_cpu_manager() -> &'static SmpCpuManager {
     unsafe { SMP_CPU_MANAGER.as_ref().unwrap() }
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub enum CpuHpState {
+    /// 启动阈值
+    ThresholdBringUp = 0,
+
+    /// 该CPU是离线的
+    Offline,
+
+    /// 该CPU是在线的
+    Online,
+}
+
+/// Per-Cpu Cpu的热插拔状态
+pub struct CpuHpCpuState {
+    /// 当前状态
+    state: CpuHpState,
+    /// 目标状态
+    target_state: CpuHpState,
+    /// 指向热插拔的线程的PCB
+    thread: Option<Arc<ProcessControlBlock>>,
+
+    /// 当前是否为启动流程
+    bringup: bool,
+    /// 启动完成的信号
+    comp_done_up: Completion,
+}
+
+impl CpuHpCpuState {
+    const fn new() -> Self {
+        Self {
+            state: CpuHpState::Offline,
+            target_state: CpuHpState::Offline,
+            thread: None,
+            bringup: false,
+            comp_done_up: Completion::new(),
+        }
+    }
+
+    pub const fn thread(&self) -> &Option<Arc<ProcessControlBlock>> {
+        &self.thread
+    }
+}
+
 pub struct SmpCpuManager {
+    /// 可用的CPU
     possible_cpus: CpuMask,
+    /// 出现的CPU
+    present_cpus: CpuMask,
+    /// 出现在系统中的CPU的数量
+    present_cnt: AtomicU32,
+    /// 可用的CPU的数量
+    possible_cnt: AtomicU32,
+    /// CPU的状态
+    cpuhp_state: PerCpuVar<CpuHpCpuState>,
 }
 
 impl SmpCpuManager {
     fn new() -> Self {
         let possible_cpus = CpuMask::new();
-        Self { possible_cpus }
+        let present_cpus = CpuMask::new();
+        let mut data = Vec::with_capacity(PerCpu::MAX_CPU_NUM as usize);
+        for i in 0..PerCpu::MAX_CPU_NUM {
+            let mut hpstate = CpuHpCpuState::new();
+            hpstate.thread = Some(ProcessManager::idle_pcb()[i as usize].clone());
+            data.push(hpstate);
+        }
+        let cpuhp_state = PerCpuVar::new(data).unwrap();
+
+        Self {
+            possible_cpus,
+            present_cpus,
+            cpuhp_state,
+            present_cnt: AtomicU32::new(0),
+            possible_cnt: AtomicU32::new(0),
+        }
     }
 
     /// 设置可用的CPU
@@ -38,14 +114,184 @@ impl SmpCpuManager {
         // 强制获取mut引用,因为该函数只能在初始化阶段调用
         let p = (self as *const Self as *mut Self).as_mut().unwrap();
 
-        p.possible_cpus.set(cpu, value);
+        if let Some(prev) = p.possible_cpus.set(cpu, value) {
+            if prev != value {
+                if value {
+                    p.possible_cnt
+                        .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
+                } else {
+                    p.possible_cnt
+                        .fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
+                }
+            }
+        }
     }
 
     /// 获取可用的CPU
-    #[allow(dead_code)]
     pub fn possible_cpus(&self) -> &CpuMask {
         &self.possible_cpus
     }
+
+    #[allow(dead_code)]
+    pub fn possible_cpus_count(&self) -> u32 {
+        self.possible_cnt.load(core::sync::atomic::Ordering::SeqCst)
+    }
+
+    pub fn present_cpus_count(&self) -> u32 {
+        self.present_cnt.load(core::sync::atomic::Ordering::SeqCst)
+    }
+
+    pub unsafe fn set_present_cpu(&self, cpu: ProcessorId, value: bool) {
+        // 强制获取mut引用,因为该函数只能在初始化阶段调用
+        let p = (self as *const Self as *mut Self).as_mut().unwrap();
+
+        if let Some(prev) = p.present_cpus.set(cpu, value) {
+            if prev != value {
+                if value {
+                    p.present_cnt
+                        .fetch_add(1, core::sync::atomic::Ordering::SeqCst);
+                } else {
+                    p.present_cnt
+                        .fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
+                }
+            }
+        }
+    }
+
+    /// 获取CPU的状态
+    pub fn cpuhp_state(&self, cpu_id: ProcessorId) -> &CpuHpCpuState {
+        unsafe { self.cpuhp_state.force_get(cpu_id) }
+    }
+
+    fn cpuhp_state_mut(&self, cpu_id: ProcessorId) -> &mut CpuHpCpuState {
+        unsafe { self.cpuhp_state.force_get_mut(cpu_id) }
+    }
+
+    /// 设置CPU的状态, 返回旧的状态
+    pub unsafe fn set_cpuhp_state(
+        &self,
+        cpu_id: ProcessorId,
+        target_state: CpuHpState,
+    ) -> CpuHpState {
+        let p = self.cpuhp_state.force_get_mut(cpu_id);
+        let old_state = p.state;
+
+        let bringup = target_state > p.state;
+        p.target_state = target_state;
+        p.bringup = bringup;
+
+        return old_state;
+    }
+
+    pub fn set_online_cpu(&self, cpu_id: ProcessorId) {
+        unsafe { self.set_cpuhp_state(cpu_id, CpuHpState::Online) };
+    }
+
+    /// 获取出现在系统中的CPU
+    #[allow(dead_code)]
+    pub fn present_cpus(&self) -> &CpuMask {
+        &self.present_cpus
+    }
+
+    /// 启动bsp以外的CPU
+    pub(super) fn bringup_nonboot_cpus(&self) {
+        for cpu_id in self.present_cpus().iter_cpu() {
+            if cpu_id == smp_get_processor_id() {
+                continue;
+            }
+
+            kdebug!("Bring up CPU {}", cpu_id.data());
+
+            if let Err(e) = self.cpu_up(cpu_id, CpuHpState::Online) {
+                kerror!("Failed to bring up CPU {}: {:?}", cpu_id.data(), e);
+            }
+        }
+
+        kinfo!("All non-boot CPUs have been brought up");
+    }
+
+    fn cpu_up(&self, cpu_id: ProcessorId, target_state: CpuHpState) -> Result<(), SystemError> {
+        if !self.possible_cpus().get(cpu_id).unwrap_or(false) {
+            return Err(SystemError::EINVAL);
+        }
+
+        let cpu_state = self.cpuhp_state(cpu_id).state;
+        kdebug!(
+            "cpu_up: cpu_id: {}, cpu_state: {:?}, target_state: {:?}",
+            cpu_id.data(),
+            cpu_state,
+            target_state
+        );
+        // 如果CPU的状态已经达到或者超过目标状态,则直接返回
+        if cpu_state >= target_state {
+            return Ok(());
+        }
+
+        unsafe { self.set_cpuhp_state(cpu_id, target_state) };
+        let cpu_state = self.cpuhp_state(cpu_id).state;
+        if cpu_state > CpuHpState::ThresholdBringUp {
+            self.cpuhp_kick_ap(cpu_id, target_state)?;
+        }
+
+        return Ok(());
+    }
+
+    fn cpuhp_kick_ap(
+        &self,
+        cpu_id: ProcessorId,
+        target_state: CpuHpState,
+    ) -> Result<(), SystemError> {
+        let prev_state = unsafe { self.set_cpuhp_state(cpu_id, target_state) };
+        let hpstate = self.cpuhp_state_mut(cpu_id);
+        if let Err(e) = self.do_cpuhp_kick_ap(hpstate) {
+            self.cpuhp_reset_state(hpstate, prev_state);
+            self.do_cpuhp_kick_ap(hpstate).ok();
+
+            return Err(e);
+        }
+
+        return Ok(());
+    }
+
+    fn do_cpuhp_kick_ap(&self, cpu_state: &mut CpuHpCpuState) -> Result<(), SystemError> {
+        let pcb = cpu_state.thread.as_ref().ok_or(SystemError::EINVAL)?;
+        let cpu_id = pcb.sched_info().on_cpu().ok_or(SystemError::EINVAL)?;
+
+        // todo: 等待CPU启动完成
+
+        ProcessManager::wakeup(cpu_state.thread.as_ref().unwrap())?;
+        CurrentSMPArch::start_cpu(cpu_id, cpu_state)?;
+        assert_eq!(ProcessManager::current_pcb().preempt_count(), 0);
+        self.wait_for_ap_thread(cpu_state, cpu_state.bringup);
+
+        return Ok(());
+    }
+
+    fn wait_for_ap_thread(&self, cpu_state: &mut CpuHpCpuState, bringup: bool) {
+        if bringup {
+            cpu_state.comp_done_up.wait_for_completion().ok();
+        } else {
+            todo!("wait_for_ap_thread")
+        }
+    }
+
+    /// 完成AP的启动
+    pub fn complete_ap_thread(&self, bringup: bool) {
+        let cpu_id = smp_get_processor_id();
+        let cpu_state = self.cpuhp_state_mut(cpu_id);
+        if bringup {
+            cpu_state.comp_done_up.complete();
+        } else {
+            todo!("complete_ap_thread")
+        }
+    }
+
+    fn cpuhp_reset_state(&self, st: &mut CpuHpCpuState, prev_state: CpuHpState) {
+        let bringup = !st.bringup;
+        st.target_state = prev_state;
+
+        st.bringup = bringup;
+    }
 }
 
 pub fn smp_cpu_manager_init(boot_cpu: ProcessorId) {

+ 27 - 0
kernel/src/smp/init.rs

@@ -0,0 +1,27 @@
+use crate::{
+    arch::{syscall::arch_syscall_init, CurrentIrqArch, CurrentSchedArch},
+    exception::InterruptArch,
+    process::ProcessManager,
+    sched::SchedArch,
+    smp::{core::smp_get_processor_id, cpu::smp_cpu_manager},
+};
+
+#[inline(never)]
+pub fn smp_ap_start_stage2() -> ! {
+    assert_eq!(CurrentIrqArch::is_irq_enabled(), false);
+
+    smp_cpu_manager().complete_ap_thread(true);
+
+    do_ap_start_stage2();
+
+    CurrentSchedArch::initial_setup_sched_local();
+
+    CurrentSchedArch::enable_sched_local();
+    ProcessManager::arch_idle_func();
+}
+
+#[inline(never)]
+fn do_ap_start_stage2() {
+    kinfo!("Successfully started AP {}", smp_get_processor_id().data());
+    arch_syscall_init().expect("AP core failed to initialize syscall");
+}

+ 19 - 5
kernel/src/smp/mod.rs

@@ -1,18 +1,18 @@
 use system_error::SystemError;
 
 use crate::{
-    arch::interrupt::ipi::send_ipi,
+    arch::{interrupt::ipi::send_ipi, CurrentSMPArch},
     exception::ipi::{IpiKind, IpiTarget},
 };
 
 use self::{
     core::smp_get_processor_id,
-    cpu::{smp_cpu_manager_init, ProcessorId},
+    cpu::{smp_cpu_manager, smp_cpu_manager_init, CpuHpCpuState, ProcessorId},
 };
 
-pub mod c_adapter;
 pub mod core;
 pub mod cpu;
+pub mod init;
 
 pub fn kick_cpu(cpu_id: ProcessorId) -> Result<(), SystemError> {
     // todo: 增加对cpu_id的有效性检查
@@ -27,10 +27,17 @@ pub trait SMPArch {
     /// 该函数需要标记为 `#[inline(never)]`
     fn prepare_cpus() -> Result<(), SystemError>;
 
-    /// 初始化SMP
+    /// 在smp初始化结束后,执行一些必要的操作
     ///
     /// 该函数需要标记为 `#[inline(never)]`
-    fn init() -> Result<(), SystemError>;
+    fn post_init() -> Result<(), SystemError> {
+        return Ok(());
+    }
+
+    /// 向目标CPU发送启动信号
+    ///
+    /// 如果目标CPU已经启动,返回Ok。
+    fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError>;
 }
 
 /// 早期SMP初始化
@@ -40,3 +47,10 @@ pub fn early_smp_init() -> Result<(), SystemError> {
 
     return Ok(());
 }
+
+#[inline(never)]
+pub fn smp_init() {
+    smp_cpu_manager().bringup_nonboot_cpus();
+
+    CurrentSMPArch::post_init().expect("SMP post init failed");
+}

+ 0 - 182
kernel/src/smp/smp.c

@@ -1,182 +0,0 @@
-#include "smp.h"
-#include <common/cpu.h>
-#include <common/kprint.h>
-#include <common/spinlock.h>
-#include <mm/slab.h>
-#include <process/process.h>
-
-#include <process/preempt.h>
-#include <sched/sched.h>
-#include <driver/acpi/acpi.h>
-#include <arch/arch.h>
-
-/* x86-64 specific MSRs */
-#define MSR_EFER 0xc0000080         /* extended feature register */
-#define MSR_STAR 0xc0000081         /* legacy mode SYSCALL target */
-#define MSR_LSTAR 0xc0000082        /* long mode SYSCALL target */
-#define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */
-
-static spinlock_t multi_core_starting_lock = {1}; // 多核启动锁
-
-static uint32_t total_processor_num = 0;
-static int current_starting_cpu = 0;
-
-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
-
-void smp_init()
-{
-    spin_init(&multi_core_starting_lock); // 初始化多核启动锁
-#if ARCH(I386) || ARCH(X86_64)
-    // 设置多核启动时,要加载的页表
-    __APU_START_CR3 = (uint64_t)get_CR3();
-
-    // kdebug("processor num=%d", total_processor_num);
-    total_processor_num = rs_smp_get_cpus(__cpu_info);
-
-    // 将引导程序复制到物理地址0x20000处
-    memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start,
-           (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
-    io_mfence();
-
-
-    io_mfence();
-
-    io_mfence();
-    rs_ipi_send_smp_init();
-
-    kdebug("total_processor_num=%d", total_processor_num);
-   
-    int core_to_start = 0;
-    // total_processor_num = 3;
-    for (int i = 0; i < total_processor_num; ++i) // i从1开始,不初始化bsp
-    {
-        io_mfence();
-
-        // 跳过BSP
-        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 (__cpu_info[i].can_boot == false)
-        {
-            // --total_processor_num;
-            kdebug("processor %d cannot be enabled.", __cpu_info[i].core_id);
-            continue;
-        }
-        ++core_to_start;
-        // continue;
-        io_mfence();
-        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", __cpu_info[i].apic_id);
-        // 连续发送两次start-up IPI
-
-        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();
-    }
-    io_mfence();
-    while (num_cpu_started != (core_to_start + 1))
-        pause();
-
-    kinfo("Cleaning page table remapping...\n");
-
-    // 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射
-    rs_unmap_at_low_addr();
-    kinfo("Successfully cleaned page table remapping!\n");
-#endif
-    io_mfence();
-}
-
-/**
- * @brief AP处理器启动后执行的第一个函数
- *
- */
-void smp_ap_start_stage2()
-{
-
-    ksuccess("AP core %d successfully started!", current_starting_cpu);
-    io_mfence();
-    ++num_cpu_started;
-    io_mfence();
-#if ARCH(I386) || ARCH(X86_64)
-    rs_apic_init_ap();
-
-    // ============ 为ap处理器初始化IDLE进程 =============
-
-    barrier();
-
-    io_mfence();
-    spin_unlock_no_preempt(&multi_core_starting_lock);
-
-    rs_init_syscall_64();
-    
-    rs_init_current_core_sched();
-#endif
-
-    sti();
-    sched();
-
-    while (1)
-    {
-        // kdebug("123");
-        hlt();
-    }
-
-    while (1)
-    {
-        printk_color(BLACK, WHITE, "CPU:%d IDLE process.\n", rs_current_cpu_id());
-    }
-    while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
-        hlt();
-}
-
-/**
- * @brief 获取当前全部的cpu数目
- *
- * @return uint32_t
- */
-uint32_t smp_get_total_cpu()
-{
-    return num_cpu_started;
-}

+ 0 - 23
kernel/src/smp/smp.h

@@ -1,23 +0,0 @@
-#pragma once
-#include <common/glib.h>
-#include <common/stddef.h>
-#include <common/asm.h>
-
-#define MAX_SUPPORTED_PROCESSOR_NUM 1024    
-
-
-
-extern uchar _apu_boot_start[];
-extern uchar _apu_boot_end[];
-/**
- * @brief 初始化对称多核处理器
- *
- */
-void smp_init();
-
-extern int64_t rs_kick_cpu(uint32_t cpu_id);
-
-uint32_t smp_get_total_cpu();
-
-extern void set_current_core_tss(uint64_t stack_start, uint64_t ist0);
-extern void rs_load_current_core_tss();

+ 11 - 0
kernel/src/time/mod.rs

@@ -425,4 +425,15 @@ impl From<Duration> for smoltcp::time::Duration {
 pub trait TimeArch {
     /// Get CPU cycles (Read from register)
     fn get_cycles() -> usize;
+
+    /// Calculate expire cycles
+    ///
+    /// # Arguments
+    ///
+    /// - `ns` - The time to expire in nanoseconds
+    ///
+    /// # Returns
+    ///
+    /// The expire cycles
+    fn cal_expire_cycles(ns: usize) -> usize;
 }

+ 3 - 6
kernel/src/time/sleep.rs

@@ -6,7 +6,7 @@ use system_error::SystemError;
 use crate::{
     arch::{sched::sched, CurrentIrqArch, CurrentTimeArch},
     exception::InterruptArch,
-    include::bindings::bindings::{useconds_t, Cpu_tsc_freq},
+    include::bindings::bindings::useconds_t,
     process::ProcessManager,
     time::timekeeping::getnstimeofday,
 };
@@ -29,11 +29,8 @@ pub fn nanosleep(sleep_time: TimeSpec) -> Result<TimeSpec, SystemError> {
     }
     // 对于小于500us的时间,使用spin/rdtsc来进行定时
     if sleep_time.tv_nsec < 500000 && sleep_time.tv_sec == 0 {
-        let expired_tsc: u64 = unsafe {
-            CurrentTimeArch::get_cycles() as u64
-                + (sleep_time.tv_nsec as u64 * Cpu_tsc_freq) / 1000000000
-        };
-        while (CurrentTimeArch::get_cycles() as u64) < expired_tsc {
+        let expired_tsc: usize = CurrentTimeArch::cal_expire_cycles(sleep_time.tv_nsec as usize);
+        while CurrentTimeArch::get_cycles() < expired_tsc {
             spin_loop()
         }
         return Ok(TimeSpec {

+ 2 - 0
kernel/src/time/timer.rs

@@ -262,7 +262,9 @@ pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
 pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
     // kdebug!("schedule_timeout");
     if timeout == MAX_TIMEOUT {
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         ProcessManager::mark_sleep(true).ok();
+        drop(irq_guard);
         sched();
         return Ok(MAX_TIMEOUT);
     } else if timeout < 0 {