浏览代码

fix: strip null terminators from some strings that had them

Wesley Norris 2 年之前
父节点
当前提交
cff6d06660
共有 6 个文件被更改,包括 237 次插入5 次删除
  1. 1 1
      Cargo.toml
  2. 二进制
      dtb/sifive.dtb
  3. 207 0
      dts/sifive.dts
  4. 1 1
      src/node.rs
  5. 5 3
      src/standard_nodes.rs
  6. 23 0
      src/tests.rs

+ 1 - 1
Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "fdt"
-version = "0.1.3"
+version = "0.1.4"
 authors = ["Wesley Norris <repnop@outlook.com>"]
 edition = "2018"
 

二进制
dtb/sifive.dtb


+ 207 - 0
dts/sifive.dts

@@ -0,0 +1,207 @@
+/dts-v1/;
+
+/ {
+	#address-cells = <0x02>;
+	#size-cells = <0x02>;
+	compatible = "sifive,hifive-unleashed-a00";
+	model = "SiFive HiFive Unleashed A00";
+
+	chosen {
+		bootargs = [00];
+		stdout-path = "/soc/serial@10010000";
+	};
+
+	aliases {
+		serial0 = "/soc/serial@10010000";
+		ethernet0 = "/soc/ethernet@10090000";
+	};
+
+	gpio-restart {
+		compatible = "gpio-restart";
+		gpios = <0x0a 0x0a 0x01>;
+	};
+
+	cpus {
+		#address-cells = <0x01>;
+		#size-cells = <0x00>;
+		timebase-frequency = <0x989680>;
+
+		cpu@0 {
+			device_type = "cpu";
+			reg = <0x00>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imacu";
+
+			interrupt-controller {
+				#interrupt-cells = <0x01>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+				phandle = <0x07>;
+			};
+		};
+
+		cpu@1 {
+			device_type = "cpu";
+			reg = <0x01>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdcsu";
+			mmu-type = "riscv,sv48";
+
+			interrupt-controller {
+				#interrupt-cells = <0x01>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+				phandle = <0x06>;
+			};
+		};
+
+		cpu@2 {
+			device_type = "cpu";
+			reg = <0x02>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdcsu";
+			mmu-type = "riscv,sv48";
+
+			interrupt-controller {
+				#interrupt-cells = <0x01>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+				phandle = <0x05>;
+			};
+		};
+
+		cpu@3 {
+			device_type = "cpu";
+			reg = <0x03>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdcsu";
+			mmu-type = "riscv,sv48";
+
+			interrupt-controller {
+				#interrupt-cells = <0x01>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+				phandle = <0x04>;
+			};
+		};
+
+		cpu@4 {
+			device_type = "cpu";
+			reg = <0x04>;
+			status = "okay";
+			compatible = "riscv";
+			riscv,isa = "rv64imafdcsu";
+			mmu-type = "riscv,sv48";
+
+			interrupt-controller {
+				#interrupt-cells = <0x01>;
+				interrupt-controller;
+				compatible = "riscv,cpu-intc";
+				phandle = <0x03>;
+			};
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00 0x80000000 0x00 0x20000000>;
+	};
+
+	rtcclk {
+		#clock-cells = <0x00>;
+		compatible = "fixed-clock";
+		clock-frequency = <0xf4240>;
+		clock-output-names = "rtcclk";
+		phandle = <0x02>;
+	};
+
+	hfclk {
+		#clock-cells = <0x00>;
+		compatible = "fixed-clock";
+		clock-frequency = <0x1fca055>;
+		clock-output-names = "hfclk";
+		phandle = <0x01>;
+	};
+
+	soc {
+		#address-cells = <0x02>;
+		#size-cells = <0x02>;
+		compatible = "simple-bus";
+		ranges;
+
+		serial@10010000 {
+			interrupts = <0x04>;
+			interrupt-parent = <0x09>;
+			clocks = <0x08 0x03>;
+			reg = <0x00 0x10010000 0x00 0x1000>;
+			compatible = "sifive,uart0";
+		};
+
+		ethernet@10090000 {
+			#size-cells = <0x00>;
+			#address-cells = <0x01>;
+			local-mac-address = [52 54 00 12 34 56];
+			clock-names = "pclk\0hclk";
+			clocks = <0x08 0x02 0x08 0x02>;
+			interrupts = <0x35>;
+			interrupt-parent = <0x09>;
+			phy-handle = <0x0b>;
+			phy-mode = "gmii";
+			reg-names = "control";
+			reg = <0x00 0x10090000 0x00 0x2000 0x00 0x100a0000 0x00 0x1000>;
+			compatible = "sifive,fu540-c000-gem";
+
+			ethernet-phy@0 {
+				reg = <0x00>;
+				phandle = <0x0b>;
+			};
+		};
+
+		gpio@10060000 {
+			compatible = "sifive,gpio0";
+			interrupt-parent = <0x09>;
+			interrupts = <0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16>;
+			reg = <0x00 0x10060000 0x00 0x1000>;
+			gpio-controller;
+			#gpio-cells = <0x02>;
+			interrupt-controller;
+			#interrupt-cells = <0x02>;
+			clocks = <0x08 0x03>;
+			phandle = <0x0a>;
+		};
+
+		interrupt-controller@c000000 {
+			phandle = <0x09>;
+			riscv,ndev = <0x35>;
+			reg = <0x00 0xc000000 0x00 0x4000000>;
+			interrupts-extended = <0x07 0x0b 0x06 0x0b 0x06 0x09 0x05 0x0b 0x05 0x09 0x04 0x0b 0x04 0x09 0x03 0x0b 0x03 0x09>;
+			interrupt-controller;
+			compatible = "riscv,plic0";
+			#interrupt-cells = <0x01>;
+		};
+
+		clock-controller@10000000 {
+			compatible = "sifive,fu540-c000-prci";
+			reg = <0x00 0x10000000 0x00 0x1000>;
+			clocks = <0x01 0x02>;
+			#clock-cells = <0x01>;
+			phandle = <0x08>;
+		};
+
+		otp@10070000 {
+			compatible = "sifive,fu540-c000-otp";
+			reg = <0x00 0x10070000 0x00 0x1000>;
+			fuse-count = <0x1000>;
+		};
+
+		clint@2000000 {
+			interrupts-extended = <0x07 0x03 0x07 0x07 0x06 0x03 0x06 0x07 0x05 0x03 0x05 0x07 0x04 0x03 0x04 0x07 0x03 0x03 0x03 0x07>;
+			reg = <0x00 0x2000000 0x00 0x10000>;
+			compatible = "riscv,clint0";
+		};
+	};
+};

+ 1 - 1
src/node.rs

@@ -493,7 +493,7 @@ impl<'a> NodeProperty<'a> {
 
     /// Attempt to parse the property value as a `&str`
     pub fn as_str(self) -> Option<&'a str> {
-        core::str::from_utf8(self.value).ok()
+        core::str::from_utf8(self.value).map(|s| s.trim_end_matches('\0')).ok()
     }
 
     fn parse(stream: &mut FdtData<'a>, header: &Fdt<'a>) -> Self {

+ 5 - 3
src/standard_nodes.rs

@@ -64,7 +64,7 @@ impl<'b, 'a: 'b> Root<'b, 'a> {
         self.node
             .properties()
             .find(|p| p.name == "model")
-            .and_then(|p| core::str::from_utf8(p.value).ok())
+            .and_then(|p| core::str::from_utf8(p.value).map(|s| s.trim_end_matches('\0')).ok())
             .unwrap()
     }
 
@@ -97,7 +97,7 @@ impl<'b, 'a: 'b> Aliases<'b, 'a> {
         self.node
             .properties()
             .find(|p| p.name == alias)
-            .and_then(|p| core::str::from_utf8(&p.value[..p.value.len() - 1]).ok())
+            .and_then(|p| core::str::from_utf8(p.value).map(|s| s.trim_end_matches('\0')).ok())
     }
 
     /// Attempt to find the node specified by the given alias
@@ -107,7 +107,9 @@ impl<'b, 'a: 'b> Aliases<'b, 'a> {
 
     /// Returns an iterator over all of the available aliases
     pub fn all(self) -> impl Iterator<Item = (&'a str, &'a str)> + 'b {
-        self.node.properties().filter_map(|p| Some((p.name, core::str::from_utf8(&p.value[..p.value.len() - 1]).ok()?)))
+        self.node.properties().filter_map(|p| {
+            Some((p.name, core::str::from_utf8(p.value).map(|s| s.trim_end_matches('\0')).ok()?))
+        })
     }
 }
 

+ 23 - 0
src/tests.rs

@@ -8,6 +8,7 @@ use crate::{node::RawReg, *};
 
 static TEST: &[u8] = include_bytes!("../dtb/test.dtb");
 static ISSUE_3: &[u8] = include_bytes!("../dtb/issue-3.dtb");
+static SIFIVE: &[u8] = include_bytes!("../dtb/sifive.dtb");
 
 #[test]
 fn returns_fdt() {
@@ -187,6 +188,28 @@ fn invalid_node() {
     assert!(fdt.find_node("this/is/an invalid node///////////").is_none());
 }
 
+#[test]
+fn aliases() {
+    let fdt = Fdt::new(SIFIVE).unwrap();
+    let aliases = fdt.aliases().unwrap();
+    for (_, node_path) in aliases.all() {
+        assert!(fdt.find_node(node_path).is_some(), "path: {:?}", node_path);
+    }
+}
+
+#[test]
+fn node_property_str_value() {
+    let fdt = Fdt::new(TEST).unwrap();
+    let cpu0 = fdt.find_node("/cpus/cpu@0").unwrap();
+    assert_eq!(cpu0.property("riscv,isa").unwrap().as_str().unwrap(), "rv64imafdcsu");
+}
+
+#[test]
+fn model_value() {
+    let fdt = Fdt::new(TEST).unwrap();
+    assert_eq!(fdt.root().model(), "riscv-virtio,qemu");
+}
+
 #[test]
 fn memory_node() {
     let fdt = Fdt::new(TEST).unwrap();