63 lines
2.3 KiB
C
63 lines
2.3 KiB
C
/*
|
|
* 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 <stdint.h>
|
|
|
|
#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/<reg> 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 */
|