[fdt] Add function to get the first range in /memory node of fdt
and test it. This function will be reused later in both pvmfw and
rialto.
Test: atest liblibfdt.integration_test
Test: atest vmbase_example.integration_test
Test: m pvmfw_img
Bug: 284462758
Change-Id: Ic547530f911281c2db14b9a59b7e2470be10361f
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 55cb01b..2a6e75f 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -51,7 +51,10 @@
srcs: ["tests/*.rs"],
test_suites: ["general-tests"],
data: [
- ":fdt_data_test_tree1_dtb",
+ ":fdt_test_tree_one_memory_range_dtb",
+ ":fdt_test_tree_multiple_memory_ranges_dtb",
+ ":fdt_test_tree_empty_memory_range_dtb",
+ ":fdt_test_tree_no_memory_node_dtb",
],
prefer_rlib: true,
rustlibs: [
@@ -60,9 +63,29 @@
}
genrule {
- name: "fdt_data_test_tree1_dtb",
- tools: ["dtc"],
- srcs: ["tests/data/test_tree1.dts"],
- out: ["data/test_tree1.dtb"],
- cmd: "$(location dtc) -O dtb -I dts -o $(out) $(in)",
+ name: "fdt_test_tree_one_memory_range_dtb",
+ defaults: ["test_avf_dts_to_dtb"],
+ srcs: ["tests/data/test_tree_one_memory_range.dts"],
+ out: ["data/test_tree_one_memory_range.dtb"],
+}
+
+genrule {
+ name: "fdt_test_tree_multiple_memory_ranges_dtb",
+ defaults: ["test_avf_dts_to_dtb"],
+ srcs: ["tests/data/test_tree_multiple_memory_ranges.dts"],
+ out: ["data/test_tree_multiple_memory_ranges.dtb"],
+}
+
+genrule {
+ name: "fdt_test_tree_empty_memory_range_dtb",
+ defaults: ["test_avf_dts_to_dtb"],
+ srcs: ["tests/data/test_tree_empty_memory_range.dts"],
+ out: ["data/test_tree_empty_memory_range.dtb"],
+}
+
+genrule {
+ name: "fdt_test_tree_no_memory_node_dtb",
+ defaults: ["test_avf_dts_to_dtb"],
+ srcs: ["tests/data/test_tree_no_memory_node.dts"],
+ out: ["data/test_tree_no_memory_node.dtb"],
}
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 91214b3..8e0bb65 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -25,6 +25,7 @@
use core::ffi::{c_int, c_void, CStr};
use core::fmt;
use core::mem;
+use core::ops::Range;
use core::result;
use zerocopy::AsBytes as _;
@@ -716,23 +717,24 @@
Ok(self)
}
- /// Return an iterator of memory banks specified the "/memory" node.
+ /// Returns an iterator of memory banks specified the "/memory" node.
+ /// Throws an error when the "/memory" is not found in the device tree.
///
/// NOTE: This does not support individual "/memory@XXXX" banks.
- pub fn memory(&self) -> Result<Option<MemRegIterator>> {
- let memory = CStr::from_bytes_with_nul(b"/memory\0").unwrap();
- let device_type = CStr::from_bytes_with_nul(b"memory\0").unwrap();
+ pub fn memory(&self) -> Result<MemRegIterator> {
+ let memory_node_name = CStr::from_bytes_with_nul(b"/memory\0").unwrap();
+ let memory_device_type = CStr::from_bytes_with_nul(b"memory\0").unwrap();
- if let Some(node) = self.node(memory)? {
- if node.device_type()? != Some(device_type) {
- return Err(FdtError::BadValue);
- }
- let reg = node.reg()?.ok_or(FdtError::BadValue)?;
-
- Ok(Some(MemRegIterator::new(reg)))
- } else {
- Ok(None)
+ let node = self.node(memory_node_name)?.ok_or(FdtError::NotFound)?;
+ if node.device_type()? != Some(memory_device_type) {
+ return Err(FdtError::BadValue);
}
+ node.reg()?.ok_or(FdtError::BadValue).map(MemRegIterator::new)
+ }
+
+ /// Returns the first memory range in the `/memory` node.
+ pub fn first_memory_range(&self) -> Result<Range<usize>> {
+ self.memory()?.next().ok_or(FdtError::NotFound)
}
/// Retrieve the standard /chosen node.
diff --git a/libs/libfdt/tests/api_test.rs b/libs/libfdt/tests/api_test.rs
index d0feb98..806e6c0 100644
--- a/libs/libfdt/tests/api_test.rs
+++ b/libs/libfdt/tests/api_test.rs
@@ -16,18 +16,57 @@
//! Integration tests of the library libfdt.
-use libfdt::Fdt;
+use libfdt::{Fdt, FdtError};
use std::fs;
use std::ops::Range;
-const TEST_TREE1_PATH: &str = "data/test_tree1.dtb";
+const TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH: &str = "data/test_tree_one_memory_range.dtb";
+const TEST_TREE_WITH_MULTIPLE_MEMORY_RANGES_PATH: &str =
+ "data/test_tree_multiple_memory_ranges.dtb";
+const TEST_TREE_WITH_EMPTY_MEMORY_RANGE_PATH: &str = "data/test_tree_empty_memory_range.dtb";
+const TEST_TREE_WITH_NO_MEMORY_NODE_PATH: &str = "data/test_tree_no_memory_node.dtb";
#[test]
-fn parse_well_formed_fdt_successfully() {
- let data = fs::read(TEST_TREE1_PATH).unwrap();
+fn retrieving_memory_from_fdt_with_one_memory_range_succeeds() {
+ let data = fs::read(TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH).unwrap();
let fdt = Fdt::from_slice(&data).unwrap();
const EXPECTED_FIRST_MEMORY_RANGE: Range<usize> = 0..256;
- let mut memory = fdt.memory().unwrap().unwrap();
+ let mut memory = fdt.memory().unwrap();
assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
+ assert!(memory.next().is_none());
+ assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
+}
+
+#[test]
+fn retrieving_memory_from_fdt_with_multiple_memory_ranges_succeeds() {
+ let data = fs::read(TEST_TREE_WITH_MULTIPLE_MEMORY_RANGES_PATH).unwrap();
+ let fdt = Fdt::from_slice(&data).unwrap();
+
+ const EXPECTED_FIRST_MEMORY_RANGE: Range<usize> = 0..256;
+ const EXPECTED_SECOND_MEMORY_RANGE: Range<usize> = 512..1024;
+ let mut memory = fdt.memory().unwrap();
+ assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
+ assert_eq!(memory.next(), Some(EXPECTED_SECOND_MEMORY_RANGE));
+ assert!(memory.next().is_none());
+ assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
+}
+
+#[test]
+fn retrieving_first_memory_from_fdt_with_empty_memory_range_fails() {
+ let data = fs::read(TEST_TREE_WITH_EMPTY_MEMORY_RANGE_PATH).unwrap();
+ let fdt = Fdt::from_slice(&data).unwrap();
+
+ let mut memory = fdt.memory().unwrap();
+ assert!(memory.next().is_none());
+ assert_eq!(fdt.first_memory_range(), Err(FdtError::NotFound));
+}
+
+#[test]
+fn retrieving_memory_from_fdt_with_no_memory_node_fails() {
+ let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
+ let fdt = Fdt::from_slice(&data).unwrap();
+
+ assert_eq!(fdt.memory().unwrap_err(), FdtError::NotFound);
+ assert_eq!(fdt.first_memory_range(), Err(FdtError::NotFound));
}
diff --git a/libs/libfdt/tests/data/test_tree_empty_memory_range.dts b/libs/libfdt/tests/data/test_tree_empty_memory_range.dts
new file mode 100644
index 0000000..c263ff3
--- /dev/null
+++ b/libs/libfdt/tests/data/test_tree_empty_memory_range.dts
@@ -0,0 +1,8 @@
+/include/ "test_tree_no_memory_node.dts"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <>;
+ };
+};
diff --git a/libs/libfdt/tests/data/test_tree_multiple_memory_ranges.dts b/libs/libfdt/tests/data/test_tree_multiple_memory_ranges.dts
new file mode 100644
index 0000000..b2ded7f
--- /dev/null
+++ b/libs/libfdt/tests/data/test_tree_multiple_memory_ranges.dts
@@ -0,0 +1,8 @@
+/include/ "test_tree_no_memory_node.dts"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x100 0x200 0x200>;
+ };
+};
diff --git a/libs/libfdt/tests/data/test_tree1.dts b/libs/libfdt/tests/data/test_tree_no_memory_node.dts
similarity index 89%
rename from libs/libfdt/tests/data/test_tree1.dts
rename to libs/libfdt/tests/data/test_tree_no_memory_node.dts
index 222b0b1..35e02cd 100644
--- a/libs/libfdt/tests/data/test_tree1.dts
+++ b/libs/libfdt/tests/data/test_tree_no_memory_node.dts
@@ -33,11 +33,6 @@
};
};
- memory {
- device_type = "memory";
- reg = <0x0 0x100>;
- };
-
chosen {
};
};
diff --git a/libs/libfdt/tests/data/test_tree_one_memory_range.dts b/libs/libfdt/tests/data/test_tree_one_memory_range.dts
new file mode 100644
index 0000000..7f863b3
--- /dev/null
+++ b/libs/libfdt/tests/data/test_tree_one_memory_range.dts
@@ -0,0 +1,8 @@
+/include/ "test_tree_no_memory_node.dts"
+
+/ {
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x100>;
+ };
+};