Bladeren bron

riscv: 把内核编译target改为riscv64gc & 获取time csr的频率 & 修正浮点保存与恢复的汇编的问题 (#699)

* 1. 把内核编译target改为riscv64gc
2. fix: 修正浮点保存与恢复的汇编的问题

* riscv: 获取time csr的频率
LoGin 1 maand geleden
bovenliggende
commit
23ef2b33d1

+ 0 - 1
.gitignore

@@ -20,4 +20,3 @@ Cargo.lock
 .cache
 compile_commands.json
 /logs/
-.vscode

+ 1 - 1
.vscode/settings.json

@@ -152,7 +152,7 @@
         "./tools/Cargo.toml",
     
     ],
-    // "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
+    // "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
     "rust-analyzer.cargo.target": "x86_64-unknown-none",
     "rust-analyzer.check.overrideCommand": [
         "make",

+ 3 - 2
build-scripts/kernel_build/src/cfiles/arch/riscv64.rs

@@ -31,8 +31,9 @@ impl CFilesArch for RiscV64CFilesArch {
         // // c.flag("-march=rv64imafdc");
         // c.no_default_flags(true);
         c.flag("-mcmodel=medany");
-        c.flag("-mabi=lp64");
-        c.flag("-march=rv64imac");
+
+        c.flag("-mabi=lp64d");
+        c.flag("-march=rv64gc");
     }
 }
 

+ 2 - 0
build-scripts/kernel_build/src/lib.rs

@@ -1,3 +1,5 @@
+#![feature(cfg_target_abi)]
+
 #[macro_use]
 extern crate lazy_static;
 extern crate cc;

+ 1 - 1
docs/kernel/configuration/arch.md

@@ -9,7 +9,7 @@
 
 为了能支持vscode的调试功能,我们需要修改`.vscode/settings.json`文件的以下行:
 ```
-    "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf",
+    "rust-analyzer.cargo.target": "riscv64gc-unknown-none-elf",
     // "rust-analyzer.cargo.target": "x86_64-unknown-none",
 ```
 

+ 2 - 2
kernel/Makefile

@@ -6,7 +6,7 @@ include ./env.mk
 ifeq ($(ARCH), x86_64)
 	export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
 else ifeq ($(ARCH), riscv64)
-	export TARGET_JSON=arch/riscv64/riscv64imac-unknown-none-elf.json
+	export TARGET_JSON=riscv64gc-unknown-none-elf
 endif
 
 export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
@@ -38,7 +38,7 @@ check: ECHO
 ifeq ($(ARCH), x86_64)
 	@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
 else ifeq ($(ARCH), riscv64)
-	@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
+	@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON)
 endif
 
 test:

+ 1 - 1
kernel/env.mk

@@ -36,7 +36,7 @@ export GLOBAL_CFLAGS := -fno-builtin -fno-stack-protector -D $(CFLAGS_DEFINE_ARC
 ifeq ($(ARCH), x86_64)
 GLOBAL_CFLAGS += -mcmodel=large -m64
 else ifeq ($(ARCH), riscv64)
-GLOBAL_CFLAGS += -mcmodel=medany -march=rv64imac -mabi=lp64
+GLOBAL_CFLAGS += -mcmodel=medany -march=rv64gc -mabi=lp64d
 endif
 
 ifeq ($(DEBUG), DEBUG)

+ 1 - 1
kernel/src/Makefile

@@ -65,7 +65,7 @@ kernel: $(kernel_subdirs) kernel_rust
 
 __link_riscv64_kernel:
 	@echo "Linking kernel..."
-	$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64imac-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
+	$(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64gc-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax
 	$(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf
 	@rm kernel
 	$(MAKE) __dragon_stub PAYLOAD_ELF="$(shell pwd)/../../bin/kernel/kernel.elf"

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

@@ -3,7 +3,6 @@ use sbi_rt::HartMask;
 
 use crate::{
     init::boot_params,
-    kdebug,
     mm::percpu::{PerCpu, PerCpuVar},
     smp::cpu::{ProcessorId, SmpCpuManager},
 };

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

@@ -1 +1,2 @@
+pub mod of;
 pub mod sbi;

+ 40 - 0
kernel/src/arch/riscv64/driver/of.rs

@@ -0,0 +1,40 @@
+use system_error::SystemError;
+
+use crate::{
+    driver::open_firmware::fdt::OpenFirmwareFdtDriver,
+    init::boot_params,
+    libs::align::page_align_up,
+    mm::{mmio_buddy::mmio_pool, MemoryManagementArch, PhysAddr},
+};
+
+impl OpenFirmwareFdtDriver {
+    #[allow(dead_code)]
+    pub unsafe fn map_fdt(&self) -> Result<(), SystemError> {
+        let bp_guard = boot_params().read();
+        let fdt_size = bp_guard.arch.fdt_size;
+        let fdt_paddr = bp_guard.arch.fdt_paddr;
+
+        let offset = fdt_paddr.data() & crate::arch::MMArch::PAGE_OFFSET_MASK;
+        let map_size = page_align_up(fdt_size + offset);
+        let map_paddr = PhysAddr::new(fdt_paddr.data() & crate::arch::MMArch::PAGE_MASK);
+        // kdebug!(
+        //     "map_fdt paddr: {:?}, map_pa: {:?},fdt_size: {},  size: {:?}",
+        //     fdt_paddr,
+        //     map_paddr,
+        //     fdt_size,
+        //     map_size
+        // );
+        let mmio_guard = mmio_pool().create_mmio(map_size)?;
+
+        // drop the boot params guard in order to avoid deadlock
+        drop(bp_guard);
+        mmio_guard.map_phys(map_paddr, map_size)?;
+        let mut bp_guard = boot_params().write();
+        let vaddr = mmio_guard.vaddr() + offset;
+
+        self.set_fdt_map_guard(Some(mmio_guard));
+        bp_guard.arch.fdt_vaddr.replace(vaddr);
+
+        return Ok(());
+    }
+}

+ 6 - 2
kernel/src/arch/riscv64/init/mod.rs

@@ -18,6 +18,7 @@ pub struct ArchBootParams {
     /// 启动时的fdt物理地址
     pub fdt_paddr: PhysAddr,
     pub fdt_vaddr: Option<VirtAddr>,
+    pub fdt_size: usize,
 
     pub boot_hartid: ProcessorId,
 }
@@ -26,6 +27,7 @@ impl ArchBootParams {
     pub const DEFAULT: Self = ArchBootParams {
         fdt_paddr: PhysAddr::new(0),
         fdt_vaddr: None,
+        fdt_size: 0,
         boot_hartid: ProcessorId::new(0),
     };
 
@@ -103,8 +105,12 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
     let hartid = unsafe { BOOT_HARTID };
     let fdt_paddr = unsafe { BOOT_FDT_PADDR };
 
+    let fdt =
+        unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
+
     let mut arch_boot_params_guard = boot_params().write();
     arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
+    arch_boot_params_guard.arch.fdt_size = fdt.total_size();
     arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
 
     drop(arch_boot_params_guard);
@@ -116,8 +122,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
     );
     mm_early_init();
 
-    let fdt =
-        unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
     print_node(fdt.find_node("/").unwrap(), 0);
 
     unsafe { parse_dtb() };

+ 23 - 7
kernel/src/arch/riscv64/interrupt/handle.rs

@@ -1,8 +1,11 @@
+//! 处理中断和异常
+//!
+//! 架构相关的处理逻辑参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/kernel/traps.c
 use core::hint::spin_loop;
 
 use system_error::SystemError;
 
-use crate::{kdebug, kerror};
+use crate::{arch::syscall::syscall_handler, kdebug, kerror};
 
 use super::TrapFrame;
 
@@ -136,11 +139,16 @@ fn do_trap_store_access_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemE
 }
 
 /// 处理环境调用异常 #8
-fn do_trap_user_env_call(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
-    kerror!("riscv64_do_irq: do_trap_user_env_call");
-    loop {
-        spin_loop();
+fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
+    if trap_frame.is_from_user() {
+        let syscall_num = trap_frame.a7;
+        trap_frame.epc += 4;
+        trap_frame.origin_a0 = trap_frame.a0;
+        syscall_handler(syscall_num, trap_frame);
+    } else {
+        panic!("do_trap_user_env_call: not from user mode")
     }
+    Ok(())
 }
 
 // 9-11 reserved
@@ -154,8 +162,16 @@ fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemErro
 }
 
 /// 处理页加载错误异常 #13
-fn do_trap_load_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
-    kerror!("riscv64_do_irq: do_trap_load_page_fault");
+fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
+    let vaddr = trap_frame.badaddr;
+    let cause = trap_frame.cause;
+    let epc = trap_frame.epc;
+    kerror!(
+        "riscv64_do_irq: do_trap_load_page_fault: epc: {epc:#x}, vaddr={:#x}, cause={:?}",
+        vaddr,
+        cause
+    );
+
     loop {
         spin_loop();
     }

+ 16 - 3
kernel/src/arch/riscv64/mm/mod.rs

@@ -5,6 +5,7 @@ use system_error::SystemError;
 
 use crate::{
     arch::MMArch,
+    driver::open_firmware::fdt::open_firmware_fdt_driver,
     kdebug,
     libs::spinlock::SpinLock,
     mm::{
@@ -13,7 +14,7 @@ use crate::{
             page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage, PhysPageFrame},
         },
         kernel_mapper::KernelMapper,
-        page::{PageEntry, PageFlags},
+        page::{PageEntry, PageFlags, PAGE_1G_SHIFT},
         ucontext::UserMapper,
         MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
     },
@@ -130,16 +131,28 @@ impl MemoryManagementArch for RiscV64MMArch {
 
     const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000);
 
-    /// 在距离sv39的顶端还有1G的位置,设置为FIXMAP的起始地址
-    const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
+    /// 在距离sv39的顶端还有64M的位置,设置为FIXMAP的起始地址
+    const FIXMAP_START_VADDR: VirtAddr = VirtAddr::new(0xffff_ffff_fc00_0000);
     /// 设置1MB的fixmap空间
     const FIXMAP_SIZE: usize = 256 * 4096;
 
+    /// 在距离sv39的顶端还有2G的位置,设置为MMIO空间的起始地址
+    const MMIO_BASE: VirtAddr = VirtAddr::new(0xffff_ffff_8000_0000);
+    /// 设置1g的MMIO空间
+    const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
+
     #[inline(never)]
     unsafe fn init() {
         riscv_mm_init().expect("init kernel memory management architecture failed");
     }
 
+    unsafe fn arch_post_init() {
+        // 映射fdt
+        open_firmware_fdt_driver()
+            .map_fdt()
+            .expect("openfirmware map fdt failed");
+    }
+
     unsafe fn invalidate_page(address: VirtAddr) {
         riscv::asm::sfence_vma(0, address.data());
     }

+ 95 - 135
kernel/src/arch/riscv64/process/mod.rs

@@ -23,10 +23,10 @@ use crate::{
     mm::VirtAddr,
     process::{
         fork::{CloneFlags, KernelCloneArgs},
-        KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
+        switch_finish_hook, KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager,
+        PROCESS_SWITCH_RESULT,
     },
     smp::cpu::ProcessorId,
-    syscall::Syscall,
 };
 
 use super::{
@@ -213,9 +213,9 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
             ld s10, {off_s10}(a1)
             ld s11, {off_s11}(a1)
             
-            // 将ra设置为标签1,并跳转到{switch_finish_hook}
+            // 将ra设置为标签1,并跳转到before_switch_finish_hook
             la ra, 1f
-            j {switch_finish_hook}
+            j {before_switch_finish_hook}
             
             1:
             ld sp, {off_sp}(a1)
@@ -238,10 +238,15 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
     off_s9 = const(offset_of!(ArchPCBInfo, s9)),
     off_s10 = const(offset_of!(ArchPCBInfo, s10)),
     off_s11 = const(offset_of!(ArchPCBInfo, s11)),
-    switch_finish_hook = sym crate::process::switch_finish_hook,
+    before_switch_finish_hook = sym before_switch_finish_hook,
     options(noreturn));
 }
 
+/// 在切换上下文完成后的钩子函数(必须在这里加一个跳转函数,否则会出现relocation truncated to fit: R_RISCV_JAL错误)
+unsafe extern "C" fn before_switch_finish_hook() {
+    switch_finish_hook();
+}
+
 impl ProcessControlBlock {
     /// 获取当前进程的pcb
     pub fn arch_current_pcb() -> Arc<Self> {
@@ -375,73 +380,50 @@ impl FpDExtState {
             asm!("frcsr {0}", lateout(reg) self.fcsr);
             asm!(concat!(
                     "
-                fsd f0, {0}
-                fsd f1, {1}
-                fsd f2, {2}
-                fsd f3, {3}
-                fsd f4, {4}
-                fsd f5, {5}
-                fsd f6, {6}
-                fsd f7, {7}
-                fsd f8, {8}
-                fsd f9, {9}
-                fsd f10, {10}
-                fsd f11, {11}
-                fsd f12, {12}
-                fsd f13, {13}
-                fsd f14, {14}
-                fsd f15, {15}
-                fsd f16, {16}
-                fsd f17, {17}
-                fsd f18, {18}
-                fsd f19, {19}
-                fsd f20, {20}
-                fsd f21, {21}
-                fsd f22, {22}
-                fsd f23, {23}
-                fsd f24, {24}
-                fsd f25, {25}
-                fsd f26, {26}
-                fsd f27, {27}
-                fsd f28, {28}
-                fsd f29, {29}
-                fsd f30, {30}
-                fsd f31, {31}
+                // 为原来的a0寄存器的值在堆栈上分配空间
+                addi sp, sp, -8
+                sd a0, 0(sp)
+                mv a0, {0}
+
+                fsd f0, 0(a0)
+                fsd f1, 8(a0)
+                fsd f2, 16(a0)
+                fsd f3, 24(a0)
+                fsd f4, 32(a0)
+                fsd f5, 40(a0)
+                fsd f6, 48(a0)
+                fsd f7, 56(a0)
+                fsd f8, 64(a0)
+                fsd f9, 72(a0)
+                fsd f10, 80(a0)
+                fsd f11, 88(a0)
+                fsd f12, 96(a0)
+                fsd f13, 104(a0)
+                fsd f14, 112(a0)
+                fsd f15, 120(a0)
+                fsd f16, 128(a0)
+                fsd f17, 136(a0)
+                fsd f18, 144(a0)
+                fsd f19, 152(a0)
+                fsd f20, 160(a0)
+                fsd f21, 168(a0)
+                fsd f22, 176(a0)
+                fsd f23, 184(a0)
+                fsd f24, 192(a0)
+                fsd f25, 200(a0)
+                fsd f26, 208(a0)
+                fsd f27, 216(a0)
+                fsd f28, 224(a0)
+                fsd f29, 232(a0)
+                fsd f30, 240(a0)
+                fsd f31, 248(a0)
+
+                // 恢复a0寄存器的值
+                ld a0, 0(sp)
+                addi sp, sp, 8
                 "
                 ),
-                lateout(reg) self.f[0],
-                lateout(reg) self.f[1],
-                lateout(reg) self.f[2],
-                lateout(reg) self.f[3],
-                lateout(reg) self.f[4],
-                lateout(reg) self.f[5],
-                lateout(reg) self.f[6],
-                lateout(reg) self.f[7],
-                lateout(reg) self.f[8],
-                lateout(reg) self.f[9],
-                lateout(reg) self.f[10],
-                lateout(reg) self.f[11],
-                lateout(reg) self.f[12],
-                lateout(reg) self.f[13],
-                lateout(reg) self.f[14],
-                lateout(reg) self.f[15],
-                lateout(reg) self.f[16],
-                lateout(reg) self.f[17],
-                lateout(reg) self.f[18],
-                lateout(reg) self.f[19],
-                lateout(reg) self.f[20],
-                lateout(reg) self.f[21],
-                lateout(reg) self.f[22],
-                lateout(reg) self.f[23],
-                lateout(reg) self.f[24],
-                lateout(reg) self.f[25],
-                lateout(reg) self.f[26],
-                lateout(reg) self.f[27],
-                lateout(reg) self.f[28],
-                lateout(reg) self.f[29],
-                lateout(reg) self.f[30],
-                lateout(reg) self.f[31],
-
+                in (reg) &self.f as *const _,
             );
             riscv::register::sstatus::set_fs(riscv::register::sstatus::FS::Off);
         }
@@ -457,72 +439,50 @@ impl FpDExtState {
             compiler_fence(Ordering::SeqCst);
             asm!(concat!(
                     "
-                fld f0, {0}
-                fld f1, {1}
-                fld f2, {2}
-                fld f3, {3}
-                fld f4, {4}
-                fld f5, {5}
-                fld f6, {6}
-                fld f7, {7}
-                fld f8, {8}
-                fld f9, {9}
-                fld f10, {10}
-                fld f11, {11}
-                fld f12, {12}
-                fld f13, {13}
-                fld f14, {14}
-                fld f15, {15}
-                fld f16, {16}
-                fld f17, {17}
-                fld f18, {18}
-                fld f19, {19}
-                fld f20, {20}
-                fld f21, {21}
-                fld f22, {22}
-                fld f23, {23}
-                fld f24, {24}
-                fld f25, {25}
-                fld f26, {26}
-                fld f27, {27}
-                fld f28, {28}
-                fld f29, {29}
-                fld f30, {30}
-                fld f31, {31}
-                "
+            // 为原来的a0寄存器的值在堆栈上分配空间
+            addi sp, sp, -8
+            sd a0, 0(sp)
+            mv a0, {0}
+
+            fld f0, 0(a0)
+            fld f1, 8(a0)
+            fld f2, 16(a0)
+            fld f3, 24(a0)
+            fld f4, 32(a0)
+            fld f5, 40(a0)
+            fld f6, 48(a0)
+            fld f7, 56(a0)
+            fld f8, 64(a0)
+            fld f9, 72(a0)
+            fld f10, 80(a0)
+            fld f11, 88(a0)
+            fld f12, 96(a0)
+            fld f13, 104(a0)
+            fld f14, 112(a0)
+            fld f15, 120(a0)
+            fld f16, 128(a0)
+            fld f17, 136(a0)
+            fld f18, 144(a0)
+            fld f19, 152(a0)
+            fld f20, 160(a0)
+            fld f21, 168(a0)
+            fld f22, 176(a0)
+            fld f23, 184(a0)
+            fld f24, 192(a0)
+            fld f25, 200(a0)
+            fld f26, 208(a0)
+            fld f27, 216(a0)
+            fld f28, 224(a0)
+            fld f29, 232(a0)
+            fld f30, 240(a0)
+            fld f31, 248(a0)
+
+            // 恢复a0寄存器的值
+            ld a0, 0(sp)
+            addi sp, sp, 8
+            "
                 ),
-                in(reg) self.f[0],
-                in(reg) self.f[1],
-                in(reg) self.f[2],
-                in(reg) self.f[3],
-                in(reg) self.f[4],
-                in(reg) self.f[5],
-                in(reg) self.f[6],
-                in(reg) self.f[7],
-                in(reg) self.f[8],
-                in(reg) self.f[9],
-                in(reg) self.f[10],
-                in(reg) self.f[11],
-                in(reg) self.f[12],
-                in(reg) self.f[13],
-                in(reg) self.f[14],
-                in(reg) self.f[15],
-                in(reg) self.f[16],
-                in(reg) self.f[17],
-                in(reg) self.f[18],
-                in(reg) self.f[19],
-                in(reg) self.f[20],
-                in(reg) self.f[21],
-                in(reg) self.f[22],
-                in(reg) self.f[23],
-                in(reg) self.f[24],
-                in(reg) self.f[25],
-                in(reg) self.f[26],
-                in(reg) self.f[27],
-                in(reg) self.f[28],
-                in(reg) self.f[29],
-                in(reg) self.f[30],
-                in(reg) self.f[31],
+                in (reg) &self.f as *const _,
             );
             compiler_fence(Ordering::SeqCst);
             asm!("fscsr {0}", in(reg) fcsr);

+ 0 - 18
kernel/src/arch/riscv64/riscv64imac-unknown-none-elf.json

@@ -1,18 +0,0 @@
-{
-  "arch": "riscv64",
-  "code-model": "medium",
-  "cpu": "generic-rv64",
-  "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
-  "eh-frame-header": false,
-  "emit-debug-gdb-scripts": false,
-  "features": "+m,+a,+c",
-  "is-builtin": false,
-  "linker": "rust-lld",
-  "linker-flavor": "ld.lld",
-  "llvm-target": "riscv64",
-  "max-atomic-width": 64,
-  "panic-strategy": "abort",
-  "relocation-model": "pic",
-  "position-independent-executables": true,
-  "target-pointer-width": "64"
-}

+ 26 - 4
kernel/src/arch/riscv64/syscall/mod.rs

@@ -2,7 +2,7 @@
 pub mod nr;
 use system_error::SystemError;
 
-use crate::exception::InterruptArch;
+use crate::{exception::InterruptArch, process::ProcessManager, syscall::Syscall};
 
 use super::{interrupt::TrapFrame, CurrentIrqArch};
 
@@ -11,10 +11,32 @@ pub fn arch_syscall_init() -> Result<(), SystemError> {
     return Ok(());
 }
 
-#[no_mangle]
-pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () {
+macro_rules! syscall_return {
+    ($val:expr, $regs:expr, $show:expr) => {{
+        let ret = $val;
+        $regs.a0 = ret;
+
+        if $show {
+            let pid = ProcessManager::current_pcb().pid();
+            crate::kdebug!("syscall return:pid={:?},ret= {:?}\n", pid, ret as isize);
+        }
+
+        unsafe {
+            CurrentIrqArch::interrupt_disable();
+        }
+        return;
+    }};
+}
+
+pub(super) fn syscall_handler(syscall_num: usize, frame: &mut TrapFrame) -> () {
     unsafe {
         CurrentIrqArch::interrupt_enable();
     }
-    unimplemented!("syscall_handler")
+
+    let args = [frame.a0, frame.a1, frame.a2, frame.a3, frame.a4, frame.a5];
+    syscall_return!(
+        Syscall::handle(syscall_num, &args, frame).unwrap_or_else(|e| e.to_posix_errno() as usize),
+        frame,
+        false
+    );
 }

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

@@ -1,20 +1,66 @@
-use crate::time::{clocksource::HZ, TimeArch};
+use crate::{
+    driver::open_firmware::fdt::open_firmware_fdt_driver,
+    kinfo,
+    time::{clocksource::HZ, TimeArch},
+};
 pub struct RiscV64TimeArch;
 
 /// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
 pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
 
+static mut TIME_FREQ: usize = 0;
+
+/// 获取CPU的time寄存器频率
+///
+/// todo: 支持从acpi中获取
+fn init_time_freq() {
+    let fdt = open_firmware_fdt_driver().fdt_ref();
+    if fdt.is_err() {
+        panic!("init_time_freq: failed to get fdt");
+    }
+    let fdt = fdt.unwrap();
+    let cpu_node = fdt.find_node("/cpus");
+    if cpu_node.is_none() {
+        panic!("init_time_freq: failed to find /cpus node");
+    }
+
+    let cpu_node = cpu_node.unwrap();
+    let time_freq = cpu_node
+        .property("timebase-frequency")
+        .map(|prop| prop.as_usize())
+        .flatten();
+    if time_freq.is_none() {
+        panic!("init_time_freq: failed to get timebase-frequency");
+    }
+
+    let time_freq: usize = time_freq.unwrap();
+    kinfo!("init_time_freq: timebase-frequency: {}", time_freq);
+    unsafe {
+        TIME_FREQ = time_freq;
+    }
+}
+
+pub fn time_init() {
+    // 初始化cpu time register频率
+    init_time_freq();
+}
+
 impl TimeArch for RiscV64TimeArch {
     fn get_cycles() -> usize {
-        riscv::register::cycle::read()
+        riscv::register::time::read()
     }
 
     fn cal_expire_cycles(ns: usize) -> usize {
-        todo!()
+        Self::get_cycles() + ns * unsafe { TIME_FREQ } / 1000000000
     }
+
     /// 将CPU的时钟周期数转换为纳秒
     #[inline(always)]
     fn cycles2ns(cycles: usize) -> usize {
-        todo!()
+        if unsafe { TIME_FREQ == 0 } {
+            return 0;
+        }
+
+        cycles * 1000000000 / unsafe { TIME_FREQ }
     }
 }

+ 4 - 1
kernel/src/arch/x86_64/mm/mod.rs

@@ -23,7 +23,7 @@ use crate::{
 };
 
 use crate::mm::kernel_mapper::KernelMapper;
-use crate::mm::page::{PageEntry, PageFlags};
+use crate::mm::page::{PageEntry, PageFlags, PAGE_1G_SHIFT};
 use crate::mm::{MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr};
 use crate::{kdebug, kinfo, kwarn};
 use system_error::SystemError;
@@ -122,6 +122,9 @@ impl MemoryManagementArch for X86_64MMArch {
     /// 设置FIXMAP区域大小为1M
     const FIXMAP_SIZE: usize = 256 * 4096;
 
+    const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
+    const MMIO_SIZE: usize = 1 << PAGE_1G_SHIFT;
+
     /// @brief 获取物理内存区域
     unsafe fn init() {
         extern "C" {

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

@@ -5,6 +5,10 @@ use super::driver::tsc::TSCManager;
 /// 这个是系统jiffies时钟源的固有频率(不是调频之后的)
 pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 1000000;
 
+pub fn time_init() {
+    // do nothing
+}
+
 pub struct X86_64TimeArch;
 
 impl TimeArch for X86_64TimeArch {

+ 36 - 8
kernel/src/driver/open_firmware/fdt.rs

@@ -9,12 +9,14 @@ use system_error::SystemError;
 use crate::{
     init::boot_params,
     libs::rwlock::RwLock,
-    mm::{memblock::mem_block_manager, PhysAddr},
+    mm::{memblock::mem_block_manager, mmio_buddy::MMIOSpaceGuard, PhysAddr},
 };
 
+static OPEN_FIRMWARE_FDT_DRIVER: OpenFirmwareFdtDriver = OpenFirmwareFdtDriver::new();
+
 #[inline(always)]
 pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
-    &OpenFirmwareFdtDriver
+    &OPEN_FIRMWARE_FDT_DRIVER
 }
 
 static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
@@ -40,22 +42,48 @@ impl FdtGlobalData {
     }
 }
 
-pub struct OpenFirmwareFdtDriver;
+#[allow(dead_code)]
+pub struct OpenFirmwareFdtDriver {
+    inner: RwLock<InnerOpenFirmwareFdtDriver>,
+}
+
+#[allow(dead_code)]
+pub struct InnerOpenFirmwareFdtDriver {
+    /// FDT自身映射的MMIO空间
+    fdt_map_guard: Option<MMIOSpaceGuard>,
+}
 
 impl OpenFirmwareFdtDriver {
+    const fn new() -> Self {
+        Self {
+            inner: RwLock::new(InnerOpenFirmwareFdtDriver {
+                fdt_map_guard: None,
+            }),
+        }
+    }
+
     #[allow(dead_code)]
     pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
+        let fdt = self.fdt_ref()?;
+        self.early_init_scan_nodes(&fdt);
+
+        return Ok(());
+    }
+
+    pub unsafe fn set_fdt_map_guard(&self, guard: Option<MMIOSpaceGuard>) {
+        self.inner.write().fdt_map_guard = guard;
+    }
+
+    /// 获取FDT的引用
+    pub fn fdt_ref(&self) -> Result<Fdt<'static>, SystemError> {
         let fdt_vaddr = boot_params().read().fdt().unwrap();
-        let fdt = unsafe {
+        let fdt: Fdt<'_> = unsafe {
             fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
                 kerror!("failed to parse fdt, err={:?}", e);
                 SystemError::EINVAL
             })
         }?;
-
-        self.early_init_scan_nodes(&fdt);
-
-        return Ok(());
+        Ok(fdt)
     }
 
     fn early_init_scan_nodes(&self, fdt: &Fdt) {

+ 2 - 0
kernel/src/init/init.rs

@@ -1,6 +1,7 @@
 use crate::{
     arch::{
         init::{early_setup_arch, setup_arch, setup_arch_post},
+        time::time_init,
         CurrentIrqArch, CurrentSMPArch, CurrentSchedArch,
     },
     driver::{base::init::driver_init, serial::serial_early_init, video::VideoRefreshManager},
@@ -70,6 +71,7 @@ fn do_start_kernel() {
     softirq_init().expect("softirq init failed");
     Syscall::init().expect("syscall init failed");
     timekeeping_init();
+    time_init();
     timer_init();
     kthread_init();
     clocksource_boot_finish();

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

@@ -58,6 +58,7 @@ pub unsafe fn mm_init() {
             Ordering::SeqCst,
         )
         .unwrap();
+    MMArch::arch_post_init();
     kinfo!("mm init done.");
 }
 

+ 33 - 25
kernel/src/mm/mmio_buddy.rs

@@ -1,8 +1,9 @@
 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
 use crate::mm::kernel_mapper::KernelMapper;
+use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
 use crate::process::ProcessManager;
 use crate::{
-    include::bindings::bindings::{PAGE_1G_SHIFT, PAGE_4K_SHIFT, PAGE_4K_SIZE},
+    include::bindings::bindings::PAGE_4K_SIZE,
     kdebug,
     mm::{MMArch, MemoryManagementArch},
 };
@@ -10,22 +11,19 @@ use crate::{kerror, kinfo, kwarn};
 use alloc::{collections::LinkedList, vec::Vec};
 use core::mem;
 use core::mem::MaybeUninit;
-use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
+use core::sync::atomic::{AtomicBool, Ordering};
 use system_error::SystemError;
 
 use super::page::PageFlags;
 use super::{PhysAddr, VirtAddr};
 
 // 最大的伙伴块的幂
-const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT;
+const MMIO_BUDDY_MAX_EXP: u32 = PAGE_1G_SHIFT as u32;
 // 最小的伙伴块的幂
-const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT;
+const MMIO_BUDDY_MIN_EXP: u32 = PAGE_4K_SHIFT as u32;
 // 内存池数组的范围
 const MMIO_BUDDY_REGION_COUNT: u32 = MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1;
 
-const MMIO_BASE: VirtAddr = VirtAddr::new(0xffffa10000000000);
-const MMIO_TOP: VirtAddr = VirtAddr::new(0xffffa20000000000);
-
 const PAGE_1G_SIZE: usize = 1 << 30;
 
 static mut __MMIO_POOL: Option<MmioBuddyMemPool> = None;
@@ -65,26 +63,35 @@ impl MmioBuddyMemPool {
         };
 
         let pool = MmioBuddyMemPool {
-            pool_start_addr: MMIO_BASE,
-            pool_size: MMIO_TOP - MMIO_BASE,
+            pool_start_addr: MMArch::MMIO_BASE,
+            pool_size: MMArch::MMIO_SIZE,
             free_regions,
         };
+
+        assert!(pool.pool_start_addr.data() % PAGE_1G_SIZE == 0);
         kdebug!("MMIO buddy pool init: created");
 
-        let cnt_1g_blocks = (MMIO_TOP - MMIO_BASE) >> 30;
-        let mut vaddr_base = MMIO_BASE;
-        kdebug!("total 1G blocks: {cnt_1g_blocks}");
-        for _i in 0..cnt_1g_blocks {
-            compiler_fence(Ordering::SeqCst);
-            match pool.give_back_block(vaddr_base, PAGE_1G_SHIFT) {
-                Ok(_) => {
-                    vaddr_base += PAGE_1G_SIZE;
-                }
-                Err(_) => {
+        let mut vaddr_base = MMArch::MMIO_BASE;
+        let mut remain_size = MMArch::MMIO_SIZE;
+        kdebug!(
+            "BASE: {:?}, TOP: {:?}, size: {:?}",
+            MMArch::MMIO_BASE,
+            MMArch::MMIO_TOP,
+            MMArch::MMIO_SIZE
+        );
+
+        for shift in (PAGE_4K_SHIFT..=PAGE_1G_SHIFT).rev() {
+            if remain_size & (1 << shift) != 0 {
+                let ok = pool.give_back_block(vaddr_base, shift as u32).is_ok();
+                if ok {
+                    vaddr_base += 1 << shift;
+                    remain_size -= 1 << shift;
+                } else {
                     panic!("MMIO buddy pool init failed");
                 }
             }
         }
+
         kdebug!("MMIO buddy pool init success");
         return pool;
     }
@@ -297,9 +304,9 @@ impl MmioBuddyMemPool {
     /// @return Ok(MmioBuddyAddrRegion)符合要求的内存块信息结构体。
     /// @return Err(MmioResult) 没有满足要求的内存块时,返回__query_addr_region的错误码。
     fn mmio_buddy_query_addr_region(&self, exp: u32) -> Result<MmioBuddyAddrRegion, MmioResult> {
-        let list_guard: &mut SpinLockGuard<MmioFreeRegionList> =
-            &mut self.free_regions[exp2index(exp)].lock();
-        match self.query_addr_region(exp, list_guard) {
+        let mut list_guard: SpinLockGuard<MmioFreeRegionList> =
+            self.free_regions[exp2index(exp)].lock();
+        match self.query_addr_region(exp, &mut list_guard) {
             Ok(ret) => return Ok(ret),
             Err(err) => {
                 kdebug!("mmio_buddy_query_addr_region failed");
@@ -487,9 +494,9 @@ impl MmioBuddyMemPool {
         let mut new_size = size;
         // 对齐要申请的空间大小
         // 如果要申请的空间大小小于4k,则分配4k
-        if size_exp < PAGE_4K_SHIFT {
+        if size_exp < PAGE_4K_SHIFT as u32 {
             new_size = PAGE_4K_SIZE as usize;
-            size_exp = PAGE_4K_SHIFT;
+            size_exp = PAGE_4K_SHIFT as u32;
         } else if (new_size & (!(1 << size_exp))) != 0 {
             // 向左对齐空间大小
             size_exp += 1;
@@ -630,7 +637,8 @@ impl MMIOSpaceGuard {
             "MMIO space vaddr must be aligned with size"
         );
         assert!(
-            vaddr.data() >= MMIO_BASE.data() && vaddr.data() + size <= MMIO_TOP.data(),
+            vaddr.data() >= MMArch::MMIO_BASE.data()
+                && vaddr.data() + size <= MMArch::MMIO_TOP.data(),
             "MMIO space must be in MMIO region"
         );
 

+ 10 - 0
kernel/src/mm/mod.rs

@@ -492,10 +492,20 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
     const FIXMAP_END_VADDR: VirtAddr =
         VirtAddr::new(Self::FIXMAP_START_VADDR.data() + Self::FIXMAP_SIZE);
 
+    /// MMIO虚拟空间的基地址
+    const MMIO_BASE: VirtAddr;
+    /// MMIO虚拟空间的大小
+    const MMIO_SIZE: usize;
+    /// MMIO虚拟空间的顶端地址(不包含)
+    const MMIO_TOP: VirtAddr = VirtAddr::new(Self::MMIO_BASE.data() + Self::MMIO_SIZE);
+
     /// @brief 用于初始化内存管理模块与架构相关的信息。
     /// 该函数应调用其他模块的接口,把可用内存区域添加到memblock,提供给BumpAllocator使用
     unsafe fn init();
 
+    /// 内存管理初始化完成后,调用该函数
+    unsafe fn arch_post_init() {}
+
     /// @brief 读取指定虚拟地址的值,并假设它是类型T的指针
     #[inline(always)]
     unsafe fn read<T>(address: VirtAddr) -> T {

+ 5 - 0
kernel/src/mm/page.rs

@@ -21,6 +21,11 @@ use super::{
     MemoryManagementArch, PageTableKind, PhysAddr, VirtAddr,
 };
 
+pub const PAGE_4K_SHIFT: usize = 12;
+#[allow(dead_code)]
+pub const PAGE_2M_SHIFT: usize = 21;
+pub const PAGE_1G_SHIFT: usize = 30;
+
 /// 全局物理页信息管理器
 pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
 

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

@@ -493,7 +493,8 @@ pub unsafe extern "sysv64" fn switch_finish_hook() {
     ProcessManager::switch_finish_hook();
 }
 #[cfg(target_arch = "riscv64")]
-pub unsafe extern "C" fn switch_finish_hook() {
+#[inline(always)]
+pub unsafe fn switch_finish_hook() {
     ProcessManager::switch_finish_hook();
 }
 

+ 8 - 11
kernel/src/sched/clock.rs

@@ -1,11 +1,6 @@
-/*
-    这个文件实现的是调度过程中设计到的时钟
-*/
-#[cfg(target_arch = "x86_64")]
-use crate::{
-    arch::{driver::tsc::TSCManager, CurrentTimeArch},
-    time::TimeArch,
-};
+//! 这个文件实现的是调度过程中涉及到的时钟
+//!
+use crate::{arch::CurrentTimeArch, time::TimeArch};
 
 pub struct SchedClock;
 
@@ -14,15 +9,17 @@ impl SchedClock {
     pub fn sched_clock_cpu(_cpu: usize) -> u64 {
         #[cfg(target_arch = "x86_64")]
         {
-            if TSCManager::cpu_khz() == 0 {
-                // TCS no init
+            if crate::arch::driver::tsc::TSCManager::cpu_khz() == 0 {
+                // TSC not calibrated yet
                 return 0;
             }
             return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
         }
 
         #[cfg(target_arch = "riscv64")]
-        todo!()
+        {
+            return CurrentTimeArch::cycles2ns(CurrentTimeArch::get_cycles()) as u64;
+        }
     }
 }