• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Iterators over cells, and various layers on top of them.
16 
17 use crate::{AddrCells, SizeCells};
18 use core::marker::PhantomData;
19 use core::{mem::size_of, ops::Range, slice::ChunksExact};
20 
21 /// Iterator over cells of a DT property.
22 #[derive(Debug)]
23 pub struct CellIterator<'a> {
24     chunks: ChunksExact<'a, u8>,
25 }
26 
27 impl<'a> CellIterator<'a> {
new(bytes: &'a [u8]) -> Self28     pub(crate) fn new(bytes: &'a [u8]) -> Self {
29         const CHUNK_SIZE: usize = size_of::<<CellIterator as Iterator>::Item>();
30 
31         Self { chunks: bytes.chunks_exact(CHUNK_SIZE) }
32     }
33 }
34 
35 impl<'a> Iterator for CellIterator<'a> {
36     type Item = u32;
37 
next(&mut self) -> Option<Self::Item>38     fn next(&mut self) -> Option<Self::Item> {
39         Some(Self::Item::from_be_bytes(self.chunks.next()?.try_into().ok()?))
40     }
41 }
42 
43 /// Iterator over a 'reg' property of a DT node.
44 #[derive(Debug)]
45 pub struct RegIterator<'a> {
46     cells: CellIterator<'a>,
47     addr_cells: AddrCells,
48     size_cells: SizeCells,
49 }
50 
51 /// Represents a contiguous region within the address space defined by the parent bus.
52 /// Commonly means the offsets and lengths of MMIO blocks, but may have a different meaning on some
53 /// bus types. Addresses in the address space defined by the root node are CPU real addresses.
54 #[derive(Copy, Clone, Debug)]
55 pub struct Reg<T> {
56     /// Base address of the region.
57     pub addr: T,
58     /// Size of the region (optional).
59     pub size: Option<T>,
60 }
61 
62 impl<'a> RegIterator<'a> {
new( cells: CellIterator<'a>, addr_cells: AddrCells, size_cells: SizeCells, ) -> Self63     pub(crate) fn new(
64         cells: CellIterator<'a>,
65         addr_cells: AddrCells,
66         size_cells: SizeCells,
67     ) -> Self {
68         Self { cells, addr_cells, size_cells }
69     }
70 }
71 
72 impl<'a> Iterator for RegIterator<'a> {
73     type Item = Reg<u64>;
74 
next(&mut self) -> Option<Self::Item>75     fn next(&mut self) -> Option<Self::Item> {
76         let addr = FromAddrCells::from_addr_cells(&mut self.cells, self.addr_cells)?;
77         // If the parent node specifies a value of 0 for #size-cells, 'size' shall be omitted.
78         let size = if self.size_cells == SizeCells::None {
79             None
80         } else {
81             Some(FromSizeCells::from_size_cells(&mut self.cells, self.size_cells)?)
82         };
83 
84         Some(Self::Item { addr, size })
85     }
86 }
87 
88 // Converts two cells into bytes of the same size
two_cells_to_bytes(cells: [u32; 2]) -> [u8; 2 * size_of::<u32>()]89 fn two_cells_to_bytes(cells: [u32; 2]) -> [u8; 2 * size_of::<u32>()] {
90     // SAFETY: the size of the two arrays are the same
91     unsafe { core::mem::transmute::<[u32; 2], [u8; 2 * size_of::<u32>()]>(cells) }
92 }
93 
94 impl Reg<u64> {
95     const NUM_CELLS: usize = 2;
96     /// Converts addr and (optional) size to the format that is consumable by libfdt.
to_cells( &self, ) -> ([u8; Self::NUM_CELLS * size_of::<u32>()], Option<[u8; Self::NUM_CELLS * size_of::<u32>()]>)97     pub fn to_cells(
98         &self,
99     ) -> ([u8; Self::NUM_CELLS * size_of::<u32>()], Option<[u8; Self::NUM_CELLS * size_of::<u32>()]>)
100     {
101         let addr =
102             two_cells_to_bytes([((self.addr >> 32) as u32).to_be(), (self.addr as u32).to_be()]);
103         let size = if self.size.is_some() {
104             let size = self.size.unwrap();
105             Some(two_cells_to_bytes([((size >> 32) as u32).to_be(), (size as u32).to_be()]))
106         } else {
107             None
108         };
109         (addr, size)
110     }
111 }
112 
113 /// Iterator over the address ranges defined by the /memory/ node.
114 #[derive(Debug)]
115 pub struct MemRegIterator<'a> {
116     reg: RegIterator<'a>,
117 }
118 
119 impl<'a> MemRegIterator<'a> {
new(reg: RegIterator<'a>) -> Self120     pub(crate) fn new(reg: RegIterator<'a>) -> Self {
121         Self { reg }
122     }
123 }
124 
125 impl<'a> Iterator for MemRegIterator<'a> {
126     type Item = Range<usize>;
127 
next(&mut self) -> Option<Self::Item>128     fn next(&mut self) -> Option<Self::Item> {
129         let next = self.reg.next()?;
130         let addr = usize::try_from(next.addr).ok()?;
131         let size = usize::try_from(next.size?).ok()?;
132 
133         Some(addr..addr.checked_add(size)?)
134     }
135 }
136 
137 /// Iterator over the 'ranges' property of a DT node.
138 #[derive(Debug)]
139 pub struct RangesIterator<'a, A, P, S> {
140     cells: CellIterator<'a>,
141     addr_cells: AddrCells,
142     parent_addr_cells: AddrCells,
143     size_cells: SizeCells,
144     _addr: PhantomData<A>,
145     _parent_addr: PhantomData<P>,
146     _size: PhantomData<S>,
147 }
148 
149 /// An address range from the 'ranges' property of a DT node.
150 #[derive(Clone, Debug, Default)]
151 pub struct AddressRange<A, P, S> {
152     /// The physical address of the range within the child bus's address space.
153     pub addr: A,
154     /// The physical address of the range in the parent bus's address space.
155     pub parent_addr: P,
156     /// The size of the range in the child's address space.
157     pub size: S,
158 }
159 
160 impl<'a, A, P, S> RangesIterator<'a, A, P, S> {
new( cells: CellIterator<'a>, addr_cells: AddrCells, parent_addr_cells: AddrCells, size_cells: SizeCells, ) -> Self161     pub(crate) fn new(
162         cells: CellIterator<'a>,
163         addr_cells: AddrCells,
164         parent_addr_cells: AddrCells,
165         size_cells: SizeCells,
166     ) -> Self {
167         Self {
168             cells,
169             addr_cells,
170             parent_addr_cells,
171             size_cells,
172             _addr: Default::default(),
173             _parent_addr: Default::default(),
174             _size: Default::default(),
175         }
176     }
177 }
178 
179 impl<'a, A: FromAddrCells, P: FromAddrCells, S: FromSizeCells> Iterator
180     for RangesIterator<'a, A, P, S>
181 {
182     type Item = AddressRange<A, P, S>;
183 
next(&mut self) -> Option<Self::Item>184     fn next(&mut self) -> Option<Self::Item> {
185         let addr = FromAddrCells::from_addr_cells(&mut self.cells, self.addr_cells)?;
186         let parent_addr = FromAddrCells::from_addr_cells(&mut self.cells, self.parent_addr_cells)?;
187         let size = FromSizeCells::from_size_cells(&mut self.cells, self.size_cells)?;
188         Some(AddressRange { addr, parent_addr, size })
189     }
190 }
191 
192 trait FromAddrCells: Sized {
from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self>193     fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self>;
194 }
195 
196 impl FromAddrCells for u64 {
from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self>197     fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self> {
198         Some(match cell_count {
199             AddrCells::Single => cells.next()?.into(),
200             AddrCells::Double => (cells.next()? as Self) << 32 | cells.next()? as Self,
201             _ => panic!("Invalid addr_cells {:?} for u64", cell_count),
202         })
203     }
204 }
205 
206 impl FromAddrCells for (u32, u64) {
from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self>207     fn from_addr_cells(cells: &mut CellIterator, cell_count: AddrCells) -> Option<Self> {
208         Some(match cell_count {
209             AddrCells::Triple => {
210                 (cells.next()?, (cells.next()? as u64) << 32 | cells.next()? as u64)
211             }
212             _ => panic!("Invalid addr_cells {:?} for (u32, u64)", cell_count),
213         })
214     }
215 }
216 
217 trait FromSizeCells: Sized {
from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self>218     fn from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self>;
219 }
220 
221 impl FromSizeCells for u64 {
from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self>222     fn from_size_cells(cells: &mut CellIterator, cell_count: SizeCells) -> Option<Self> {
223         Some(match cell_count {
224             SizeCells::Single => cells.next()?.into(),
225             SizeCells::Double => (cells.next()? as Self) << 32 | cells.next()? as Self,
226             _ => panic!("Invalid size_cells {:?} for u64", cell_count),
227         })
228     }
229 }
230 
231 impl AddressRange<(u32, u64), u64, u64> {
232     const SIZE_CELLS: usize = 7;
233     /// Converts to the format that is consumable by libfdt
to_cells(&self) -> [u8; Self::SIZE_CELLS * size_of::<u32>()]234     pub fn to_cells(&self) -> [u8; Self::SIZE_CELLS * size_of::<u32>()] {
235         let buf = [
236             self.addr.0.to_be(),
237             ((self.addr.1 >> 32) as u32).to_be(),
238             (self.addr.1 as u32).to_be(),
239             ((self.parent_addr >> 32) as u32).to_be(),
240             (self.parent_addr as u32).to_be(),
241             ((self.size >> 32) as u32).to_be(),
242             (self.size as u32).to_be(),
243         ];
244         // SAFETY: the size of the two arrays are the same
245         unsafe {
246             core::mem::transmute::<[u32; Self::SIZE_CELLS], [u8; Self::SIZE_CELLS * size_of::<u32>()]>(
247                 buf,
248             )
249         }
250     }
251 }
252