/* fdt.h * * Functions to help with flattened device tree (DTB) parsing * * * Copyright (C) 2023 wolfSSL Inc. * * This file is part of wolfBoot. * * wolfBoot is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef FDT_H #define FDT_H #ifdef __cplusplus extern "C" { #endif #include #define FDT_MAGIC 0xD00DFEEDUL #define FDT_SW_MAGIC (uint32_t)(~FDT_MAGIC) /* marker for run-time creation/edit of FDT */ struct fdt_header { 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; }; struct fdt_reserve_entry { uint64_t address; uint64_t size; }; struct fdt_prop { uint32_t len; uint32_t nameoff; }; struct fdt_node_header { uint32_t tag; char name[0]; }; struct fdt_property { uint32_t tag; uint32_t len; uint32_t nameoff; char data[0]; }; #define FDT_TAGSIZE sizeof(uint32_t) #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) #define FDT_FIRST_SUPPORTED_VERSION 0x10 #define FDT_LAST_SUPPORTED_VERSION 0x11 #define FDT_BEGIN_NODE 0x00000001UL #define FDT_END_NODE 0x00000002UL #define FDT_PROP 0x00000003UL #define FDT_NOP 0x00000004UL #define FDT_END 0x00000009UL #define FDT_ERR_BADMAGIC 1 #define FDT_ERR_BADVERSION 2 #define FDT_ERR_BADSTRUCTURE 3 #define FDT_ERR_BADOFFSET 4 #define FDT_ERR_BADSTATE 5 #define FDT_ERR_NOTFOUND 6 #define FDT_ERR_NOSPACE 7 #define FDT_ERR_TRUNCATED 8 #define FDT_ERR_INTERNAL 9 #define FDT_ERR_EXISTS 10 #define FDT_PCI_PREFETCH (0x40000000) #define FDT_PCI_MEM32 (0x02000000) #define FDT_PCI_IO (0x01000000) #define FDT_PCI_MEM64 (0x03000000) uint32_t cpu_to_fdt32(uint32_t x); uint64_t cpu_to_fdt64(uint64_t x); uint32_t fdt32_to_cpu(uint32_t x); uint64_t fdt64_to_cpu(uint64_t x); #define fdt_get_header(fdt, field) (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) #define fdt_version(fdt) (fdt_get_header(fdt, version)) #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) #define fdt_set_header(fdt, field, val) (((struct fdt_header *)fdt)->field = cpu_to_fdt32(val)) #define fdt_set_magic(fdt, val) (fdt_set_header(fdt, magic, (val))) #define fdt_set_totalsize(fdt, val) (fdt_set_header(fdt, totalsize, (val))) #define fdt_set_off_dt_struct(fdt, val) (fdt_set_header(fdt, off_dt_struct, (val))) #define fdt_set_off_dt_strings(fdt, val) (fdt_set_header(fdt, off_dt_strings, (val))) #define fdt_set_off_mem_rsvmap(fdt, val) (fdt_set_header(fdt, off_mem_rsvmap, (val))) #define fdt_set_version(fdt, val) (fdt_set_header(fdt, version, (val))) #define fdt_set_last_comp_version(fdt, val) (fdt_set_header(fdt, last_comp_version, (val))) #define fdt_set_boot_cpuid_phys(fdt, val) (fdt_set_header(fdt, boot_cpuid_phys, (val))) #define fdt_set_size_dt_strings(fdt, val) (fdt_set_header(fdt, size_dt_strings, (val))) #define fdt_set_size_dt_struct(fdt, val) (fdt_set_header(fdt, size_dt_struct, (val))) int fdt_check_header(const void *fdt); int fdt_next_node(const void *fdt, int offset, int *depth); int fdt_first_property_offset(const void *fdt, int nodeoffset); int fdt_next_property_offset(const void *fdt, int offset); const struct fdt_property *fdt_get_property_by_offset(const void *fdt, int offset, int *lenp); const char* fdt_get_name(const void *fdt, int nodeoffset, int *len); const char* fdt_get_string(const void *fdt, int stroffset, int *lenp); const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp); int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len); int fdt_find_devtype(void* fdt, int startoff, const char* node); int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible); int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible); int fdt_add_subnode(void* fdt, int parentoff, const char* name); int fdt_del_node(void *fdt, int nodeoffset); /* helpers to fix/append a property to a node */ int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str); int fdt_fixup_val(void* fdt, int off, const char* node, const char* name, uint32_t val); int fdt_fixup_val64(void* fdt, int off, const char* node, const char* name, uint64_t val); int fdt_shrink(void* fdt); #ifdef __cplusplus } #endif #endif /* !FDT_H */