use core::fmt::{self, Display, Formatter};
use core::ops::Deref;
use crate::error::{PropertyError, StandardError};
use crate::fdt::{Fdt, FdtNode};
use crate::{Cells, Node, Property};
impl<'a> Fdt<'a> {
pub fn cpus(self) -> Result<Cpus<FdtNode<'a>>, StandardError> {
let node = self.find_node("/cpus").ok_or(StandardError::CpusMissing)?;
Ok(Cpus { node })
}
}
#[derive(Clone, Copy, Debug)]
pub struct Cpus<N> {
node: N,
}
impl<N> Deref for Cpus<N> {
type Target = N;
fn deref(&self) -> &Self::Target {
&self.node
}
}
impl<N: Display> Display for Cpus<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.node.fmt(f)
}
}
impl<'a, N: Node<'a>> Cpus<N> {
pub fn cpus(&self) -> impl Iterator<Item = Cpu<N>> + use<'a, N> {
self.node.children().filter_map(|child| {
if child.name_without_address() == "cpu" {
Some(Cpu { node: child })
} else {
None
}
})
}
}
#[derive(Clone, Copy, Debug)]
pub struct Cpu<N> {
node: N,
}
impl<N> Deref for Cpu<N> {
type Target = N;
fn deref(&self) -> &Self::Target {
&self.node
}
}
impl<N: Display> Display for Cpu<N> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.node.fmt(f)
}
}
impl<'a, N: Node<'a>> Cpu<N> {
pub fn enable_method(&self) -> Option<impl Iterator<Item = &'a str>> {
Some(self.node.property("enable-method")?.as_str_list())
}
pub fn cpu_release_addr(&self) -> Result<Option<u64>, PropertyError> {
self.node
.property("cpu-release-addr")
.map(|value| value.as_u64())
.transpose()
}
}
impl<'a> Cpu<FdtNode<'a>> {
pub fn ids(&self) -> Result<impl Iterator<Item = Cells<'a>> + use<'a>, StandardError> {
Ok(self
.node
.reg()?
.ok_or(StandardError::CpuMissingReg)?
.map(|reg| reg.address))
}
}