FlattenedDeviceTree.h 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright (c) 2021-2023, Andrew Kaster <akaster@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Endian.h>
  8. #include <AK/Error.h>
  9. #include <AK/Function.h>
  10. #include <AK/IterationDecision.h>
  11. #include <AK/StringView.h>
  12. #include <AK/Types.h>
  13. namespace DeviceTree {
  14. // https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html
  15. struct FlattenedDeviceTreeHeader {
  16. BigEndian<u32> magic; // 0xDOODFEED (BE)
  17. BigEndian<u32> totalsize; // Total size of entire blob including padding b/w and after fields
  18. BigEndian<u32> off_dt_struct; // Offset of StructureBlock from beginning of header
  19. // https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#sect-fdt-structure-block
  20. BigEndian<u32> off_dt_strings; // Offset of StringsBlock from beginning of header
  21. // https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#sect-fdt-strings-block
  22. BigEndian<u32> off_mem_rsvmap; // Offset of MemoryReservationBlock from beginning of header
  23. BigEndian<u32> version; // 0.3 spec defines version 17
  24. BigEndian<u32> last_comp_version; // 0.3 spec back-compatible with version 16, mandated to be 16
  25. BigEndian<u32> boot_cpuid_phys; // Physical ID given in `reg` property of CPU node of boot cpu
  26. BigEndian<u32> size_dt_strings; // Length in bytes of StringsBlock
  27. BigEndian<u32> size_dt_struct; // Length in bytes of StructureBlock
  28. };
  29. static_assert(sizeof(FlattenedDeviceTreeHeader) == 40, "FDT Header size must match specification");
  30. // https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#format
  31. struct FlattenedDeviceTreeReserveEntry {
  32. BigEndian<u64> address;
  33. BigEndian<u64> size;
  34. bool operator==(FlattenedDeviceTreeReserveEntry const& other) const { return other.address == address && other.size == size; }
  35. };
  36. static_assert(sizeof(FlattenedDeviceTreeReserveEntry) == 16, "FDT Memory Reservation entry size must match specification");
  37. // https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html#lexical-structure
  38. enum FlattenedDeviceTreeTokenType : u32 {
  39. BeginNode = 1,
  40. EndNode = 2,
  41. Property = 3,
  42. NoOp = 4,
  43. End = 9
  44. };
  45. struct DeviceTreeCallbacks {
  46. Function<ErrorOr<IterationDecision>(StringView)> on_node_begin;
  47. Function<ErrorOr<IterationDecision>(StringView)> on_node_end;
  48. Function<ErrorOr<IterationDecision>(StringView, ReadonlyBytes)> on_property;
  49. Function<ErrorOr<IterationDecision>()> on_noop;
  50. Function<ErrorOr<void>()> on_end;
  51. };
  52. ErrorOr<void> walk_device_tree(FlattenedDeviceTreeHeader const&, ReadonlyBytes raw_device_tree, DeviceTreeCallbacks);
  53. template<typename T>
  54. ErrorOr<T> slow_get_property(StringView name, FlattenedDeviceTreeHeader const&, ReadonlyBytes raw_device_tree);
  55. extern template ErrorOr<void> slow_get_property(StringView name, FlattenedDeviceTreeHeader const& header, ReadonlyBytes raw_device_tree);
  56. extern template ErrorOr<u32> slow_get_property(StringView name, FlattenedDeviceTreeHeader const& header, ReadonlyBytes raw_device_tree);
  57. extern template ErrorOr<u64> slow_get_property(StringView name, FlattenedDeviceTreeHeader const& header, ReadonlyBytes raw_device_tree);
  58. extern template ErrorOr<StringView> slow_get_property(StringView name, FlattenedDeviceTreeHeader const& header, ReadonlyBytes raw_device_tree);
  59. } // namespace DeviceTree