소스 검색

feat(prototyper): Added support for 32-bit wide Uart16550 device

guttatus 3 달 전
부모
커밋
f045c64fc5
7개의 변경된 파일69개의 추가작업 그리고 41개의 파일을 삭제
  1. 10 2
      Cargo.lock
  2. 1 1
      prototyper/Cargo.toml
  3. 8 8
      prototyper/build.rs
  4. 24 14
      prototyper/src/board.rs
  5. 1 1
      prototyper/src/firmware/dynamic.rs
  6. 16 6
      prototyper/src/firmware/mod.rs
  7. 9 9
      prototyper/src/main.rs

+ 10 - 2
Cargo.lock

@@ -289,7 +289,7 @@ dependencies = [
  "sbi-spec 0.0.8",
  "sbi-testing 0.0.3-alpha.2 (git+https://github.com/rustsbi/rustsbi?rev=4821073)",
  "serde",
- "serde-device-tree",
+ "serde-device-tree 0.0.1 (git+https://github.com/rustsbi/serde-device-tree)",
  "spin",
  "uart16550",
 ]
@@ -318,7 +318,7 @@ dependencies = [
  "rustsbi",
  "sbi-spec 0.0.7",
  "serde",
- "serde-device-tree",
+ "serde-device-tree 0.0.1 (git+https://github.com/woshiluo/serde-device-tree?branch=aliases)",
  "sifive-test-device",
  "spin",
  "uart16550",
@@ -415,6 +415,14 @@ dependencies = [
  "serde_derive",
 ]
 
+[[package]]
+name = "serde-device-tree"
+version = "0.0.1"
+source = "git+https://github.com/woshiluo/serde-device-tree?branch=aliases#2f51fdf7fbe3ed394af41d83652c45f8acd51636"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde-device-tree"
 version = "0.0.1"

+ 1 - 1
prototyper/Cargo.toml

@@ -16,7 +16,7 @@ riscv = "0.11.1"
 rustsbi = { version = "0.4.0", features = ["machine"] }
 sbi-spec = { version = "0.0.7", features = ["legacy"] }
 serde = { version = "1.0.202", default-features = false, features = ["derive"] }
-serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree", default-features = false }
+serde-device-tree = { git = "https://github.com/woshiluo/serde-device-tree", branch = "aliases", default-features = false }
 sifive-test-device = "0.0.0"
 spin = "0.9.8"
 uart16550 = "0.0.1"

+ 8 - 8
prototyper/build.rs

@@ -25,23 +25,23 @@ SECTIONS {
     }
 
     .rodata : ALIGN(0x1000) { 
-        srodata = .;
+        sbi_rodata_start = .;
         *(.rodata .rodata.*)
         *(.srodata .srodata.*)
         . = ALIGN(0x1000);  
     } 
 
-    .dynsym : ALIGN(0x1000) {
+    .dynsym : ALIGN(8) {
         *(.dynsym)
     }
 
-    .rela.dyn : ALIGN(0x1000) {
+    .rela.dyn : ALIGN(8) {
         __rel_dyn_start = .;
         *(.rela*)
         __rel_dyn_end = .;
     }
 
-    erodata = .;
+    sbi_rodata_end = .;
 
 	/*
 	 * PMP regions must be to be power-of-2. RX/RW will have separate
@@ -51,20 +51,20 @@ SECTIONS {
 				+ SIZEOF(.dynsym) + SIZEOF(.rela.dyn))));
 
     .data : ALIGN(0x1000) { 
-        sdata = .;
+        sbi_data_start = .;
         *(.data .data.*)
         *(.sdata .sdata.*)
         . = ALIGN(0x1000); 
-        edata = .;
+        sbi_data_end = .;
     }
     sidata = LOADADDR(.data);
 
     .bss (NOLOAD) : ALIGN(0x1000) {  
         *(.bss.uninit)
-        sbss = .;
+        sbi_bss_start = .;
         *(.bss .bss.*)
         *(.sbss .sbss.*)
-        ebss = .;
+        sbi_bss_end = .;
     } 
     /DISCARD/ : {
         *(.eh_frame)

+ 24 - 14
prototyper/src/board.rs

@@ -23,10 +23,11 @@ use crate::sbi::trap_stack::NUM_HART_MAX;
 use crate::sbi::SBI;
 use crate::{dt, sbi::rfence::SbiRFence};
 
-pub(crate) const UART16650_COMPATIBLE: &str = "ns16550a";
-pub(crate) const UARTAXILITE_COMPATIBLE: &str = "xlnx,xps-uartlite-1.00.a";
-pub(crate) const SIFIVETEST_COMPATIBLE: &str = "sifive,test0";
-pub(crate) const SIFIVECLINT_COMPATIBLE: &str = "riscv,clint0";
+pub(crate) const UART16650U8_COMPATIBLE: [&str; 1] = ["ns16550a"];
+pub(crate) const UART16650U32_COMPATIBLE: [&str; 1] = ["snps,dw-apb-uart"];
+pub(crate) const UARTAXILITE_COMPATIBLE: [&str; 1] = ["xlnx,xps-uartlite-1.00.a"];
+pub(crate) const SIFIVETEST_COMPATIBLE: [&str; 1] = ["sifive,test0"];
+pub(crate) const SIFIVECLINT_COMPATIBLE: [&str; 1] = ["riscv,clint0"];
 
 type BaseAddress = usize;
 /// Store finite-length string on the stack.
@@ -137,11 +138,15 @@ impl Board {
                 let result = info.is_some_and(|info| {
                     let (compatible, regs) = info;
                     for device_id in compatible.iter() {
-                        if device_id == UART16650_COMPATIBLE {
-                            self.info.console = Some((regs.start, MachineConsoleType::Uart16550));
+                        if UART16650U8_COMPATIBLE.contains(&device_id) {
+                            self.info.console = Some((regs.start, MachineConsoleType::Uart16550U8));
                             return true;
                         }
-                        if device_id == UARTAXILITE_COMPATIBLE {
+                        if UART16650U32_COMPATIBLE.contains(&device_id) {
+                            self.info.console = Some((regs.start, MachineConsoleType::Uart16550U32));
+                            return true;
+                        }
+                        if UARTAXILITE_COMPATIBLE.contains(&device_id) {
                             self.info.console = Some((regs.start, MachineConsoleType::UartAxiLite));
                             return true;
                         }
@@ -162,11 +167,11 @@ impl Board {
                 let base_address = regs.start;
                 for device_id in compatible.iter() {
                     // Initialize clint device.
-                    if device_id == SIFIVECLINT_COMPATIBLE {
+                    if SIFIVECLINT_COMPATIBLE.contains(&device_id) {
                         self.info.ipi = Some(base_address);
                     }
                     // Initialize reset device.
-                    if device_id == SIFIVETEST_COMPATIBLE {
+                    if SIFIVETEST_COMPATIBLE.contains(&device_id) {
                         self.info.reset = Some(base_address);
                     }
                 }
@@ -225,7 +230,8 @@ impl Board {
     fn sbi_console_init(&mut self) {
         if let Some((base, console_type)) = self.info.console {
             let new_console = match console_type {
-                MachineConsoleType::Uart16550 => MachineConsole::Uart16550(base as _),
+                MachineConsoleType::Uart16550U8 => MachineConsole::Uart16550U8(base as _),
+                MachineConsoleType::Uart16550U32 => MachineConsole::Uart16550U32(base as _),
                 MachineConsoleType::UartAxiLite => {
                     MachineConsole::UartAxiLite(MmioUartAxiLite::new(base))
                 }
@@ -281,13 +287,15 @@ pub(crate) static mut BOARD: Board = Board::new();
 #[allow(unused)]
 #[derive(Clone, Copy, Debug)]
 pub enum MachineConsoleType {
-    Uart16550,
+    Uart16550U8,
+    Uart16550U32,
     UartAxiLite,
 }
 #[doc(hidden)]
 #[allow(unused)]
 pub enum MachineConsole {
-    Uart16550(*const Uart16550<u8>),
+    Uart16550U8(*const Uart16550<u8>),
+    Uart16550U32(*const Uart16550<u32>),
     UartAxiLite(MmioUartAxiLite),
 }
 
@@ -297,14 +305,16 @@ unsafe impl Sync for MachineConsole {}
 impl ConsoleDevice for MachineConsole {
     fn read(&self, buf: &mut [u8]) -> usize {
         match self {
-            Self::Uart16550(uart16550) => unsafe { (**uart16550).read(buf) },
+            Self::Uart16550U8(uart16550) => unsafe { (**uart16550).read(buf) },
+            Self::Uart16550U32(uart16550) => unsafe { (**uart16550).read(buf) },
             Self::UartAxiLite(axilite) => axilite.read(buf),
         }
     }
 
     fn write(&self, buf: &[u8]) -> usize {
         match self {
-            MachineConsole::Uart16550(uart16550) => unsafe { (**uart16550).write(buf) },
+            MachineConsole::Uart16550U8(uart16550) => unsafe { (**uart16550).write(buf) },
+            MachineConsole::Uart16550U32(uart16550) => unsafe { (**uart16550).write(buf) },
             Self::UartAxiLite(axilite) => axilite.write(buf),
         }
     }

+ 1 - 1
prototyper/src/firmware/dynamic.rs

@@ -64,7 +64,7 @@ pub struct DynamicInfo {
 const DYNAMIC_INFO_INVALID_ADDRESSES: usize = 0x00000000;
 const NEXT_ADDR_VALID_ADDRESSES: Range<usize> = 0x80000000..0x90000000;
 pub(crate) const MAGIC: usize = 0x4942534f;
-const SUPPORTED_VERSION: Range<usize> = 2..3;
+const SUPPORTED_VERSION: Range<usize> = 0..3;
 
 /// Error type for dynamic info read failures.
 pub struct DynamicReadError {

+ 16 - 6
prototyper/src/firmware/mod.rs

@@ -63,14 +63,20 @@ pub fn set_pmp(memory_range: &Range<usize>) {
     unsafe {
         // [0..memory_range.start] RW
         // [memory_range.start..sbi_start] RWX
-        // [sbi_start..sbi_end] NONE
+        // [sbi_start..sbi_rodata_start] NONE
+        // [sbi_rodata_start..sbi_rodata_end] NONE
+        // [sbi_rodata_end..sbi_end] NONE
         // [sbi_end..memory_range.end] RWX
         // [memory_range.end..INF] RW
         use riscv::register::*;
         let mut sbi_start_address: usize;
         let mut sbi_end_address: usize;
+        let mut rodata_start_address: usize;
+        let mut rodata_end_address: usize;
         asm!("la {}, sbi_start", out(reg) sbi_start_address, options(nomem));
         asm!("la {}, sbi_end", out(reg) sbi_end_address, options(nomem));
+        asm!("la {}, sbi_rodata_start", out(reg) rodata_start_address, options(nomem));
+        asm!("la {}, sbi_rodata_end", out(reg) rodata_end_address, options(nomem));
         pmpcfg0::set_pmp(0, Range::OFF, Permission::NONE, false);
         pmpaddr0::write(0);
         pmpcfg0::set_pmp(1, Range::TOR, Permission::RW, false);
@@ -78,10 +84,14 @@ pub fn set_pmp(memory_range: &Range<usize>) {
         pmpcfg0::set_pmp(2, Range::TOR, Permission::RWX, false);
         pmpaddr2::write(sbi_start_address >> 2);
         pmpcfg0::set_pmp(3, Range::TOR, Permission::NONE, false);
-        pmpaddr3::write(sbi_end_address >> 2);
-        pmpcfg0::set_pmp(4, Range::TOR, Permission::RWX, false);
-        pmpaddr4::write(memory_range.end >> 2);
-        pmpcfg0::set_pmp(5, Range::TOR, Permission::RW, false);
-        pmpaddr5::write(usize::MAX >> 2);
+        pmpaddr3::write(rodata_start_address >> 2);
+        pmpcfg0::set_pmp(4, Range::TOR, Permission::RW, false);
+        pmpaddr4::write(rodata_end_address >> 2);
+        pmpcfg0::set_pmp(5, Range::TOR, Permission::NONE, false);
+        pmpaddr5::write(sbi_end_address >> 2);
+        pmpcfg0::set_pmp(6, Range::TOR, Permission::RWX, false);
+        pmpaddr6::write(memory_range.end >> 2);
+        pmpcfg0::set_pmp(7, Range::TOR, Permission::RW, false);
+        pmpaddr7::write(usize::MAX >> 2);
     }
 }

+ 9 - 9
prototyper/src/main.rs

@@ -91,13 +91,13 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
         medeleg::clear_supervisor_env_call();
         medeleg::clear_illegal_instruction();
         // Configure environment features based on available extensions.
-        if hart_extension_probe(current_hartid(), Extension::Sstc) {
-            menvcfg::set_bits(
-                menvcfg::STCE | menvcfg::CBIE_INVALIDATE | menvcfg::CBCFE | menvcfg::CBZE,
-            );
-        } else {
-            menvcfg::set_bits(menvcfg::CBIE_INVALIDATE | menvcfg::CBCFE | menvcfg::CBZE);
-        }
+        // if hart_extension_probe(current_hartid(), Extension::Sstc) {
+        //     menvcfg::set_bits(
+        //         menvcfg::STCE | menvcfg::CBIE_INVALIDATE | menvcfg::CBCFE | menvcfg::CBZE,
+        //     );
+        // } else {
+        //     menvcfg::set_bits(menvcfg::CBIE_INVALIDATE | menvcfg::CBCFE | menvcfg::CBZE);
+        // }
         // Set up vectored trap handling.
         mtvec::write(trap_vec as _, mtvec::TrapMode::Vectored);
     }
@@ -117,8 +117,8 @@ unsafe extern "C" fn start() -> ! {
         "   call    {relocation_update}",
         "1:",
         // 3. Hart 0 clear bss segment.
-        "   lla     t0, sbss
-            lla     t1, ebss
+        "   lla     t0, sbi_bss_start
+            lla     t1, sbi_bss_end
          2: bgeu    t0, t1, 3f
             sd      zero, 0(t0)
             addi    t0, t0, 8