Skip to main content

fdt_raw/
define.rs

1//! Core type definitions and constants for FDT parsing.
2//!
3//! This module provides fundamental types used throughout the FDT parser,
4//! including the magic number constant, tokens for parsing the structure
5//! block, error types, and common enums.
6
7use core::{
8    ffi::FromBytesUntilNulError,
9    fmt::{Debug, Display},
10    ops::Deref,
11};
12
13/// The magic number that identifies a valid Flattened Device Tree blob.
14///
15/// This value (0xd00dfeed) must be present at the beginning of any
16/// valid device tree blob. It is used for validation when parsing.
17pub const FDT_MAGIC: u32 = 0xd00dfeed;
18
19/// Entry in the memory reservation block.
20///
21/// The memory reservation block contains a list of physical memory regions
22/// that must be preserved (not used by the OS) during boot. Each entry
23/// specifies the starting address and size of a reserved region.
24#[derive(Clone, Debug, Default)]
25pub struct MemoryReservation {
26    /// Physical address of the reserved region
27    pub address: u64,
28    /// Size of the reserved region in bytes
29    pub size: u64,
30}
31
32/// Token type for parsing the FDT structure block.
33///
34/// The device tree structure block is composed of a sequence of 32-bit
35/// tokens followed by data. This enum represents the possible token values.
36#[derive(Debug, PartialEq, Eq, Clone, Copy)]
37pub enum Token {
38    /// Marks the beginning of a node (FDT_BEGIN_NODE, 0x00000001)
39    BeginNode,
40    /// Marks the end of a node (FDT_END_NODE, 0x00000002)
41    EndNode,
42    /// Marks a property (FDT_PROP, 0x00000003)
43    Prop,
44    /// No-op token, should be ignored (FDT_NOP, 0x00000004)
45    Nop,
46    /// Marks the end of the structure block (FDT_END, 0x00000009)
47    End,
48    /// Any other 32-bit value (invalid or unknown token)
49    Data(u32),
50}
51
52impl From<u32> for Token {
53    fn from(value: u32) -> Self {
54        match value {
55            0x1 => Token::BeginNode,
56            0x2 => Token::EndNode,
57            0x3 => Token::Prop,
58            0x4 => Token::Nop,
59            0x9 => Token::End,
60            _ => Token::Data(value),
61        }
62    }
63}
64
65impl From<Token> for u32 {
66    fn from(value: Token) -> Self {
67        match value {
68            Token::BeginNode => 0x1,
69            Token::EndNode => 0x2,
70            Token::Prop => 0x3,
71            Token::Nop => 0x4,
72            Token::End => 0x9,
73            Token::Data(v) => v,
74        }
75    }
76}
77
78/// Device tree node status property value.
79///
80/// The `status` property in a device tree indicates whether a node is
81/// enabled or disabled. A disabled node should generally be ignored by
82/// the OS, though the node may still be probed if explicitly requested.
83#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
84pub enum Status {
85    /// Node is operational and should be used ("okay")
86    Okay,
87    /// Node is disabled and should not be used ("disabled")
88    Disabled,
89}
90
91impl Deref for Status {
92    type Target = str;
93
94    fn deref(&self) -> &Self::Target {
95        match self {
96            Status::Okay => "okay",
97            Status::Disabled => "disabled",
98        }
99    }
100}
101
102impl core::fmt::Display for Status {
103    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104        write!(f, "{}", self.deref())
105    }
106}
107
108/// A phandle (pointer handle) for referencing device tree nodes.
109///
110/// Phandles provide a way for nodes to reference other nodes in the device tree.
111/// A node that may be referenced defines a `phandle` property with a unique value,
112/// and other nodes reference it using that value in properties like `interrupt-parent`.
113#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
114#[repr(transparent)]
115pub struct Phandle(u32);
116
117impl From<u32> for Phandle {
118    fn from(value: u32) -> Self {
119        Self(value)
120    }
121}
122
123impl Phandle {
124    /// Returns the phandle value as a `usize`.
125    pub fn as_usize(&self) -> usize {
126        self.0 as usize
127    }
128
129    /// Returns the raw u32 value of this phandle.
130    pub fn raw(&self) -> u32 {
131        self.0
132    }
133}
134
135impl Display for Phandle {
136    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
137        write!(f, "<{:#x}>", self.0)
138    }
139}
140
141/// Errors that can occur during FDT parsing.
142///
143/// This enum represents all possible error conditions that may be encountered
144/// when parsing a device tree blob or accessing its contents.
145#[derive(thiserror::Error, Debug, Clone)]
146pub enum FdtError {
147    /// A requested item (node, property, etc.) was not found
148    #[error("not found")]
149    NotFound,
150    /// The buffer is too small to read the requested data at the given position
151    #[error("buffer too small at position {pos}")]
152    BufferTooSmall {
153        /// The position at which the buffer was too small
154        pos: usize,
155    },
156    /// The FDT magic number doesn't match the expected value
157    #[error("invalid magic number {0:#x} != {FDT_MAGIC:#x}")]
158    InvalidMagic(u32),
159    /// An invalid pointer was provided
160    #[error("invalid pointer")]
161    InvalidPtr,
162    /// The input data is invalid or malformed
163    #[error("invalid input")]
164    InvalidInput,
165    /// A null-terminated string was expected but not found
166    #[error("data provided does not contain a nul")]
167    FromBytesUntilNull,
168    /// Failed to parse data as a UTF-8 string
169    #[error("{0}")]
170    Utf8Error(#[from] core::str::Utf8Error),
171    /// The specified alias was not found in the /aliases node
172    #[error("no aliase `{0}` found")]
173    NoAlias(&'static str),
174    /// Memory allocation failed
175    #[error("system out of memory")]
176    NoMemory,
177    /// The specified node was not found
178    #[error("node `{0}` not found")]
179    NodeNotFound(&'static str),
180    /// The specified property was not found
181    #[error("property `{0}` not found")]
182    PropertyNotFound(&'static str),
183}
184
185impl From<FromBytesUntilNulError> for FdtError {
186    fn from(_: FromBytesUntilNulError) -> Self {
187        FdtError::FromBytesUntilNull
188    }
189}