Bladeren bron

feat(arch): add console io and mmio io

Heinz 8 maanden geleden
bovenliggende
commit
530df496c2
5 gewijzigde bestanden met toevoegingen van 88 en 9 verwijderingen
  1. 16 0
      arch/src/riscv64/console.rs
  2. 5 7
      arch/src/riscv64/entry.rs
  3. 59 0
      arch/src/riscv64/io.rs
  4. 4 2
      arch/src/riscv64/mm.rs
  5. 4 0
      arch/src/riscv64/mod.rs

+ 16 - 0
arch/src/riscv64/console.rs

@@ -0,0 +1,16 @@
+use sbi::legacy::{console_putchar, console_getchar};
+
+pub fn getchar() -> Option<u8> {
+    let c = console_getchar();
+    if c == Some(!0) {
+        None
+    } else {
+        c
+    }
+}
+
+fn write_str(s: &str) {
+    for c in s.chars() {
+        console_putchar(c as u8);
+    }
+}

+ 5 - 7
arch/src/riscv64/entry.rs

@@ -14,8 +14,6 @@ use eonix_mm::{
 };
 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];
 
@@ -158,14 +156,14 @@ fn setup_page_tables() {
         | PageAttribute::GLOBAL
         | PageAttribute::PRESENT;
 
-    BUDDY.lock().create_pages(PAddr::from(0x80400000), PAddr::from(0x80800000));
+    BUDDY.lock().create_pages(PAddr::from(ROOT_PAGE_TABLE_PHYS_ADDR), PAddr::from(PAGE_TABLE_PHYS_END));
 
     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_levels(VRange::from(VAddr::from(0x80200000)).grow(0x1000000), &PagingModeSv48::LEVELS[..2])
+        .iter_kernel_levels(VRange::from(VAddr::from(KIMAGE_PHYS_BASE)).grow(0x1000000), &PagingModeSv48::LEVELS[..2])
         .enumerate()
     {
         pte.set(PFN::from(idx * 0x200 + 0x80200), PageAttribute64::from_page_attr(attr));
@@ -174,15 +172,15 @@ fn setup_page_tables() {
     // Map 0x0000_0000_0000_0000-0x0000_007F_FFFF_FFFF 512GB
     // to 0xFFFF_FF00_0000_0000 to 0xFFFF_FF7F_FFFF_FFFF, use 1 GB page
     for (idx, pte) in page_table
-        .iter_kernel_levels(VRange::from(VAddr::from(0xFFFF_FF00_0000_0000)).grow(0x80_0000_0000), &PagingModeSv48::LEVELS[..1])
+        .iter_kernel_levels(VRange::from(VAddr::from(PHYS_MAP_VIRT)).grow(0x80_0000_0000), &PagingModeSv48::LEVELS[..1])
         .enumerate()
     {
         pte.set(PFN::from(idx * 0x40000), PageAttribute64::from_page_attr(attr));
     }
 
-    // Map kernel image
+    // Map 2 MB kernel image
     for (idx, pte) in page_table
-        .iter_kernel_levels(VRange::from(VAddr::from(0xFFFF_FFFF_FFC0_0000)).grow(0x20_0000), &PagingModeSv48::LEVELS[..3])
+        .iter_kernel_levels(VRange::from(VAddr::from(KIMAGE_VIRT_BASE)).grow(0x20_0000), &PagingModeSv48::LEVELS[..3])
         .enumerate()
     {
         pte.set(PFN::from(idx + 0x80200), PageAttribute64::from_page_attr(attr));

+ 59 - 0
arch/src/riscv64/io.rs

@@ -0,0 +1,59 @@
+use core::ptr::{read_volatile, write_volatile};
+use riscv::register::sstatus::{self, FS};
+
+pub fn enable_sse() {
+    unsafe {
+        // FS (Floating-point Status) Initial (0b01)
+        sstatus::set_fs(FS::Initial);
+    }
+}
+
+// MMIO
+
+pub fn inb(addr: usize) -> u8 {
+    unsafe {
+        read_volatile(addr as *const u8)
+    }
+}
+
+pub fn inw(addr: usize) -> u16 {
+    unsafe {
+        read_volatile(addr as *const u16)
+    }
+}
+
+pub fn inl(addr: usize) -> u32 {
+    unsafe {
+        read_volatile(addr as *const u32)
+    }
+}
+
+pub fn inu64(addr: usize) -> u64 {
+    unsafe {
+        read_volatile(addr as *const u64)
+    }
+}
+
+pub fn outb(addr: usize, data: u8) {
+    unsafe {
+        write_volatile(addr as *mut u8, data)
+    }
+}
+
+pub fn outw(addr: usize, data: u16) {
+    unsafe {
+        write_volatile(addr as *mut u16, data)
+    }
+}
+
+pub fn outl(addr: usize, data: u32) {
+    unsafe {
+        write_volatile(addr as *mut u32, data)
+    }
+}
+
+pub fn outu64(addr: usize, data: u64) {
+    unsafe {
+        write_volatile(addr as *mut u64, data)
+    }
+}

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

@@ -15,11 +15,13 @@ pub enum PageSize {
 }
 
 pub const ROOT_PAGE_TABLE_PHYS_ADDR: usize = 0x8040_0000;
-pub const PAGE_TABLE_END: usize = 0x8080_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;
-const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PHYS_ADDR >> 12);
+pub const PAGE_TABLE_BASE: PFN = PFN::from_val(ROOT_PAGE_TABLE_PFN);
 
 pub const PA_V: u64 = 0b1 << 0;
 pub const PA_R: u64 = 0b1 << 1;

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

@@ -1,7 +1,11 @@
 mod mm;
 mod entry;
 mod context;
+mod console;
+mod io;
 
 pub use self::mm::*;
 pub use self::entry::*;
 pub use self::context::*;
+pub use self::console::*;
+pub use self::io::*;