Ver Fonte

feat(prototyper): get device address from fdt

Signed-off-by: Woshiluo Luo <woshiluo.luo@outlook.com>
Woshiluo Luo há 6 meses atrás
pai
commit
90fbc08a62
2 ficheiros alterados com 39 adições e 12 exclusões
  1. 16 3
      prototyper/src/dt.rs
  2. 23 9
      prototyper/src/main.rs

+ 16 - 3
prototyper/src/dt.rs

@@ -1,6 +1,6 @@
 use serde::Deserialize;
 use serde_device_tree::{
-    buildin::{NodeSeq, StrSeq},
+    buildin::{NodeSeq, Reg, StrSeq},
     Dtb, DtbPtr,
 };
 
@@ -9,6 +9,7 @@ pub struct Tree<'a> {
     pub model: Option<StrSeq<'a>>,
     pub chosen: Chosen<'a>,
     pub cpus: Cpus<'a>,
+    pub soc: Soc<'a>,
 }
 
 #[derive(Deserialize)]
@@ -23,11 +24,23 @@ pub struct Cpus<'a> {
     pub cpu: NodeSeq<'a>,
 }
 
-#[allow(dead_code)]
 #[derive(Deserialize, Debug)]
 pub struct Cpu<'a> {
     #[serde(rename = "riscv,isa-extensions")]
-    pub isa: StrSeq<'a>,
+    pub isa: Option<StrSeq<'a>>,
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Soc<'a> {
+    pub serial: Option<NodeSeq<'a>>,
+    pub test: Option<NodeSeq<'a>>,
+    pub clint: Option<NodeSeq<'a>>,
+}
+
+#[allow(unused)]
+#[derive(Deserialize, Debug)]
+pub struct Device<'a> {
+    pub reg: Reg<'a>,
 }
 
 pub enum ParseDeviceTreeError {

+ 23 - 9
prototyper/src/main.rs

@@ -49,18 +49,25 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
             dynamic::mpp_next_addr(&info).unwrap_or_else(fail::invalid_dynamic_data);
 
         // parse the device tree
-        let dtb = dt::parse_device_tree(opaque).unwrap_or_else(fail::device_tree_format);
-        let dtb = dtb.share();
-
-        // TODO: The device base address needs to be parsed from FDT
-        // 1. Init device
-        board::reset_dev_init(0x100000);
-        board::console_dev_init(0x10000000);
-        board::ipi_dev_init(0x2000000);
 
         // 2. Init FDT
+        let dtb = dt::parse_device_tree(opaque).unwrap_or_else(fail::device_tree_format);
+        let dtb = dtb.share();
         let tree =
             serde_device_tree::from_raw_mut(&dtb).unwrap_or_else(fail::device_tree_deserialize);
+
+        // 1. Init device
+        // TODO: The device base address should be find in a better way
+        let reset_device = tree.soc.test.unwrap().iter().next().unwrap();
+        let console_base = tree.soc.serial.unwrap().iter().next().unwrap();
+        let clint_device = tree.soc.clint.unwrap().iter().next().unwrap();
+        let reset_base_address = reset_device.at();
+        let console_base_address = console_base.at();
+        let ipi_base_address = clint_device.at();
+        board::reset_dev_init(usize::from_str_radix(reset_base_address, 16).unwrap());
+        board::console_dev_init(usize::from_str_radix(console_base_address, 16).unwrap());
+        board::ipi_dev_init(usize::from_str_radix(ipi_base_address, 16).unwrap());
+        // Assume sstc is enabled only if all hart has sstc ext
         let sstc_support = tree
             .cpus
             .cpu
@@ -68,7 +75,11 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
             .map(|cpu_iter| {
                 use crate::dt::Cpu;
                 let cpu = cpu_iter.deserialize::<Cpu>();
-                cpu.isa.iter().find(|&x| x == "sstc").is_some()
+                let isa = match cpu.isa {
+                    Some(value) => value,
+                    None => return false,
+                };
+                isa.iter().find(|&x| x == "sstc").is_some()
             })
             .all(|x| x);
         // 3. Init SBI
@@ -92,6 +103,9 @@ extern "C" fn rust_main(_hart_id: usize, opaque: usize, nonstandard_a2: usize) {
             info!("Model: {}", model.iter().next().unwrap_or("<unspecified>"));
         }
         info!("Support sstc: {sstc_support}");
+        info!("Clint device: {}", ipi_base_address);
+        info!("Console deivce: {}", console_base_address);
+        info!("Reset device: {}", reset_base_address);
         info!(
             "Chosen stdout item: {}",
             tree.chosen