Parcourir la source

device_tree: parse chosen stdout device

Signed-off-by: Zhouqi Jiang <luojia@hust.edu.cn>
Zhouqi Jiang il y a 10 mois
Parent
commit
3bd6cfe1c0
5 fichiers modifiés avec 89 ajouts et 7 suppressions
  1. 38 5
      Cargo.lock
  2. 3 1
      Cargo.toml
  3. 29 0
      src/device_tree.rs
  4. 13 1
      src/fail.rs
  5. 6 0
      src/main.rs

+ 38 - 5
Cargo.lock

@@ -78,8 +78,9 @@ dependencies = [
 
 [[package]]
 name = "rustsbi"
-version = "0.4.0-alpha.2"
-source = "git+https://github.com/rustsbi/rustsbi#2daec25b1bdcb8596ae01a25327eb9ce6fb4738f"
+version = "0.4.0-alpha.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce47c5c62f6a4d9586b78cc2ba963330bc57a046c4b2949ebc128265707a40c3"
 dependencies = [
  "riscv",
  "rustsbi-macros",
@@ -88,8 +89,9 @@ dependencies = [
 
 [[package]]
 name = "rustsbi-macros"
-version = "0.0.1"
-source = "git+https://github.com/rustsbi/rustsbi#2daec25b1bdcb8596ae01a25327eb9ce6fb4738f"
+version = "0.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a71347da9582cc6b6f3652c7d2c06516c9555690b3738ecdff7e84297f4e17fc"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -105,6 +107,8 @@ dependencies = [
  "panic-halt",
  "riscv",
  "rustsbi",
+ "serde",
+ "serde-device-tree",
  "sifive-test-device",
  "spin",
  "uart16550",
@@ -113,7 +117,8 @@ dependencies = [
 [[package]]
 name = "sbi-spec"
 version = "0.0.7"
-source = "git+https://github.com/rustsbi/rustsbi#2daec25b1bdcb8596ae01a25327eb9ce6fb4738f"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"
 
 [[package]]
 name = "scopeguard"
@@ -121,6 +126,34 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
+[[package]]
+name = "serde"
+version = "1.0.202"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-device-tree"
+version = "0.0.1"
+source = "git+https://github.com/rustsbi/serde-device-tree#b8c2da9ee425cce49480731fa48e2ea39b457803"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.202"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "sifive-test-device"
 version = "0.0.0"

+ 3 - 1
Cargo.toml

@@ -13,7 +13,9 @@ aclint = "0.0.0"
 log = "0.4.21"
 panic-halt = "0.2.0"
 riscv = "0.11.1"
-rustsbi = { git = "https://github.com/rustsbi/rustsbi", features = ["machine"] }
+rustsbi = { version = "0.4.0-alpha.3", features = ["machine"] }
+serde = { version = "1.0.202", default-features = false, features = ["derive"]}
+serde-device-tree = { git = "https://github.com/rustsbi/serde-device-tree", default-features = false }
 sifive-test-device = "0.0.0"
 spin = "0.9.8"
 uart16550 = "0.0.1"

+ 29 - 0
src/device_tree.rs

@@ -0,0 +1,29 @@
+use serde::Deserialize;
+use serde_device_tree::{buildin::StrSeq, from_raw_mut, Dtb, DtbPtr};
+
+#[derive(Deserialize)]
+pub struct Tree<'a> {
+    pub chosen: Chosen<'a>,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub struct Chosen<'a> {
+    pub stdout_path: StrSeq<'a>,
+}
+
+pub enum ParseDeviceTreeError {
+    Format,
+    Deserialize,
+}
+
+pub fn parse_device_tree<'a>(opaque: usize) -> Result<Tree<'a>, ParseDeviceTreeError> {
+    let Ok(ptr) = DtbPtr::from_raw(opaque as *mut _) else {
+        return Err(ParseDeviceTreeError::Format);
+    };
+    let dtb = Dtb::from(ptr).share();
+    let Ok(tree) = from_raw_mut(&dtb) else {
+        return Err(ParseDeviceTreeError::Deserialize);
+    };
+    Ok(tree)
+}

+ 13 - 1
src/fail.rs

@@ -1,6 +1,18 @@
-use crate::{dynamic, reset};
+use crate::{
+    device_tree::{self, ParseDeviceTreeError, Tree},
+    dynamic, reset,
+};
 use riscv::register::mstatus;
 
+#[cold]
+pub fn invalid_device_tree<'a>(err: device_tree::ParseDeviceTreeError) -> Tree<'a> {
+    match err {
+        ParseDeviceTreeError::Deserialize => error!("- deserialization failed"),
+        ParseDeviceTreeError::Format => error!("- FDT format error"),
+    }
+    reset::fail()
+}
+
 #[cold]
 pub fn invalid_dynamic_data(err: dynamic::DynamicError) -> (mstatus::MPP, usize) {
     error!("Invalid data in dynamic information:");

+ 6 - 0
src/main.rs

@@ -9,6 +9,7 @@ mod macros;
 
 mod board;
 mod console;
+mod device_tree;
 mod dynamic;
 mod fail;
 mod reset;
@@ -25,6 +26,11 @@ extern "C" fn main(hart_id: usize, opaque: usize, nonstandard_a2: usize) -> usiz
     rustsbi::LOGO.lines().for_each(|line| info!("{}", line));
     info!("Initializing RustSBI machine-mode environment.");
 
+    let tree = device_tree::parse_device_tree(opaque).unwrap_or_else(fail::invalid_device_tree);
+    for item in tree.chosen.stdout_path.iter() {
+        info!("chosen stdout item: {:?}", item);
+    }
+
     let info = dynamic::read_paddr(nonstandard_a2).unwrap_or_else(fail::no_dynamic_info_available);
 
     let (mpp, next_addr) = dynamic::mpp_next_addr(&info).unwrap_or_else(fail::invalid_dynamic_data);