Explorar o código

refactor(arch): refactor riscv64's bootstrap

Heinz hai 8 meses
pai
achega
b364127dac

+ 2 - 1
.cargo/config.toml

@@ -1,5 +1,6 @@
 [build]
-target = 'x86_64-unknown-none.json'
+# target = 'x86_64-unknown-none.json'
+target = "riscv64gc-unknown-none-elf"
 target-dir = 'build'
 
 [unstable]

+ 84 - 0
Cargo.lock

@@ -15,9 +15,14 @@ dependencies = [
 name = "arch"
 version = "0.1.0"
 dependencies = [
+ "buddy_allocator",
  "cfg-if",
  "eonix_mm",
+ "intrusive_list",
  "percpu-macros",
+ "riscv",
+ "sbi",
+ "spin",
 ]
 
 [[package]]
@@ -90,12 +95,24 @@ dependencies = [
  "libloading",
 ]
 
+[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
 [[package]]
 name = "either"
 version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
 
+[[package]]
+name = "embedded-hal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
+
 [[package]]
 name = "eonix_log"
 version = "0.1.0"
@@ -204,6 +221,16 @@ dependencies = [
  "windows-targets",
 ]
 
+[[package]]
+name = "lock_api"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
 [[package]]
 name = "log"
 version = "0.4.22"
@@ -241,6 +268,12 @@ dependencies = [
  "minimal-lexical",
 ]
 
+[[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"
@@ -315,18 +348,69 @@ version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
 
+[[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 = "rustc-hash"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
+[[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 = "shlex"
 version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
+[[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"

+ 5 - 0
arch/Cargo.toml

@@ -6,4 +6,9 @@ edition = "2021"
 [dependencies]
 eonix_mm = { path = "../crates/eonix_mm" }
 percpu-macros = { path = "./percpu-macros" }
+buddy_allocator = { path = "../crates/buddy_allocator" }
+intrusive_list = { path = "../crates/intrusive_list" }
 cfg-if = "1.0"
+sbi = "0.3.0"
+riscv = { version = "0.13.0", features = ["s-mode"] }
+spin = "0.10.0"

+ 0 - 2
arch/src/lib.rs

@@ -1,8 +1,6 @@
 #![no_std]
 #![feature(naked_functions)]
 
-// for dev
-mod riscv64;
 
 cfg_if::cfg_if! {
     if #[cfg(target_arch = "x86_64")] {

+ 0 - 26
arch/src/riscv64/entry.S

@@ -1,26 +0,0 @@
-    .section .text.entry
-    .global _start
-_start:
-    la sp, stack_top
-
-    la a0, BSS_START
-    la a1, BSS_END
-// clear bss section
-.Lclear_bss_loop:
-    bge a0, a1, .Lclear_bss_done
-    sw x0, (a0)
-    addi a0, a0, 4
-    j .Lclear_bss_loop
-.Lclear_bss_done:
-    // jump to kernel entry point
-    call start
-.Lhang:
-    wfi
-    j .Lhang
-
-    .section .bss.stack
-    .globl stack_bottom
-stack_bottom:
-    .space 4096 * 16
-    .globl stack_top
-stack_top:

+ 167 - 175
arch/src/riscv64/entry.rs

@@ -1,202 +1,196 @@
-use core::{arch::{asm, naked_asm}, ptr};
-use super::{mm::*, PAGE_SIZE};
-
-pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8030_0000;
-pub const KERNEL_PHYS_BASE: usize = 0x8000_0000;
-pub const KIMAGE_VIRT_BASE: usize = 0xFFFF_FFFF_FFC0_0000;
+use core::{
+    arch::naked_asm,
+    ptr::NonNull,
+    sync::atomic::AtomicUsize,
+};
+use intrusive_list::{container_of, Link};
+use super::mm::*;
+use buddy_allocator::{BuddyAllocator, BuddyRawPage};
+use riscv::register::satp;
+use eonix_mm::{
+    address::{Addr as _, PAddr, VAddr, VRange},
+    page_table::{PageAttribute, RawAttribute, PTE as _},
+    paging::{Page, PageAccess, PageAlloc, PageBlock, RawPage as RawPageTrait, PFN},
+};
+use spin::Mutex;
+
+const ROOT_PAGE_TABLE_PFN: usize = ROOT_PAGE_TABLE_PHYS_ADDR >> 12;
 
 #[link_section = ".bss.stack"]
 static mut BOOT_STACK: [u8; 4096 * 16] = [0; 4096 * 16];
 
-#[link_section = ".data.root_page_tables"]
-static mut ROOT_PAGE_TABLES: [PTE64; 512] = [PTE64(0); 512];
+static mut PAGES: [RawPage; 1024] = [const { RawPage::new() }; 1024];
+
+fn page(index: usize) -> &'static mut RawPage {
+    let page = unsafe { PAGES.as_mut_ptr().add(index) };
+    unsafe { &mut *page }
+}
 
-#[link_section = ".data.boot_page_tables_lvl"]
-#[used]
-static mut LEVEL1_IDENTITY_TABLE: [PTE64; 512] = [PTE64(0); 512];
+#[derive(Clone, Copy)]
+struct RawPageHandle(usize);
 
-#[link_section = ".data.boot_page_tables_lvl"]
-#[used]
-static mut LEVEL1_KERNEL_TABLE: [PTE64; 512] = [PTE64(0); 512];
+impl From<PFN> for RawPageHandle {
+    fn from(pfn: PFN) -> Self {
+        assert!(usize::from(pfn) - ROOT_PAGE_TABLE_PFN < 1024, "PFN out of range");
 
-#[link_section = ".data.boot_page_tables_lvl"]
-#[used]
-static mut LEVEL0_KERNEL_TEXT_TABLE: [PTE64; 512] = [PTE64(0); 512];
+        Self(usize::from(pfn) - ROOT_PAGE_TABLE_PFN)
+    }
+}
+
+impl From<RawPageHandle> for PFN {
+    fn from(raw_page: RawPageHandle) -> Self {
+        PFN::from(raw_page.0 + ROOT_PAGE_TABLE_PFN)
+    }
+}
 
-#[link_section = ".data.boot_page_tables_lvl"]
-#[used]
-static mut LEVEL0_KERNEL_RODATA_TABLE: [PTE64; 512] = [PTE64(0); 512];
+impl RawPageTrait for RawPageHandle {
+    fn order(&self) -> u32 {
+        page(self.0).order
+    }
 
-#[link_section = ".data.boot_page_tables_lvl"]
-#[used]
-static mut LEVEL0_KERNEL_DATA_TABLE: [PTE64; 512] = [PTE64(0); 512];
+    fn refcount(&self) -> &AtomicUsize {
+        &page(self.0).refcount
+    }
 
-#[inline]
-fn phys_to_ppn(phys_addr: usize) -> u64 {
-    (phys_addr >> 12) as u64
+    fn is_present(&self) -> bool {
+        self.0 < 1024
+    }
 }
 
-#[inline]
-fn virt_to_vpn_idx(virt_addr: usize, level: u8) -> usize {
-    match level {
-        2 => (virt_addr >> 30) & 0x1FF, // VPN[2] bits 38-30 (9 bits)
-        1 => (virt_addr >> 21) & 0x1FF, // VPN[1] bits 29-21 (9 bits)
-        0 => (virt_addr >> 12) & 0x1FF, // VPN[0] bits 20-12 (9 bits)
-        _ => 0,
+impl BuddyRawPage for RawPageHandle {
+    unsafe fn from_link(link: &mut Link) -> Self {
+        let page = container_of!(link, RawPage, link);
+        let page_index = page.as_ptr().offset_from_unsigned(PAGES.as_ptr());
+        assert!(page_index < 1024, "Page index out of range");
+
+        Self(page_index)
+    }
+
+    unsafe fn get_link(&self) -> &mut Link {
+        &mut page(self.0).link
+    }
+
+    fn set_order(&self, order: u32) {
+        page(self.0).order = order;
+    }
+
+    fn is_buddy(&self) -> bool {
+        page(self.0).buddy
+    }
+
+    fn is_free(&self) -> bool {
+        page(self.0).free
+    }
+
+    fn set_buddy(&self) {
+        page(self.0).buddy = true;
+    }
+
+    fn set_free(&self) {
+        page(self.0).free = true;
+    }
+
+    fn clear_buddy(&self) {
+        page(self.0).buddy = false;
+    }
+
+    fn clear_free(&self) {
+        page(self.0).free = false;
     }
 }
 
-fn fill_pte(page_table_entry: &mut PTE64, phys_addr: usize, flags: u64) {
-    let ppn = phys_to_ppn(phys_addr);
-    *page_table_entry = PTE64(ppn << 10 | flags); // PPN 10-53
+struct RawPage {
+    link: Link,
+    free: bool,
+    buddy: bool,
+    order: u32,
+    refcount: AtomicUsize,
 }
 
-fn setup_page_tables() {
-    extern "C" {
-        static TEXT_START: usize;
-        static TEXT_END: usize;
-        static RODATA_START: usize;
-        static RODATA_END: usize;
-        static DATA_START: usize;
-        static DATA_END: usize;
+impl RawPage {
+    const fn new() -> Self {
+        Self {
+            link: Link::new(),
+            free: false,
+            buddy: false,
+            order: 0,
+            refcount: AtomicUsize::new(0),
+        }
     }
-    unsafe {
+}
 
-        // 1. clear page table
-        let root_page_tables_phys = ROOT_PAGE_TABLES.as_mut_ptr() as usize;
-        let total_page_tables_size = (LEVEL0_KERNEL_DATA_TABLE.as_mut_ptr() as usize + PAGE_SIZE) - root_page_tables_phys;
-        ptr::write_bytes(root_page_tables_phys as *mut u8, 0, total_page_tables_size);
-
-        // 2. Identity Mapping
-        // Level 2 (BOOT_PAGE_TABLES) -> Level 1 (LEVEL1_IDENTITY_TABLE) -> 2MB Huge Pages
-        fill_pte(
-            &mut ROOT_PAGE_TABLES[0],
-            LEVEL1_IDENTITY_TABLE.as_ptr() as usize,
-            PA_V
-        );
-
-        // LEVEL1_IDENTITY_TABLE (Level 1)
-        // KERNEL_PHYS_BASE 1GB
-        let identity_map_start_phys = KERNEL_PHYS_BASE;
-        let identity_map_size = LEVEL2_PAGE_SIZE;
-
-        let mut current_phys_addr = identity_map_start_phys;
-        let end_phys_addr = identity_map_start_phys + identity_map_size;
-
-        while current_phys_addr < end_phys_addr {
-            let pte_idx_lvl1 = virt_to_vpn_idx(current_phys_addr, 1);
-            fill_pte(
-                &mut LEVEL1_IDENTITY_TABLE[pte_idx_lvl1],
-                current_phys_addr, // 2MB
-                PA_KERNEL_RWX
-            );
-            current_phys_addr += LEVEL1_PAGE_SIZE;
-        }
+struct DirectPageAccess;
 
-        // 3. Kernel Space Mapping
-        let kimage_vpn2_idx = virt_to_vpn_idx(KIMAGE_VIRT_BASE, 2);
-
-        // ROOT_PAGE_TABLES (Level 2) -> LEVEL1_KERNEL_TABLE
-        fill_pte(
-            &mut ROOT_PAGE_TABLES[kimage_vpn2_idx],
-            LEVEL1_KERNEL_TABLE.as_ptr() as usize,
-            PA_V
-        );
-
-        let get_phys_addr = |virt_addr: usize, virt_base: usize, phys_base: usize| {
-            phys_base + (virt_addr - virt_base)
-        };
-
-        // .text
-        let text_virt_start = TEXT_START;
-        let text_phys_start = get_phys_addr(TEXT_START, KIMAGE_VIRT_BASE, KERNEL_PHYS_BASE);
-        let text_size = TEXT_END - TEXT_START;
-        let text_vpn1_idx = virt_to_vpn_idx(text_virt_start, 1);
-        
-        fill_pte(
-            &mut LEVEL1_KERNEL_TABLE[text_vpn1_idx],
-            LEVEL0_KERNEL_TEXT_TABLE.as_ptr() as usize,
-            PA_V
-        );
-        
-        let mut current_virt = text_virt_start;
-        let mut current_phys = text_phys_start;
-        while current_virt < text_virt_start + text_size {
-            let pte_idx_lvl0 = virt_to_vpn_idx(current_virt, 0);
-            fill_pte(
-                &mut LEVEL0_KERNEL_TEXT_TABLE[pte_idx_lvl0],
-                current_phys,
-                PA_KERNEL_RWX
-            );
-            current_virt += LEVEL0_PAGE_SIZE;
-            current_phys += LEVEL0_PAGE_SIZE;
-        }
+impl PageAccess for DirectPageAccess {
+    unsafe fn get_ptr_for_pfn(pfn: PFN) -> NonNull<PageBlock> {
+        unsafe { NonNull::new_unchecked(PAddr::from(pfn).addr() as *mut _) }
+    }
+}
 
-        // .rodata
-        let rodata_virt_start = RODATA_START;
-        let rodata_phys_start = get_phys_addr(RODATA_START, KIMAGE_VIRT_BASE, KERNEL_PHYS_BASE);
-        let rodata_size = RODATA_END - RODATA_START;
-        let rodata_vpn1_idx = virt_to_vpn_idx(rodata_virt_start, 1);
-        
-        if rodata_vpn1_idx != text_vpn1_idx {
-            fill_pte(
-                &mut LEVEL1_KERNEL_TABLE[rodata_vpn1_idx],
-                LEVEL0_KERNEL_RODATA_TABLE.as_ptr() as usize,
-                PA_V
-            );
-        }
-        
-        current_virt = rodata_virt_start;
-        current_phys = rodata_phys_start;
-        while current_virt < rodata_virt_start + rodata_size {
-            let pte_idx_lvl0 = virt_to_vpn_idx(current_virt, 0);
-            fill_pte(
-                &mut LEVEL0_KERNEL_RODATA_TABLE[pte_idx_lvl0],
-                current_phys,
-                PA_KERNEL_RO
-            );
-            current_virt += LEVEL0_PAGE_SIZE;
-            current_phys += LEVEL0_PAGE_SIZE;
-        }
+static BUDDY: Mutex<BuddyAllocator<RawPageHandle>> = Mutex::new(BuddyAllocator::new());
 
-        // .data 
-        let data_virt_start = DATA_START;
-        let data_phys_start = get_phys_addr(DATA_START, KIMAGE_VIRT_BASE, KERNEL_PHYS_BASE);
-        let data_size = DATA_END - DATA_START;
-        let data_vpn1_idx = virt_to_vpn_idx(data_virt_start, 1);
-
-        if data_vpn1_idx != text_vpn1_idx && data_vpn1_idx != rodata_vpn1_idx {
-            fill_pte(
-                &mut LEVEL1_KERNEL_TABLE[data_vpn1_idx],
-                LEVEL0_KERNEL_DATA_TABLE.as_ptr() as usize,
-                PA_V
-            );
-        }
-        
-        current_virt = data_virt_start;
-        current_phys = data_phys_start;
-        while current_virt < data_virt_start + data_size {
-            let pte_idx_lvl0 = virt_to_vpn_idx(current_virt, 0);
-            fill_pte(
-                &mut LEVEL0_KERNEL_DATA_TABLE[pte_idx_lvl0],
-                current_phys,
-                PA_KERNEL_RW
-            );
-            current_virt += LEVEL0_PAGE_SIZE;
-            current_phys += LEVEL0_PAGE_SIZE;
-        }
+#[derive(Clone)]
+struct BuddyPageAlloc;
+
+impl PageAlloc for BuddyPageAlloc {
+    type RawPage = RawPageHandle;
+
+    fn alloc_order(&self, order: u32) -> Option<Self::RawPage> {
+        let retval = BUDDY.lock().alloc_order(order);
+        retval
+    }
+
+    unsafe fn dealloc(&self, raw_page: Self::RawPage) {
+        BUDDY.lock().dealloc(raw_page);
+    }
+
+    fn has_management_over(&self, page_ptr: Self::RawPage) -> bool {
+        BuddyAllocator::has_management_over(page_ptr)
     }
 }
 
-fn enable_mmu() {
+type PageTable<'a> = eonix_mm::page_table::PageTable<'a, PagingModeSv48, BuddyPageAlloc, DirectPageAccess>;
+
+fn setup_page_tables() {
+    let attr = PageAttribute::WRITE
+        | PageAttribute::READ
+        | PageAttribute::EXECUTE
+        | PageAttribute::GLOBAL
+        | PageAttribute::PRESENT;
+
+    BUDDY.lock().create_pages(PAddr::from(0x80400000), PAddr::from(0x80800000));
+
+    let root_table_page = Page::alloc_in(BuddyPageAlloc);
+    let page_table = PageTable::new_in(&root_table_page, BuddyPageAlloc);
+
+    // Map 0x80200000-0x81200000 16MB identically, use 2MB page
+    for (idx, pte) in page_table
+        .iter_kernel(VRange::from(VAddr::from(0x80200000)).grow(0x1000000), 2)
+        .enumerate()
+    {
+        pte.set(PFN::from(idx * 0x200 + 0x80200), PageAttribute64::from_page_attr(attr));
+    }
+
+    // Map 0x0000_0000_0000_0000-0x0000_007F_FFFF_FFFF 256GB
+    // to 0xFFFF_FF00_0000_0000 to 0xFFFF_FF7F_FFFF_FFFF, use 1 GB page
+    for (idx, pte) in page_table
+        .iter_kernel(VRange::from(VAddr::from(0xFFFF_FF00_0000_0000)).grow(0x80_0000_0000), 1)
+        .enumerate()
+    {
+        pte.set(PFN::from(idx * 0x40000), PageAttribute64::from_page_attr(attr));
+    }
+
+    // Map kernel image
+    for (idx, pte) in page_table
+        .iter_kernel(VRange::from(VAddr::from(0xFFFF_FFFF_FFC0_0000)).grow(0x20_0000), 3)
+        .enumerate()
+    {
+        pte.set(PFN::from(idx + 0x80200), PageAttribute64::from_page_attr(attr));
+    }
+
+
     unsafe {
-        let satp_val = ROOT_PAGE_TABLE_PHYS_ADDR | (8 << 60); // Sv39 mode (8)
-        
-        asm!(
-            "csrw satp, {satp_val}",
-            "sfence.vma",
-            satp_val = in(reg) satp_val,
-        );
+        satp::set(satp::Mode::Sv48, 0, PFN::from(page_table.addr()).into());
     }
 }
 
@@ -213,11 +207,9 @@ unsafe extern "C" fn _start() -> ! {
         "la sp, {stack_top}",
         // TODO: set up page table, somewhere may be wrong
         "call {setup_page_tables_fn}",
-        "call {enable_mmu_fn}",
         "jr {kernel_init_fn}",
         stack_top = sym BOOT_STACK,
         setup_page_tables_fn = sym setup_page_tables,
-        enable_mmu_fn = sym enable_mmu,
         kernel_init_fn = sym kernel_init,
     )
 }

+ 1 - 9
arch/src/riscv64/kernel.ld

@@ -12,7 +12,7 @@ MEMORY
 
 SECTIONS
 {
-    .text : AT(0x80000000)
+    .text : AT(0x80200000)
     {
         TEXT_START = .;
         *(.text.entry)
@@ -78,14 +78,6 @@ SECTIONS
         DATA_END = .;
     } > KIMAGE
 
-    .data.root_page_tables : AT(0x80300000) {
-        . = ALIGN(0x1000);
-        *(.data.root_page_tables)
-        *(.data.boot_page_tables_lvl)
-
-        . = ALIGN(0x1000);
-    }
-
     DATA_PAGES = (DATA_END - DATA_START) / 0x1000;
 
     _PERCPU_DATA_START = .;

+ 12 - 7
arch/src/riscv64/mm.rs

@@ -7,8 +7,12 @@ use eonix_mm::{
     paging::{PageBlock, PFN},
 };
 
+pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8040_0000;
+pub const PAGE_TABLE_END: usize = 0x8080_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;
-const PAGE_TABLE_BASE: PFN = PFN::from_val(0x8030_0000 >> 12);
+const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PHYS_ADDR >> 12);
 
 pub const PA_V: u64 = 0b1 << 0;
 pub const PA_R: u64 = 0b1 << 1;
@@ -45,9 +49,9 @@ pub struct PTE64(pub u64);
 #[derive(Clone, Copy)]
 pub struct PageAttribute64(u64);
 
-pub struct RawPageTableSv39<'a>(NonNull<PTE64>, PhantomData<&'a ()>);
+pub struct RawPageTableSv48<'a>(NonNull<PTE64>, PhantomData<&'a ()>);
 
-pub struct PagingModeSv39;
+pub struct PagingModeSv48;
 
 impl PTE for PTE64 {
     type Attr = PageAttribute64;
@@ -64,10 +68,11 @@ impl PTE for PTE64 {
     }
 }
 
-impl PagingMode for PagingModeSv39 {
+impl PagingMode for PagingModeSv48 {
     type Entry = PTE64;
-    type RawTable<'a> = RawPageTableSv39<'a>;
+    type RawTable<'a> = RawPageTableSv48<'a>;
     const LEVELS: &'static [PageTableLevel] = &[
+        PageTableLevel::new(39, 9),
         PageTableLevel::new(30, 9),
         PageTableLevel::new(21, 9),
         PageTableLevel::new(12, 9),
@@ -75,7 +80,7 @@ impl PagingMode for PagingModeSv39 {
     const KERNEL_ROOT_TABLE_PFN: PFN = PAGE_TABLE_BASE;
 }
 
-impl<'a> RawPageTable<'a> for RawPageTableSv39<'a> {
+impl<'a> RawPageTable<'a> for RawPageTableSv48<'a> {
     type Entry = PTE64;
 
     fn index(&self, index: u16) -> &'a Self::Entry {
@@ -209,4 +214,4 @@ impl RawAttribute for PageAttribute64 {
     }
 }
 
-pub type DefaultPagingMode = PagingModeSv39;
+pub type DefaultPagingMode = PagingModeSv48;

+ 2 - 2
arch/src/riscv64/mod.rs

@@ -1,7 +1,7 @@
 mod mm;
 mod entry;
+mod context;
 
 pub use self::mm::*;
-#[allow(unused_imports)]
 pub use self::entry::*;
-
+pub use self::context::*;