use crate::node::{Compatible, FdtNode, MemoryRegion, NodeProperty};
#[derive(Debug, Clone, Copy)]
pub struct Chosen<'a> {
pub(crate) node: FdtNode<'a>,
}
impl<'a> Chosen<'a> {
#[inline(always)]
pub fn bootargs(self) -> Option<&'a str> {
self.node.property("bootargs")?.as_str()
}
#[inline(always)]
pub fn stdout_path(self) -> Option<&'a str> {
self.node.property("stdout-path")?.as_str()
}
#[inline(always)]
pub fn stdin_path(self) -> Option<&'a str> {
self.node.property("stdin-path")?.as_str()
}
}
#[derive(Debug, Clone, Copy)]
pub struct Root<'a> {
pub(crate) node: FdtNode<'a>,
}
impl<'a> Root<'a> {
#[inline(always)]
pub fn model(self) -> Option<&'a str> {
self.node.property("model")?.as_str()
}
#[inline(always)]
pub fn compatible(self) -> Option<Compatible<'a>> {
self.node.compatible()
}
#[inline(always)]
pub fn properties(self) -> impl Iterator<Item = NodeProperty<'a>> {
self.node.properties()
}
#[inline(always)]
pub fn node(self) -> FdtNode<'a> {
self.node
}
}
#[derive(Debug, Clone, Copy)]
pub struct Cpu<'a> {
pub(crate) parent: FdtNode<'a>,
pub(crate) node: FdtNode<'a>,
}
impl<'a> Cpu<'a> {
#[moa_sec_macros::init]
#[allow(clippy::cast_possible_truncation)]
pub fn id(self) -> Option<usize> {
let address_cells = self.node.parent_cell_sizes().address_cells;
let prop = self.node.property("reg")?;
let mut stream = crate::parsing::FdtData::new(prop.value);
match address_cells {
1 => Some(stream.u32()? as usize),
2 => Some(stream.u64()? as usize),
_ => None,
}
}
#[inline(always)]
#[allow(clippy::cast_possible_truncation)]
pub fn clock_frequency(self) -> Option<usize> {
let prop = self
.node
.property("clock-frequency")
.or_else(|| self.parent.property("clock-frequency"))?;
prop.as_usize()
}
#[inline(always)]
#[allow(clippy::cast_possible_truncation)]
pub fn timebase_frequency(self) -> Option<usize> {
let prop = self
.node
.property("timebase-frequency")
.or_else(|| self.parent.property("timebase-frequency"))?;
prop.as_usize()
}
#[inline(always)]
pub fn properties(self) -> impl Iterator<Item = NodeProperty<'a>> {
self.node.properties()
}
#[inline(always)]
pub fn node(self) -> FdtNode<'a> {
self.node
}
}
#[derive(Clone, Copy)]
pub struct Memory<'a> {
pub(crate) structs: &'a [u8],
pub(crate) strings: &'a [u8],
}
impl<'a> Memory<'a> {
#[inline(always)]
pub fn regions(self) -> MemoryRegions<'a> {
MemoryRegions {
nodes: crate::node::AllNodes::new(self.structs, self.strings),
current: None,
}
}
}
pub struct MemoryRegions<'a> {
nodes: crate::node::AllNodes<'a>,
current: Option<crate::node::RegIter<'a>>,
}
impl Iterator for MemoryRegions<'_> {
type Item = MemoryRegion;
#[moa_sec_macros::init]
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(ref mut reg) = self.current {
if let Some(region) = reg.next() {
return Some(region);
}
self.current = None;
}
let n = self.nodes.next()?;
if n.name == "memory" || n.name.starts_with("memory@") {
self.current = n.reg();
}
}
}
}