aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/devicetree.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vppinfra/devicetree.h')
-rw-r--r--src/vppinfra/devicetree.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/vppinfra/devicetree.h b/src/vppinfra/devicetree.h
new file mode 100644
index 00000000000..db7d8411a11
--- /dev/null
+++ b/src/vppinfra/devicetree.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright (c) 2024 Cisco Systems, Inc.
+ */
+
+#ifndef CLIB_DEVICETREE_H_
+#define CLIB_DEVICETREE_H_
+
+#include <vppinfra/clib.h>
+#include <vlib/vlib.h>
+
+#ifdef __linux
+#define CLIB_DT_LINUX_PREFIX "/sys/firmware/devicetree/base"
+#endif
+
+typedef struct
+{
+ char name[32];
+ u32 size;
+ u8 data[];
+} clib_dt_property_t;
+
+typedef struct clib_dt_main clib_dt_main_t;
+
+typedef struct clib_dt_node
+{
+ u8 *path;
+ struct clib_dt_node *parent;
+ struct clib_dt_node *prev;
+ struct clib_dt_node *next;
+ struct clib_dt_node **child_nodes;
+ u8 depth;
+ clib_dt_property_t *name;
+ clib_dt_property_t **properties;
+ clib_dt_main_t *dt_main;
+} clib_dt_node_t;
+
+typedef struct clib_dt_main
+{
+ clib_dt_node_t **nodes;
+ clib_dt_node_t *root;
+ uword *node_by_path;
+ uword *node_by_phandle;
+} clib_dt_main_t;
+
+__clib_export clib_dt_node_t *clib_dt_get_child_node (clib_dt_node_t *n,
+ char *fmt, ...);
+clib_dt_node_t *clib_dt_get_node_with_path (clib_dt_main_t *dm, char *fmt,
+ ...);
+clib_dt_property_t *clib_dt_get_node_property_by_name (clib_dt_node_t *,
+ char *);
+int clib_dt_node_is_compatible (clib_dt_node_t *, char *);
+clib_dt_node_t *clib_dt_dereference_node (clib_dt_node_t *, char *);
+#ifdef __linux
+clib_error_t *clib_dt_read_from_sysfs (clib_dt_main_t *dm);
+#endif
+
+format_function_t format_clib_dt_desc;
+format_function_t format_clib_dt_property_data;
+
+static_always_inline int
+clib_dt_property_is_u32 (clib_dt_property_t *p)
+{
+ if (p == 0 || p->size != 4)
+ return 0;
+ return 1;
+}
+
+static_always_inline u32
+clib_dt_property_get_u32 (clib_dt_property_t *p)
+{
+ return clib_net_to_host_u32 (*(u32u *) p->data);
+}
+
+static_always_inline char *
+clib_dt_property_get_string (clib_dt_property_t *p)
+{
+ return (char *) p->data;
+}
+
+static_always_inline clib_dt_node_t *
+clib_dt_get_root_node (clib_dt_node_t *n)
+{
+ return n->dt_main->root;
+}
+
+static_always_inline clib_dt_node_t *
+foreach_clib_dt_tree_node_helper (clib_dt_node_t *first, clib_dt_node_t **prev,
+ clib_dt_node_t *n)
+{
+ clib_dt_node_t *next;
+
+again:
+ if ((!*prev || (*prev)->parent != n) && vec_len (n->child_nodes) > 0)
+ next = n->child_nodes[0];
+ else if (n->next)
+ next = n->next;
+ else
+ {
+ next = n->parent;
+ *prev = n;
+ n = next;
+ if (n == first)
+ return 0;
+ goto again;
+ }
+
+ *prev = n;
+ return next == first ? 0 : next;
+}
+
+#define foreach_clib_dt_child_node(_cn, _n) \
+ vec_foreach_pointer (_cn, (_n)->child_nodes)
+
+#define foreach_clib_dt_tree_node(_n, _first) \
+ for (clib_dt_node_t *__last = 0, *(_n) = _first; _n; \
+ _n = foreach_clib_dt_tree_node_helper (_first, &__last, _n))
+
+#endif /* CLIB_DEVICETREE_H_ */