Эх сурвалжийг харах

feat(arch): impl interrupt's data structure

Heinz 8 сар өмнө
parent
commit
d0c35b8e01

+ 113 - 2
arch/Cargo.lock

@@ -6,35 +6,89 @@ version = 4
 name = "arch"
 version = "0.1.0"
 dependencies = [
- "bitflags",
+ "buddy_allocator",
  "cfg-if",
  "eonix_mm",
+ "intrusive_list",
+ "once_cell",
  "percpu-macros",
+ "riscv",
+ "sbi",
+ "spin",
+ "volatile",
 ]
 
+[[package]]
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
 [[package]]
 name = "bitflags"
 version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
+[[package]]
+name = "buddy_allocator"
+version = "0.1.0"
+dependencies = [
+ "eonix_mm",
+ "intrusive_list",
+]
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
+[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
+name = "embedded-hal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
+
 [[package]]
 name = "eonix_mm"
 version = "0.1.0"
 dependencies = [
- "intrusive_list",
+ "bitflags",
 ]
 
 [[package]]
 name = "intrusive_list"
 version = "0.1.0"
 
+[[package]]
+name = "lock_api"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
+
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
 [[package]]
 name = "percpu-macros"
 version = "0.1.0"
@@ -62,6 +116,57 @@ dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "riscv"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afa3cdbeccae4359f6839a00e8b77e5736caa200ba216caf38d24e4c16e2b586"
+dependencies = [
+ "critical-section",
+ "embedded-hal",
+ "paste",
+ "riscv-macros",
+ "riscv-pac",
+]
+
+[[package]]
+name = "riscv-macros"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8c4aa1ea1af6dcc83a61be12e8189f9b293c3ba5a487778a4cd89fb060fdbbc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "riscv-pac"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436"
+
+[[package]]
+name = "sbi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c64a569a412de4ad7b123f429e434751d74dd7ed25654af962b93c4d1cd584e"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "spin"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
+dependencies = [
+ "lock_api",
+]
+
 [[package]]
 name = "syn"
 version = "2.0.89"
@@ -78,3 +183,9 @@ name = "unicode-ident"
 version = "1.0.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+
+[[package]]
+name = "volatile"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af8ca9a5d4debca0633e697c88269395493cebf2e10db21ca2dbde37c1356452"

+ 50 - 0
arch/src/riscv64/config.rs

@@ -0,0 +1,50 @@
+/// mm
+pub mod mm {
+    pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8040_0000;
+    pub const ROOT_PAGE_TABLE_PFN: usize = ROOT_PAGE_TABLE_PHYS_ADDR >> 12;
+    pub const PAGE_TABLE_PHYS_END: usize = 0x8080_0000;
+    pub const PHYS_MAP_VIRT: usize = 0xFFFF_FF00_0000_0000;
+    pub const KIMAGE_PHYS_BASE: usize = 0x8020_0000;
+    pub const KIMAGE_VIRT_BASE: usize = 0xFFFF_FFFF_FFC0_0000;
+    pub const PAGE_SIZE: usize = 0x1000;
+    #[derive(Clone, Copy)]
+    pub enum PageSize {
+        _4KbPage = 4096,
+        _2MbPage = 2 * 1024 * 1024,
+        _1GbPage = 1 * 1024 * 1024 * 1024,
+    }
+}
+
+/// smp
+pub mod smp {
+    pub const MAX_HART: usize = 4;
+}
+
+pub mod platform {
+    pub mod virt {
+        pub const PLIC_BASE: usize = 0x0C00_0000;
+
+        pub const PLIC_ENABLE_PER_HART_OFFSET: usize = 0x80; // 每个 Hart使能块 0x80 字节 (128 字节)
+
+        pub const PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET: usize = 0x1000; // 每个 Hart/上下文块 0x1000 字节 (4KB)
+
+        pub const PLIC_PRIORITY_OFFSET: usize = 0x0000_0000;
+        pub const PLIC_PENDING_OFFSET: usize = 0x0000_1000;
+        pub const PLIC_ENABLE_OFFSET: usize = 0x0000_2000; // Varies by context and mode (M/S/U)
+        pub const PLIC_THRESHOLD_OFFSET: usize = 0x0020_0000; // Varies by context and mode (M/S/U)
+        pub const PLIC_CLAIM_COMPLETE_OFFSET: usize = 0x0020_0004; // Varies by context and mode (M/S/U)
+
+        // PLIC Context IDs for S-mode (assuming hart 0's S-mode context is 1, hart 1's is 3, etc.)
+        // A common pattern is: context_id = hart_id * 2 + 1 (for S-mode)
+        pub const PLIC_S_MODE_CONTEXT_STRIDE: usize = 2;
+
+        // CLINT (Core Local Interruptor) memory-mapped registers
+        // Base address for CLINT on QEMU virt platform
+        pub const CLINT_BASE: usize = 0x200_0000;
+        pub const CLINT_MSIP_OFFSET: usize = 0x0000;      // Machine-mode Software Interrupt Pending (MSIP)
+        pub const CLINT_MTIMECMP_OFFSET: usize = 0x4000;  // Machine-mode Timer Compare (MTIMECMP)
+        pub const CLINT_MTIME_OFFSET: usize = 0xBFF8;
+        pub const CPU_FREQ_HZ: u64 = 10_000_000;
+    }
+}
+

+ 4 - 2
arch/src/riscv64/entry.rs

@@ -4,9 +4,10 @@ use core::{
     sync::atomic::AtomicUsize,
 };
 use intrusive_list::{container_of, Link};
+use super::config::mm::*;
 use super::mm::*;
 use buddy_allocator::{BuddyAllocator, BuddyRawPage};
-use riscv::register::satp;
+use riscv::{asm::sfence_vma_all, register::satp};
 use eonix_mm::{
     address::{Addr as _, PAddr, VAddr, VRange},
     page_table::{PageAttribute, PagingMode, RawAttribute, PTE as _},
@@ -190,6 +191,7 @@ fn setup_page_tables() {
     unsafe {
         satp::set(satp::Mode::Sv48, 0, PFN::from(page_table.addr()).into());
     }
+    sfence_vma_all();
 }
 
 extern "C" {
@@ -200,7 +202,7 @@ extern "C" {
 #[naked]
 #[no_mangle]
 #[link_section = ".text.entry"]
-unsafe extern "C" fn _start() -> ! {
+unsafe extern "C" fn _start(hart_id: usize, dtb_addr: usize) -> ! {
     naked_asm!(
         "la sp, {stack_top}",
         // TODO: set up page table, somewhere may be wrong

+ 62 - 0
arch/src/riscv64/interrupt/clint.rs

@@ -0,0 +1,62 @@
+use super::super::config::platform::virt::*;
+use core::ptr;
+
+use sbi::{
+    ipi::send_ipi,
+    timer::set_timer,
+    HartMask,
+    SbiError
+};
+use riscv::register::mie;
+
+/// CLINT (Core Local Interruptor) driver
+/// This struct now owns the base address and hart_id.
+pub struct ClintDriver {
+    base_addr: usize,
+    hart_id: usize,
+}
+
+impl ClintDriver {
+    pub fn new(base_addr: usize, hart_id: usize) -> Self {
+        let driver = ClintDriver { base_addr, hart_id };
+
+        driver.clear_soft_interrupt_pending(hart_id);
+
+        // Enable Supervisor-mode Software Interrupts (SSIE)
+        // and Supervisor-mode Timer Interrupts (STIE) in the `mie` CSR.
+        unsafe {
+            mie::set_ssoft(); // Enable S-mode Software Interrupts
+            mie::set_stimer(); // Enable S-mode Timer Interrupts
+        }
+
+        driver
+    }
+
+    /// Reads the current value of the global MTIME (Machine Timer) counter.
+    pub fn get_time(&self) -> u64 {
+        unsafe {
+            // MTIME is a 64-bit counter at CLINT_BASE + CLINT_MTIME_OFFSET
+            ptr::read_volatile((self.base_addr + CLINT_MTIME_OFFSET) as *mut u64)
+        }
+    }
+
+    /// Sets the next timer interrupt trigger point using SBI.
+    pub fn set_timer(&self, time_value: u64) -> Result<(), SbiError> {
+        set_timer(time_value)
+    }
+
+    /// Sends an Inter-Processor Interrupt (IPI) to the specified Hart(s).
+    pub fn send_ipi(&self, hart_id_mask: usize) -> Result<(), SbiError> {
+        // This utilizes the SBI `send_ipi` call.
+        send_ipi(HartMask::from(hart_id_mask))
+    }
+
+    /// Clears the software interrupt pending bit for the specified Hart.
+    pub fn clear_soft_interrupt_pending(&self, hart_id: usize) {
+        unsafe {
+            // MSIP registers are typically located at CLINT_BASE + 4 * hart_id.
+            // Writing 0 to the register clears the pending bit.
+            ptr::write_volatile((self.base_addr + CLINT_MSIP_OFFSET + hart_id * 4) as *mut u32, 0);
+        }
+    }
+}

+ 186 - 0
arch/src/riscv64/interrupt/mod.rs

@@ -0,0 +1,186 @@
+mod plic;
+mod clint;
+
+pub use plic::*;
+pub use clint::*;
+
+/// TODO:
+/// 一开始的中断汇编
+
+use riscv::register::sstatus::{self, Sstatus};
+use sbi::SbiError;
+
+use super::platform::virt::*;
+
+/// Floating-point registers context.
+#[repr(C)]
+#[derive(Debug, Clone, Copy, Default)]
+pub struct FpuRegisters {
+    pub f: [u64; 32],
+    pub fcsr: u32,
+}
+
+/// Saved CPU context when a trap (interrupt or exception) occurs on RISC-V 64.
+#[repr(C)]
+#[derive(Debug, Clone, Copy, Default)]
+pub struct TrapContext {
+    pub x: [usize; 32],
+
+    // CSRs
+    pub sstatus: usize, // sstatus CSR value. Contains privilege mode, interrupt enable, FPU state.
+    pub sepc: usize,    // sepc (Supervisor Exception Program Counter). Program counter at trap.
+    pub scause: usize,  // scause (Supervisor Cause). Describes the cause of the trap.
+    pub stval: usize,   // stval (Supervisor Trap Value). Contains faulting address for exceptions.
+    pub satp: usize,    // satp (Supervisor Address Translation and Protection). Page table base.
+
+    // may need to save
+    // pub sscratch: usize, // sscratch (Supervisor Scratch).
+
+    // FPU
+    // pub fpu_regs: FpuRegisters,
+}
+
+impl TrapContext {
+    pub fn set_return_value(&mut self, value: usize) {
+        // a0, x10
+        self.x[10] = value;
+    }
+
+    pub fn set_return_address(&mut self, addr: usize, user: bool) {
+        self.sepc = addr; // 设置 Supervisor Exception Program Counter
+
+        // if user==true,set SPP to U-mode (0)
+        // if user==false, set SPP to S-mode (1)
+        if user {
+            self.sstatus &= !(1 << 8); // clear SPP bit
+        } else {
+            self.sstatus |= 1 << 8;  // set SPP bit
+        }
+    }
+
+    pub fn set_stack_pointer(&mut self, sp: usize, _user: bool) {
+        self.x[2] = sp;
+    }
+
+    pub fn set_interrupt_enabled(&mut self, enabled: bool) {
+        // S mode Previous Interrupt Enable (SPIE)
+        if enabled {
+            self.sstatus |= 1 << 5;
+        } else {
+            self.sstatus &= !(1 << 5);
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct IrqState(usize);
+
+impl IrqState {
+    #[inline]
+    pub fn save() -> Self {
+        let sstatus_val = sstatus::read().bits();
+
+        unsafe {
+            sstatus::clear_sie();
+        }
+
+        IrqState(sstatus_val)
+    }
+
+    #[inline]
+    pub fn restore(self) {
+        let Self(state) = self;
+        unsafe {
+            sstatus::write(Sstatus::from_bits(state));
+        }
+    }
+
+    #[inline]
+    pub fn was_enabled(&self) -> bool {
+        (self.0 & (1 << 1)) != 0
+    }
+}
+
+#[inline]
+pub fn disable_interrupts() {
+    unsafe {
+        sstatus::clear_sie();
+    }
+}
+
+#[inline]
+pub fn enable_interrupts() {
+    unsafe {
+        sstatus::set_sie();
+    }
+}
+
+/// Architecture-specific interrupt control block.
+pub struct InterruptControl {
+    hart_id: usize,
+    plic: PlicDriver,
+    clint: ClintDriver,
+}
+
+impl InterruptControl {
+    /// # Safety
+    /// should be called only once.
+    pub(crate) fn new(hart_id: usize) -> Self {
+        // Initialize PLICDriver for this Hart
+        let plic = PlicDriver::new(PLIC_BASE, hart_id);
+
+        // Initialize ClintDriver for this Hart
+        let clint = ClintDriver::new(CLINT_BASE, hart_id);
+
+        Self {
+            hart_id,
+            plic: plic,
+            clint: clint,
+        }
+    }
+
+    /// Configures the CLINT timer for a periodic interrupt.
+    ///
+    /// # Arguments
+    /// * `interval_us`: The desired interval between timer interrupts in microseconds.
+    pub fn setup_timer(&self, interval_us: u64) {
+        let current_time = self.clint.get_time();
+        // Calculate ticks per microsecond based on CPU_FREQ_HZ
+        let ticks_per_us = CPU_FREQ_HZ / 1_000_000;
+        let ticks = interval_us * ticks_per_us;
+
+        let next_timer_at = current_time.checked_add(ticks).unwrap_or(u64::MAX);
+
+        if let Err(e) = self.clint.set_timer(next_timer_at) {
+            panic!("Failed to set CLINT timer: {:?}", e);
+        }
+    }
+
+    /// Sends an Inter-Processor Interrupt (IPI) to target Harts.
+    pub fn send_ipi(&self, target_hart_mask: usize) -> Result<(), SbiError> {
+        self.clint.send_ipi(target_hart_mask)
+    }
+
+    /// Handles the "End Of Interrupt" (EOI) for the most recently claimed
+    /// external interrupt.
+    pub fn end_of_external_interrupt(&self, irq_id: u32) {
+        self.plic.complete_interrupt(irq_id);
+    }
+
+    /// Clears the pending software interrupt for the current Hart.
+    pub fn clear_soft_interrupt_pending(&self) {
+        self.clint.clear_soft_interrupt_pending(self.hart_id);
+    }
+
+    pub fn plic_enable_interrupt(&self, irq_id: u32) {
+        self.plic.enable_interrupt(irq_id);
+    }
+
+    pub fn plic_set_priority(&self, irq_id: u32, priority: u32) {
+        self.plic.set_priority(irq_id, priority);
+    }
+
+    pub fn plic_claim_interrupt(&self) -> u32 {
+        self.plic.claim_interrupt()
+    }
+}

+ 137 - 0
arch/src/riscv64/interrupt/plic.rs

@@ -0,0 +1,137 @@
+use core::ptr::{read_volatile, write_volatile};
+
+use super::super::config::platform::virt::*;
+
+use riscv::register::mie;
+
+pub struct PlicDriver {
+    base_addr: usize,
+    hart_id: usize,
+}
+
+impl PlicDriver {
+    pub fn new(base_addr: usize, hart_id: usize) -> Self {
+        let driver = PlicDriver { base_addr, hart_id };
+
+        let s_context_id = driver.s_context_id();
+
+        driver.set_priority_threshold(0);
+
+        let enable_reg_base_for_context = driver.enable_addr(s_context_id);
+        // PLIC enable bits are grouped into 32-bit registers.
+        // Assuming 32 registers for up to 1024 IRQs, but 32 is common for a few hundred.
+        for i in 0..(driver.max_irq_num() / 32 + 1) {
+            let reg_addr = (enable_reg_base_for_context as usize + (i as usize) * 4) as *mut u32;
+            unsafe {
+                (reg_addr as *mut u32).write_volatile(0);
+            }
+        }
+
+        unsafe {
+            mie::set_sext();
+        }
+
+        driver.set_priority(10, 1);
+        driver.enable_interrupt(10);
+
+        // TODO: may need more set_priority
+        // driver.set_priority(UART_IRQ_ID, 1);
+        // driver.enable_interrupt(UART_IRQ_ID);
+        // driver.set_priority(VIRTIO_BLOCK_IRQ_ID, 1);
+        // driver.enable_interrupt(VIRTIO_BLOCK_IRQ_ID);
+
+        driver
+    }
+
+    fn s_context_id(&self) -> usize {
+        self.hart_id * PLIC_S_MODE_CONTEXT_STRIDE + 1
+    }
+
+    fn priority_addr(&self, irq_id: u32) -> *mut u32 {
+        (self.base_addr + PLIC_PRIORITY_OFFSET + (irq_id as usize) * 4) as *mut u32
+    }
+
+    fn pending_addr(&self) -> *mut u32 {
+        (self.base_addr + PLIC_PENDING_OFFSET) as *mut u32
+    }
+
+    fn enable_addr(&self, context_id: usize) -> *mut u32 {
+        // PLIC enable bits are typically organized as 32-bit banks.
+        // The offset for each context's enable registers.
+        // A common stride for context enable blocks is 0x80 (128 bytes).
+        (self.base_addr + PLIC_ENABLE_OFFSET + context_id * PLIC_ENABLE_PER_HART_OFFSET) as *mut u32
+    }
+
+    fn threshold_addr(&self, context_id: usize) -> *mut u32 {
+        // A common stride for context threshold/claim/complete registers is 0x1000 (4KB).
+        (self.base_addr + PLIC_THRESHOLD_OFFSET + context_id * PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET) as *mut u32
+    }
+
+    fn claim_complete_addr(&self, context_id: usize) -> *mut u32 {
+        (self.base_addr + PLIC_CLAIM_COMPLETE_OFFSET + context_id * PLIC_THRESHOLD_CLAIM_COMPLETE_PER_HART_OFFSET) as *mut u32
+    }
+
+    pub fn set_priority(&self, irq_id: u32, priority: u32) {
+        unsafe {
+            write_volatile(self.priority_addr(irq_id), priority);
+        }
+    }
+
+    pub fn get_priority(&self, irq_id: u32) -> u32 {
+        unsafe { read_volatile(self.priority_addr(irq_id)) }
+    }
+
+    pub fn enable_interrupt(&self, irq_id: u32) {
+        let context_id = self.s_context_id();
+        let enable_reg_offset_in_bank = (irq_id / 32) as usize * 4;
+        let bit_index_in_reg = irq_id % 32;
+
+        let enable_reg_addr = (self.enable_addr(context_id) as usize + enable_reg_offset_in_bank) as *mut u32;
+        let bit_mask = 1 << bit_index_in_reg;
+        unsafe {
+            let old = read_volatile(enable_reg_addr);
+            write_volatile(enable_reg_addr, old | bit_mask);
+        }
+    }
+
+    pub fn disable_interrupt(&self, irq_id: u32) {
+        let context_id = self.s_context_id();
+        let enable_reg_offset_in_bank = (irq_id / 32) as usize * 4;
+        let bit_index_in_reg = irq_id % 32;
+
+        let enable_reg_addr = (self.enable_addr(context_id) as usize + enable_reg_offset_in_bank) as *mut u32;
+        let bit_mask = 1 << bit_index_in_reg;
+        unsafe {
+            let old = read_volatile(enable_reg_addr);
+            write_volatile(enable_reg_addr, old & !bit_mask);
+        }
+    }
+
+    pub fn set_priority_threshold(&self, threshold: u32) {
+        let context_id = self.s_context_id();
+        unsafe {
+            write_volatile(self.threshold_addr(context_id), threshold);
+        }
+    }
+
+    pub fn get_priority_threshold(&self) -> u32 {
+        let context_id = self.s_context_id();
+        unsafe { read_volatile(self.threshold_addr(context_id)) }
+    }
+
+    pub fn claim_interrupt(&self) -> u32 {
+        let context_id = self.s_context_id();
+        unsafe { read_volatile(self.claim_complete_addr(context_id)) }
+    }
+
+    pub fn complete_interrupt(&self, irq_id: u32) {
+        let context_id = self.s_context_id();
+        unsafe {
+            write_volatile(self.claim_complete_addr(context_id), irq_id);
+        }
+    }
+
+    pub fn max_irq_num(&self) -> u32 {
+        127
+    }
+}

+ 9 - 13
arch/src/riscv64/mm.rs

@@ -6,21 +6,10 @@ use eonix_mm::{
     },
     paging::{PageBlock, PFN},
 };
+use riscv::{asm::sfence_vma_all, register::satp};
 
-#[derive(Clone, Copy)]
-pub enum PageSize {
-    _4KbPage = 4096,
-    _2MbPage = 2 * 1024 * 1024,
-    _1GbPage = 1 * 1024 * 1024 * 1024,
-}
+use super::config::mm::ROOT_PAGE_TABLE_PFN;
 
-pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8040_0000;
-pub const ROOT_PAGE_TABLE_PFN: usize = ROOT_PAGE_TABLE_PHYS_ADDR >> 12;
-pub const PAGE_TABLE_PHYS_END: usize = 0x8080_0000;
-pub const PHYS_MAP_VIRT: usize = 0xFFFF_FF00_0000_0000;
-pub const KIMAGE_PHYS_BASE: usize = 0x8020_0000;
-pub const KIMAGE_VIRT_BASE: usize = 0xFFFF_FFFF_FFC0_0000;
-pub const PAGE_SIZE: usize = 0x1000;
 pub const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PFN);
 
 pub const PA_V: u64 = 0b1 << 0;
@@ -224,3 +213,10 @@ impl RawAttribute for PageAttribute64 {
 }
 
 pub type DefaultPagingMode = PagingModeSv48;
+
+pub fn setup_kernel_page_table() {
+    unsafe {
+        satp::set(satp::Mode::Sv48, 0, PFN::from(ROOT_PAGE_TABLE_PFN).into());
+    }
+    sfence_vma_all();
+}

+ 6 - 0
arch/src/riscv64/mod.rs

@@ -4,6 +4,9 @@ mod context;
 mod console;
 mod io;
 mod fence;
+mod config;
+mod init;
+mod interrupt;
 
 pub use self::mm::*;
 pub use self::entry::*;
@@ -11,3 +14,6 @@ pub use self::context::*;
 pub use self::console::*;
 pub use self::io::*;
 pub use self::fence::*;
+pub use self::config::*;
+pub use self::init::*;
+pub use self::interrupt::*;