Sfoglia il codice sorgente

Handle `ranges` properties with an `#address-cells` of `3` (#16)

* Handle `ranges` properties with an `#address-cells` of `3`

* fix: correct tests + default to 0 for child high address

---------

Co-authored-by: Wesley Norris <repnop@outlook.com>
Isaac Woods 1 anno fa
parent
commit
d75fb57c9b
3 ha cambiato i file con 24 aggiunte e 12 eliminazioni
  1. 15 7
      src/node.rs
  2. 2 0
      src/standard_nodes.rs
  3. 7 5
      src/tests.rs

+ 15 - 7
src/node.rs

@@ -174,8 +174,10 @@ impl<'b, 'a: 'b> FdtNode<'b, 'a> {
     }
 
     pub fn ranges(self) -> Option<impl Iterator<Item = crate::MemoryRange> + 'a> {
-        let sizes = self.parent_cell_sizes();
-        if sizes.address_cells > 2 || sizes.size_cells > 2 {
+        let sizes = self.cell_sizes();
+        let parent_sizes = self.parent_cell_sizes();
+
+        if sizes.address_cells > 3 || sizes.size_cells > 2 || parent_sizes.size_cells > 2 {
             return None;
         }
 
@@ -184,13 +186,14 @@ impl<'b, 'a: 'b> FdtNode<'b, 'a> {
             if prop.name == "ranges" {
                 let mut stream = FdtData::new(prop.value);
                 ranges = Some(core::iter::from_fn(move || {
-                    let child_bus_address = match sizes.address_cells {
-                        1 => stream.u32()?.get() as usize,
-                        2 => stream.u64()?.get() as usize,
+                    let (child_bus_address_hi, child_bus_address) = match sizes.address_cells {
+                        1 => (0, stream.u32()?.get() as usize),
+                        2 => (0, stream.u64()?.get() as usize),
+                        3 => (stream.u32()?.get(), stream.u64()?.get() as usize),
                         _ => return None,
                     };
 
-                    let parent_bus_address = match sizes.address_cells {
+                    let parent_bus_address = match parent_sizes.address_cells {
                         1 => stream.u32()?.get() as usize,
                         2 => stream.u64()?.get() as usize,
                         _ => return None,
@@ -202,7 +205,12 @@ impl<'b, 'a: 'b> FdtNode<'b, 'a> {
                         _ => return None,
                     };
 
-                    Some(MemoryRange { child_bus_address, parent_bus_address, size })
+                    Some(MemoryRange {
+                        child_bus_address,
+                        child_bus_address_hi,
+                        parent_bus_address,
+                        size,
+                    })
                 }));
                 break;
             }

+ 2 - 0
src/standard_nodes.rs

@@ -340,6 +340,8 @@ pub struct MemoryRegion {
 pub struct MemoryRange {
     /// Starting address on child bus
     pub child_bus_address: usize,
+    /// The high bits of the child bus' starting address, if present
+    pub child_bus_address_hi: u32,
     /// Starting address on parent bus
     pub parent_bus_address: usize,
     /// Size of range

+ 7 - 5
src/tests.rs

@@ -62,14 +62,16 @@ fn parses_populated_ranges() {
         ranges,
         &[
             MemoryRange {
-                child_bus_address: 0x100_0000_0000_0000,
-                parent_bus_address: 0x0,
-                size: 0x300_0000_0000_0000
+                child_bus_address: 0x0000_0000_0000_0000,
+                child_bus_address_hi: 0x0100_0000,
+                parent_bus_address: 0x3000000,
+                size: 0x10000,
             },
             MemoryRange {
-                child_bus_address: 0x1_0000_0200_0000,
+                child_bus_address: 0x40000000,
+                child_bus_address_hi: 0x2000000,
                 parent_bus_address: 0x4000_0000,
-                size: 0x4000_0000
+                size: 0x4000_0000,
             }
         ]
     );