/* * UniversalisOS minimal Flattened Device Tree (FDT/DTB) reader (MP0). * * QEMU aarch64 virt and the STM32MP257/i.MX8MP all pass a DTB (device tree * blob) describing the hardware: GIC base, CNTFRQ, UART, memory, etc. This * minimal reader walks the DTB structure (not libfdt — we're freestanding) to * extract the few fields the early boot needs: memory range, GIC distributor/ * CPU interface bases, UART base, and the timer frequency. * * The DTB binary format: a header (magic, totalsize, off_dt_struct, off_dt_strings, * ...), then a structure block (tokens: FDT_BEGIN_NODE, FDT_PROP, FDT_END_NODE, * FDT_END) and a strings block (NUL-terminated property name strings). */ #ifndef UOS_FDT_READER_H #define UOS_FDT_READER_H #include #define FDT_MAGIC 0xedfe0dd0 /* "0xd00dfeed" in little-endian word */ typedef struct { uint32_t magic; uint32_t totalsize; uint32_t off_dt_struct; uint32_t off_dt_strings; uint32_t off_mem_rsvmap; uint32_t version; uint32_t last_comp_version; uint32_t boot_cpuid_phys; uint32_t size_dt_strings; uint32_t size_dt_struct; } fdt_header_t; /* Tokens in the structure block. */ #define FDT_BEGIN_NODE 0x00000001 #define FDT_END_NODE 0x00000002 #define FDT_PROP 0x00000003 #define FDT_NOP 0x00000004 #define FDT_END 0x00000009 /* Result of an FDT lookup. */ typedef struct { uint64_t addr; /* address of the property value in the DTB */ uint32_t len; /* length of the property value */ } fdt_prop_t; /* Validate the DTB magic at `dtb`. Returns 0 if valid. */ int fdt_check(const void* dtb); /* Find a property `name` under the node path "node_name" (e.g. "gic" or "uart"). * Returns 0 + fills `out` on success, -1 if not found. */ int fdt_get_prop(const void* dtb, const char* node_name, const char* prop_name, fdt_prop_t* out); /* Convenience: read a #address-cells/ pair as a 64-bit address. */ uint64_t fdt_read_addr(const void* dtb, const char* node_name); /* Convenience: read the /memory/reg node → RAM base + size. */ void fdt_get_memory(const void* dtb, uint64_t* base, uint64_t* size); /* Convenience: read the timer frequency from /timer or the firmware. */ uint32_t fdt_get_cntfrq(const void* dtb); #endif /* UOS_FDT_READER_H */