summaryrefslogtreecommitdiff
path: root/tools/src/adt.h
diff options
context:
space:
mode:
Diffstat (limited to 'tools/src/adt.h')
-rw-r--r--tools/src/adt.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/tools/src/adt.h b/tools/src/adt.h
new file mode 100644
index 0000000..6373c86
--- /dev/null
+++ b/tools/src/adt.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+
+#ifndef XDT_H
+#define XDT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "types.h"
+
+#define ADT_ERR_NOTFOUND 1
+#define ADT_ERR_BADOFFSET 4
+#define ADT_ERR_BADPATH 5
+#define ADT_ERR_BADNCELLS 14
+#define ADT_ERR_BADVALUE 15
+#define ADT_ERR_BADLENGTH 20
+
+#define ADT_ALIGN 4
+
+extern void *adt;
+
+struct adt_property {
+ char name[32];
+ u32 size;
+ u8 value[];
+};
+
+struct adt_node_hdr {
+ u32 property_count;
+ u32 child_count;
+};
+
+#define ADT_NODE(adt, offset) ((const struct adt_node_hdr *)(((u8 *)(adt)) + (offset)))
+#define ADT_PROP(adt, offset) ((const struct adt_property *)(((u8 *)(adt)) + (offset)))
+#define ADT_SIZE(node) ((node)->size & 0x7fffffff)
+
+/* This API is designed to match libfdt's read-only API */
+
+/* Basic sanity check */
+int adt_check_header(const void *adt);
+
+static inline int adt_get_property_count(const void *adt, int offset)
+{
+ return ADT_NODE(adt, offset)->property_count;
+}
+
+static inline int adt_first_property_offset(const void *adt, int offset)
+{
+ UNUSED(adt);
+ return offset + sizeof(struct adt_node_hdr);
+}
+
+static inline int adt_next_property_offset(const void *adt, int offset)
+{
+ const struct adt_property *prop = ADT_PROP(adt, offset);
+ return offset + sizeof(struct adt_property) + ((prop->size + ADT_ALIGN - 1) & ~(ADT_ALIGN - 1));
+}
+
+static inline const struct adt_property *adt_get_property_by_offset(const void *adt, int offset)
+{
+ return ADT_PROP(adt, offset);
+}
+
+static inline int adt_get_child_count(const void *adt, int offset)
+{
+ return ADT_NODE(adt, offset)->child_count;
+}
+
+int adt_first_child_offset(const void *adt, int offset);
+int adt_next_sibling_offset(const void *adt, int offset);
+
+int adt_subnode_offset_namelen(const void *adt, int parentoffset, const char *name, size_t namelen);
+int adt_subnode_offset(const void *adt, int parentoffset, const char *name);
+int adt_path_offset(const void *adt, const char *path);
+int adt_path_offset_trace(const void *adt, const char *path, int *offsets);
+
+const char *adt_get_name(const void *adt, int nodeoffset);
+const struct adt_property *adt_get_property_namelen(const void *adt, int nodeoffset,
+ const char *name, size_t namelen);
+const struct adt_property *adt_get_property(const void *adt, int nodeoffset, const char *name);
+const void *adt_getprop_by_offset(const void *adt, int offset, const char **namep, u32 *lenp);
+const void *adt_getprop_namelen(const void *adt, int nodeoffset, const char *name, size_t namelen,
+ u32 *lenp);
+const void *adt_getprop(const void *adt, int nodeoffset, const char *name, u32 *lenp);
+int adt_setprop(void *adt, int nodeoffset, const char *name, void *value, size_t len);
+int adt_getprop_copy(const void *adt, int nodeoffset, const char *name, void *out, size_t len);
+
+#define ADT_GETPROP(adt, nodeoffset, name, val) \
+ adt_getprop_copy(adt, nodeoffset, name, (val), sizeof(*(val)))
+
+#define ADT_GETPROP_ARRAY(adt, nodeoffset, name, arr) \
+ adt_getprop_copy(adt, nodeoffset, name, (arr), sizeof(arr))
+
+int adt_get_reg(const void *adt, int *path, const char *prop, int idx, u64 *addr, u64 *size);
+bool adt_is_compatible(const void *adt, int nodeoffset, const char *compat);
+
+#define ADT_FOREACH_CHILD(adt, node) \
+ for (int _child_count = adt_get_child_count(adt, node); _child_count; _child_count = 0) \
+ for (node = adt_first_child_offset(adt, node); _child_count--; \
+ node = adt_next_sibling_offset(adt, node))
+
+#define ADT_FOREACH_PROPERTY(adt, node, prop) \
+ for (int _prop_count = adt_get_property_count(adt, node), \
+ _poff = adt_first_property_offset(adt, node); \
+ _prop_count; _prop_count = 0) \
+ for (const struct adt_property *prop = ADT_PROP(adt, _poff); _prop_count--; \
+ prop = ADT_PROP(adt, _poff = adt_next_property_offset(adt, _poff)))
+
+#endif