Browse Source

让riscv64能正常切换进程,并运行完所有的initcall (#721)

LoGin 11 months ago
parent
commit
9621ab16ef

+ 2 - 1
kernel/Cargo.toml

@@ -26,6 +26,7 @@ kvm = []
 # 运行时依赖项
 [dependencies]
 acpi = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/acpi-rs.git", rev = "fb69243dcf" }
+asm_macros = { path = "crates/asm_macros" }
 atomic_enum = "=0.2.0"
 bit_field = "=0.10"
 bitfield-struct = "=0.5.3"
@@ -62,7 +63,7 @@ x86_64 = "=0.14.10"
 
 # target为riscv64时,使用下面的依赖
 [target.'cfg(target_arch = "riscv64")'.dependencies]
-riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "bf771288c3", features = [ "s-mode" ] }
+riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "cc4d3ea82a", features = [ "s-mode" ] }
 sbi-rt = { version = "=0.0.3", features = ["legacy"] }
 
 

+ 8 - 0
kernel/crates/asm_macros/Cargo.toml

@@ -0,0 +1,8 @@
+[package]
+name = "asm_macros"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]

+ 7 - 0
kernel/crates/asm_macros/src/lib.rs

@@ -0,0 +1,7 @@
+#![no_std]
+
+#[cfg(target_arch = "x86_64")]
+pub mod x86_64;
+
+#[cfg(target_arch = "riscv64")]
+pub mod riscv64;

+ 72 - 0
kernel/crates/asm_macros/src/riscv64/context.rs

@@ -0,0 +1,72 @@
+/// 保存x6-x31寄存器
+#[macro_export]
+macro_rules! save_from_x6_to_x31 {
+    () => {
+        concat!(
+            "
+            sd x6, {off_t1}(sp)
+            sd x7, {off_t2}(sp)
+            sd x8, {off_s0}(sp)
+            sd x9, {off_s1}(sp)
+            sd x10, {off_a0}(sp)
+            sd x11, {off_a1}(sp)
+            sd x12, {off_a2}(sp)
+            sd x13, {off_a3}(sp)
+            sd x14, {off_a4}(sp)
+            sd x15, {off_a5}(sp)
+            sd x16, {off_a6}(sp)
+            sd x17, {off_a7}(sp)
+            sd x18, {off_s2}(sp)
+            sd x19, {off_s3}(sp)
+            sd x20, {off_s4}(sp)
+            sd x21, {off_s5}(sp)
+            sd x22, {off_s6}(sp)
+            sd x23, {off_s7}(sp)
+            sd x24, {off_s8}(sp)
+            sd x25, {off_s9}(sp)
+            sd x26, {off_s10}(sp)
+            sd x27, {off_s11}(sp)
+            sd x28, {off_t3}(sp)
+            sd x29, {off_t4}(sp)
+            sd x30, {off_t5}(sp)
+            sd x31, {off_t6}(sp)
+
+        "
+        )
+    };
+}
+
+#[macro_export]
+macro_rules! restore_from_x6_to_x31 {
+    () => {
+        concat!("
+        
+            ld x6, {off_t1}(sp)
+            ld x7, {off_t2}(sp)
+            ld x8, {off_s0}(sp)
+            ld x9, {off_s1}(sp)
+            ld x10, {off_a0}(sp)
+            ld x11, {off_a1}(sp)
+            ld x12, {off_a2}(sp)
+            ld x13, {off_a3}(sp)
+            ld x14, {off_a4}(sp)
+            ld x15, {off_a5}(sp)
+            ld x16, {off_a6}(sp)
+            ld x17, {off_a7}(sp)
+            ld x18, {off_s2}(sp)
+            ld x19, {off_s3}(sp)
+            ld x20, {off_s4}(sp)
+            ld x21, {off_s5}(sp)
+            ld x22, {off_s6}(sp)
+            ld x23, {off_s7}(sp)
+            ld x24, {off_s8}(sp)
+            ld x25, {off_s9}(sp)
+            ld x26, {off_s10}(sp)
+            ld x27, {off_s11}(sp)
+            ld x28, {off_t3}(sp)
+            ld x29, {off_t4}(sp)
+            ld x30, {off_t5}(sp)
+            ld x31, {off_t6}(sp)
+        ")
+    };
+}

+ 1 - 0
kernel/crates/asm_macros/src/riscv64/mod.rs

@@ -0,0 +1 @@
+pub mod context;

+ 1 - 0
kernel/crates/asm_macros/src/x86_64/mod.rs

@@ -0,0 +1 @@
+

+ 1 - 71
kernel/src/arch/riscv64/interrupt/entry.rs

@@ -5,80 +5,10 @@ use crate::arch::{
     cpu::LocalContext,
     interrupt::TrapFrame,
 };
+use asm_macros::{restore_from_x6_to_x31, save_from_x6_to_x31};
 use core::arch::asm;
 use kdepends::memoffset::offset_of;
 
-/// 保存x6-x31寄存器
-macro_rules! save_from_x6_to_x31 {
-    () => {
-        concat!(
-            "
-            sd x6, {off_t1}(sp)
-            sd x7, {off_t2}(sp)
-            sd x8, {off_s0}(sp)
-            sd x9, {off_s1}(sp)
-            sd x10, {off_a0}(sp)
-            sd x11, {off_a1}(sp)
-            sd x12, {off_a2}(sp)
-            sd x13, {off_a3}(sp)
-            sd x14, {off_a4}(sp)
-            sd x15, {off_a5}(sp)
-            sd x16, {off_a6}(sp)
-            sd x17, {off_a7}(sp)
-            sd x18, {off_s2}(sp)
-            sd x19, {off_s3}(sp)
-            sd x20, {off_s4}(sp)
-            sd x21, {off_s5}(sp)
-            sd x22, {off_s6}(sp)
-            sd x23, {off_s7}(sp)
-            sd x24, {off_s8}(sp)
-            sd x25, {off_s9}(sp)
-            sd x26, {off_s10}(sp)
-            sd x27, {off_s11}(sp)
-            sd x28, {off_t3}(sp)
-            sd x29, {off_t4}(sp)
-            sd x30, {off_t5}(sp)
-            sd x31, {off_t6}(sp)
-
-        "
-        )
-    };
-}
-
-macro_rules! restore_from_x6_to_x31 {
-    () => {
-        concat!("
-        
-            ld x6, {off_t1}(sp)
-            ld x7, {off_t2}(sp)
-            ld x8, {off_s0}(sp)
-            ld x9, {off_s1}(sp)
-            ld x10, {off_a0}(sp)
-            ld x11, {off_a1}(sp)
-            ld x12, {off_a2}(sp)
-            ld x13, {off_a3}(sp)
-            ld x14, {off_a4}(sp)
-            ld x15, {off_a5}(sp)
-            ld x16, {off_a6}(sp)
-            ld x17, {off_a7}(sp)
-            ld x18, {off_s2}(sp)
-            ld x19, {off_s3}(sp)
-            ld x20, {off_s4}(sp)
-            ld x21, {off_s5}(sp)
-            ld x22, {off_s6}(sp)
-            ld x23, {off_s7}(sp)
-            ld x24, {off_s8}(sp)
-            ld x25, {off_s9}(sp)
-            ld x26, {off_s10}(sp)
-            ld x27, {off_s11}(sp)
-            ld x28, {off_t3}(sp)
-            ld x29, {off_t4}(sp)
-            ld x30, {off_t5}(sp)
-            ld x31, {off_t6}(sp)
-        ")
-    };
-}
-
 /// Riscv64中断处理入口
 #[naked]
 #[no_mangle]

+ 1 - 2
kernel/src/arch/riscv64/interrupt/handle.rs

@@ -6,8 +6,7 @@ use core::hint::spin_loop;
 use system_error::SystemError;
 
 use crate::{
-    arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq,
-    exception::HardwareIrqNumber, kdebug, kerror,
+    arch::syscall::syscall_handler, driver::irqchip::riscv_intc::riscv_intc_irq, kdebug, kerror,
 };
 
 use super::TrapFrame;

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

@@ -35,6 +35,7 @@ impl InterruptArch for RiscV64InterruptArch {
 
     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
         let sie = riscv::register::sstatus::read().sie();
+        riscv::register::sstatus::clear_sie();
         IrqFlagsGuard::new(IrqFlags::new(sie.into()))
     }
 

+ 0 - 2
kernel/src/arch/riscv64/mm/mod.rs

@@ -1,4 +1,3 @@
-use acpi::address;
 use riscv::register::satp;
 use sbi_rt::{HartMask, SbiRet};
 use system_error::SystemError;
@@ -6,7 +5,6 @@ use system_error::SystemError;
 use crate::{
     arch::MMArch,
     driver::open_firmware::fdt::open_firmware_fdt_driver,
-    kdebug,
     libs::spinlock::SpinLock,
     mm::{
         allocator::{

+ 2 - 2
kernel/src/arch/riscv64/msi.rs

@@ -3,7 +3,7 @@ use crate::driver::pci::pci_irq::TriggerMode;
 /// @brief 获得MSI Message Address
 /// @param processor 目标CPU ID号
 /// @return MSI Message Address
-pub fn arch_msi_message_address(processor: u16) -> u32 {
+pub fn arch_msi_message_address(_processor: u16) -> u32 {
     unimplemented!("riscv64::arch_msi_message_address()")
 }
 /// @brief 获得MSI Message Data
@@ -11,6 +11,6 @@ pub fn arch_msi_message_address(processor: u16) -> u32 {
 /// @param processor 目标CPU ID号
 /// @param trigger  申请中断的触发模式,MSI默认为边沿触发
 /// @return MSI Message Address
-pub fn arch_msi_message_data(vector: u16, _processor: u16, trigger: TriggerMode) -> u32 {
+pub fn arch_msi_message_data(_vector: u16, _processor: u16, _trigger: TriggerMode) -> u32 {
     unimplemented!("riscv64::arch_msi_message_data()")
 }

+ 6 - 6
kernel/src/arch/riscv64/pio.rs

@@ -4,32 +4,32 @@ pub struct RiscV64PortIOArch;
 
 impl PortIOArch for RiscV64PortIOArch {
     #[inline(always)]
-    unsafe fn in8(port: u16) -> u8 {
+    unsafe fn in8(_port: u16) -> u8 {
         unimplemented!("RiscV64PortIOArch::in8")
     }
 
     #[inline(always)]
-    unsafe fn in16(port: u16) -> u16 {
+    unsafe fn in16(_port: u16) -> u16 {
         unimplemented!("RiscV64PortIOArch::in16")
     }
 
     #[inline(always)]
-    unsafe fn in32(port: u16) -> u32 {
+    unsafe fn in32(_port: u16) -> u32 {
         unimplemented!("RiscV64PortIOArch::in32")
     }
 
     #[inline(always)]
-    unsafe fn out8(port: u16, data: u8) {
+    unsafe fn out8(_port: u16, _data: u8) {
         unimplemented!("RiscV64PortIOArch::out8")
     }
 
     #[inline(always)]
-    unsafe fn out16(port: u16, data: u16) {
+    unsafe fn out16(_port: u16, _data: u16) {
         unimplemented!("RiscV64PortIOArch::out16")
     }
 
     #[inline(always)]
-    unsafe fn out32(port: u16, data: u32) {
+    unsafe fn out32(_port: u16, _data: u32) {
         unimplemented!("RiscV64PortIOArch::out32")
     }
 }

+ 1 - 3
kernel/src/arch/riscv64/process/idle.rs

@@ -9,9 +9,7 @@ impl ProcessManager {
     pub fn arch_idle_func() -> ! {
         loop {
             if CurrentIrqArch::is_irq_enabled() {
-                unsafe {
-                    riscv::asm::wfi();
-                }
+                riscv::asm::wfi();
             } else {
                 kBUG!("Idle process should not be scheduled with IRQs disabled.");
                 spin_loop();

+ 62 - 7
kernel/src/arch/riscv64/process/kthread.rs

@@ -1,15 +1,18 @@
-use alloc::sync::Arc;
-use riscv::register::sstatus::SPP;
-use system_error::SystemError;
+use core::arch::asm;
 
 use crate::{
-    arch::interrupt::TrapFrame,
+    arch::{asm::csr::CSR_SSTATUS, interrupt::TrapFrame},
     process::{
         fork::CloneFlags,
-        kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
+        kthread::{kernel_thread_bootstrap_stage2, KernelThreadCreateInfo, KernelThreadMechanism},
         Pid, ProcessManager,
     },
 };
+use alloc::sync::Arc;
+use asm_macros::restore_from_x6_to_x31;
+use kdepends::memoffset::offset_of;
+use riscv::register::sstatus::SPP;
+use system_error::SystemError;
 
 impl KernelThreadMechanism {
     /// 伪造trapframe,创建内核线程
@@ -27,7 +30,7 @@ impl KernelThreadMechanism {
             KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
 
         let mut frame = TrapFrame::new();
-        frame.a0 = create_info as usize;
+        frame.a2 = create_info as usize;
 
         // 使能中断
         frame.status.update_sie(true);
@@ -58,8 +61,60 @@ impl KernelThreadMechanism {
 // pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
 //     todo!()
 // }
+#[naked]
 pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
     // 这个函数要是naked的,只是因为现在还没有实现,而naked func不能打`unimplemented!()`
     // 所以先写成了普通函数
-    unimplemented!("kernel_thread_bootstrap_stage1")
+    asm!(concat!(
+        "
+            ld x3, {off_gp}(sp)
+            ld x5, {off_t0}(sp)
+
+        ",
+        restore_from_x6_to_x31!(),
+
+        "
+            ld a0, {off_status}(sp)
+            csrw {csr_status}, a0
+            mv a0, a2
+            j {stage2_func}
+        "
+    ),
+        csr_status = const CSR_SSTATUS,
+        off_status = const offset_of!(TrapFrame, status),
+        off_gp = const offset_of!(TrapFrame, gp),
+        off_t0 = const offset_of!(TrapFrame, t0),
+        off_t1 = const offset_of!(TrapFrame, t1),
+        off_t2 = const offset_of!(TrapFrame, t2),
+        off_s0 = const offset_of!(TrapFrame, s0),
+        off_s1 = const offset_of!(TrapFrame, s1),
+        off_a0 = const offset_of!(TrapFrame, a0),
+        off_a1 = const offset_of!(TrapFrame, a1),
+        off_a2 = const offset_of!(TrapFrame, a2),
+        off_a3 = const offset_of!(TrapFrame, a3),
+        off_a4 = const offset_of!(TrapFrame, a4),
+        off_a5 = const offset_of!(TrapFrame, a5),
+        off_a6 = const offset_of!(TrapFrame, a6),
+        off_a7 = const offset_of!(TrapFrame, a7),
+        off_s2 = const offset_of!(TrapFrame, s2),
+        off_s3 = const offset_of!(TrapFrame, s3),
+        off_s4 = const offset_of!(TrapFrame, s4),
+        off_s5 = const offset_of!(TrapFrame, s5),
+        off_s6 = const offset_of!(TrapFrame, s6),
+        off_s7 = const offset_of!(TrapFrame, s7),
+        off_s8 = const offset_of!(TrapFrame, s8),
+        off_s9 = const offset_of!(TrapFrame, s9),
+        off_s10 = const offset_of!(TrapFrame, s10),
+        off_s11 = const offset_of!(TrapFrame, s11),
+        off_t3 = const offset_of!(TrapFrame, t3),
+        off_t4 = const offset_of!(TrapFrame, t4),
+        off_t5 = const offset_of!(TrapFrame, t5),
+        off_t6 = const offset_of!(TrapFrame, t6),
+        stage2_func = sym jump_to_stage2,
+        options(noreturn),
+    );
+}
+
+fn jump_to_stage2(ptr: *const KernelThreadCreateInfo) {
+    unsafe { kernel_thread_bootstrap_stage2(ptr) };
 }

+ 23 - 3
kernel/src/arch/riscv64/process/mod.rs

@@ -10,6 +10,7 @@ use core::{
     sync::atomic::{compiler_fence, Ordering},
 };
 use kdepends::memoffset::offset_of;
+use riscv::register::sstatus::Sstatus;
 use system_error::SystemError;
 
 use crate::{
@@ -133,16 +134,13 @@ impl ProcessManager {
             next.pid()
         );
         Self::switch_process_fpu(&prev, &next);
-        kdebug!("riscv switch process: after switch_process_fpu");
         Self::switch_local_context(&prev, &next);
-        kdebug!("riscv switch process: after switch_local_context");
 
         // 切换地址空间
         let next_addr_space = next.basic().user_vm().as_ref().unwrap().clone();
         compiler_fence(Ordering::SeqCst);
 
         next_addr_space.read().user_mapper.utable.make_current();
-        kdebug!("riscv switch process: after switch addr space");
         drop(next_addr_space);
         compiler_fence(Ordering::SeqCst);
 
@@ -206,6 +204,13 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
             sd s10, {off_s10}(a0)
             sd s11, {off_s11}(a0)
 
+            addi sp , sp, -8
+            sd a1, 0(sp)
+            csrr a0, sstatus
+            sd a0, {off_sstatus}(a1)
+            ld a1, 0(sp)
+            addi sp, sp, 8
+
 
             ld sp, {off_sp}(a1)
             ld s0, {off_s0}(a1)
@@ -220,19 +225,32 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
             ld s9, {off_s9}(a1)
             ld s10, {off_s10}(a1)
             ld s11, {off_s11}(a1)
+
+            // save a1 temporarily
+            addi sp , sp, -8
+            sd a1, 0(sp)
+
+            ld a0, {off_sstatus}(a1)
+            csrw sstatus, a0
             
             // 将ra设置为标签1,并跳转到before_switch_finish_hook
             la ra, 1f
             j {before_switch_finish_hook}
             
             1:
+
+            // restore a1
+            ld a1, 0(sp)
+            addi sp, sp, 8
             ld sp, {off_sp}(a1)
             ld ra, {off_ra}(a1)
+            
             ret
 
         "
     ), 
     off_ra = const(offset_of!(ArchPCBInfo, ra)),
+    off_sstatus = const(offset_of!(ArchPCBInfo, sstatus)),
     off_sp = const(offset_of!(ArchPCBInfo, ksp)),
     off_s0 = const(offset_of!(ArchPCBInfo, s0)),
     off_s1 = const(offset_of!(ArchPCBInfo, s1)),
@@ -308,6 +326,7 @@ pub struct ArchPCBInfo {
     s9: usize,
     s10: usize,
     s11: usize,
+    sstatus: Sstatus,
 
     fp_state: FpDExtState,
     local_context: LocalContext,
@@ -340,6 +359,7 @@ impl ArchPCBInfo {
             s9: 0,
             s10: 0,
             s11: 0,
+            sstatus: Sstatus::from(0),
             fp_state: FpDExtState::new(),
             local_context: LocalContext::new(ProcessorId::new(0)),
         }

+ 1 - 1
kernel/src/driver/clocksource/timer_riscv.rs

@@ -60,7 +60,7 @@ pub fn riscv_sbi_timer_init_local() {
 
     if unsafe { INTERVAL_CNT } == 0 {
         // todo: 将来正式实现时,需要除以HZ
-        let new = riscv_time_base_freq();
+        let new = riscv_time_base_freq() / 3;
         if new == 0 {
             panic!("riscv_sbi_timer_init: failed to get timebase-frequency");
         }

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

@@ -1,3 +1,4 @@
 pub mod ps2_dev;
+#[cfg(target_arch = "x86_64")]
 pub mod ps2_mouse;
 pub mod serio;

+ 10 - 10
kernel/src/driver/input/serio/i8042/mod.rs

@@ -3,16 +3,13 @@ use system_error::SystemError;
 use unified_init::macros::unified_init;
 
 use crate::{
-    driver::{
-        base::{
-            device::{device_manager, Device},
-            kobject::KObject,
-            platform::{
-                platform_device::{platform_device_manager, PlatformDevice},
-                platform_driver::{platform_driver_manager, PlatformDriver},
-            },
+    driver::base::{
+        device::{device_manager, Device},
+        kobject::KObject,
+        platform::{
+            platform_device::{platform_device_manager, PlatformDevice},
+            platform_driver::{platform_driver_manager, PlatformDriver},
         },
-        input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init,
     },
     init::initcall::INITCALL_DEVICE,
 };
@@ -70,6 +67,9 @@ pub fn i8042_setup_aux() -> Result<(), SystemError> {
     )));
     serio_device_manager().register_port(aux_port.clone() as Arc<dyn SerioDevice>)?;
 
-    rs_ps2_mouse_device_init(aux_port.clone() as Arc<dyn KObject>)?;
+    #[cfg(target_arch = "x86_64")]
+    crate::driver::input::ps2_mouse::ps_mouse_device::rs_ps2_mouse_device_init(
+        aux_port.clone() as Arc<dyn KObject>
+    )?;
     Ok(())
 }

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

@@ -1 +1,2 @@
+#[cfg(target_arch = "x86_64")]
 pub mod ps2_keyboard;

+ 1 - 5
kernel/src/driver/serial/serial8250/mod.rs

@@ -526,10 +526,6 @@ pub fn send_to_default_serial8250_port(s: &[u8]) {
 
     #[cfg(target_arch = "riscv64")]
     {
-        if unsafe { INITIALIZED } {
-            todo!("riscv64: send_to_default_serial8250_port")
-        } else {
-            crate::arch::driver::sbi::console_putstr(s);
-        }
+        crate::arch::driver::sbi::console_putstr(s);
     }
 }

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

@@ -155,7 +155,6 @@ impl File {
             readdir_subdirs_name: SpinLock::new(Vec::default()),
             private_data: SpinLock::new(FilePrivateData::default()),
         };
-        // kdebug!("inode:{:?}",f.inode);
         f.inode.open(f.private_data.lock(), &mode)?;
 
         return Ok(f);

+ 1 - 0
kernel/src/mm/kernel_mapper.rs

@@ -124,6 +124,7 @@ impl KernelMapper {
             vaddr += MMArch::PAGE_SIZE;
             paddr += MMArch::PAGE_SIZE;
         }
+        compiler_fence(Ordering::SeqCst);
         return Ok(());
     }
 }

+ 0 - 6
kernel/src/sched/mod.rs

@@ -914,12 +914,6 @@ pub fn __schedule(sched_mod: SchedMode) {
 
         unsafe { ProcessManager::switch_process(prev, next) };
     } else {
-        kwarn!(
-            "!!!switch_process {} {:?} to self ",
-            prev.basic().name(),
-            prev.pid(),
-        );
-
         assert!(
             Arc::ptr_eq(&ProcessManager::current_pcb(), &prev),
             "{}",