ladybird/Userland/Libraries/LibDeviceTree/FlattenedDeviceTree.h
Hediadyoin1 21a21c6a11 LibDeviceTree: Add a simple DeviceTree class
This makes it easier to work with device tree nodes and properties, then
writing simple state machines to parse the device tree.
This also makes the old slow traversal methods use the
DeviceTreeProperty helper class, and adds a simple test.
2024-02-24 16:43:44 -07:00

67 lines
2.9 KiB
C++

/*
* Copyright (c) 2021-2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Endian.h>
#include <AK/Error.h>
#include <AK/Function.h>
#include <AK/IterationDecision.h>
#include <AK/StringView.h>
#include <AK/Types.h>
#include "DeviceTree.h"
namespace DeviceTree {
// https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html
struct FlattenedDeviceTreeHeader {
BigEndian<u32> magic; // 0xDOODFEED (BE)
BigEndian<u32> totalsize; // Total size of entire blob including padding b/w and after fields
BigEndian<u32> off_dt_struct; // Offset of StructureBlock from beginning of header
// https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#sect-fdt-structure-block
BigEndian<u32> off_dt_strings; // Offset of StringsBlock from beginning of header
// https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#sect-fdt-strings-block
BigEndian<u32> off_mem_rsvmap; // Offset of MemoryReservationBlock from beginning of header
BigEndian<u32> version; // 0.3 spec defines version 17
BigEndian<u32> last_comp_version; // 0.3 spec back-compatible with version 16, mandated to be 16
BigEndian<u32> boot_cpuid_phys; // Physical ID given in `reg` property of CPU node of boot cpu
BigEndian<u32> size_dt_strings; // Length in bytes of StringsBlock
BigEndian<u32> size_dt_struct; // Length in bytes of StructureBlock
};
static_assert(sizeof(FlattenedDeviceTreeHeader) == 40, "FDT Header size must match specification");
// https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#format
struct FlattenedDeviceTreeReserveEntry {
BigEndian<u64> address;
BigEndian<u64> size;
bool operator==(FlattenedDeviceTreeReserveEntry const& other) const { return other.address == address && other.size == size; }
};
static_assert(sizeof(FlattenedDeviceTreeReserveEntry) == 16, "FDT Memory Reservation entry size must match specification");
// https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#lexical-structure
enum FlattenedDeviceTreeTokenType : u32 {
BeginNode = 1,
EndNode = 2,
Property = 3,
NoOp = 4,
End = 9
};
struct DeviceTreeCallbacks {
Function<ErrorOr<IterationDecision>(StringView)> on_node_begin;
Function<ErrorOr<IterationDecision>(StringView)> on_node_end;
Function<ErrorOr<IterationDecision>(StringView, ReadonlyBytes)> on_property;
Function<ErrorOr<IterationDecision>()> on_noop;
Function<ErrorOr<void>()> on_end;
};
ErrorOr<void> walk_device_tree(FlattenedDeviceTreeHeader const&, ReadonlyBytes raw_device_tree, DeviceTreeCallbacks);
ErrorOr<DeviceTreeProperty> slow_get_property(StringView name, FlattenedDeviceTreeHeader const&, ReadonlyBytes raw_device_tree);
} // namespace DeviceTree