summaryrefslogtreecommitdiff
path: root/src/commonlib/include
diff options
context:
space:
mode:
authorMaximilian Brune <maximilian.brune@9elements.com>2023-09-16 20:08:41 +0200
committerLean Sheng Tan <sheng.tan@9elements.com>2024-06-22 04:02:04 +0000
commitda336cd5c61b3ec137ec21d059aa36b9f8e80269 (patch)
tree6d56c287e931cf18d257ec2cccb066eec8a21910 /src/commonlib/include
parent5afdcd9190a83cb3a13e17cb59126bfcf58e739a (diff)
treewide: Move device_tree to commonlib
Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com> Change-Id: I990d74d9fff06b17ec8a6ee962955e4b0df8b907 Reviewed-on: https://review.coreboot.org/c/coreboot/+/77970 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/commonlib/include')
-rw-r--r--src/commonlib/include/commonlib/device_tree.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/commonlib/include/commonlib/device_tree.h b/src/commonlib/include/commonlib/device_tree.h
new file mode 100644
index 0000000000..be7335783f
--- /dev/null
+++ b/src/commonlib/include/commonlib/device_tree.h
@@ -0,0 +1,232 @@
+/* Taken from depthcharge: src/base/device_tree.h */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef __COMMONLIB_DEVICE_TREE_H__
+#define __COMMONLIB_DEVICE_TREE_H__
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <commonlib/list.h>
+
+/*
+ * Flattened device tree structures/constants.
+ */
+
+struct fdt_header {
+ uint32_t magic;
+ uint32_t totalsize;
+ uint32_t structure_offset;
+ uint32_t strings_offset;
+ uint32_t reserve_map_offset;
+
+ uint32_t version;
+ uint32_t last_comp_version;
+
+ uint32_t boot_cpuid_phys;
+
+ uint32_t strings_size;
+ uint32_t structure_size;
+};
+
+#define FDT_HEADER_MAGIC 0xd00dfeed
+#define FDT_SUPPORTED_VERSION 17
+#define FDT_TOKEN_BEGIN_NODE 1
+#define FDT_TOKEN_END_NODE 2
+#define FDT_TOKEN_PROPERTY 3
+#define FDT_TOKEN_NOP 4
+#define FDT_TOKEN_END 9
+#define FDT_PHANDLE_ILLEGAL 0xdeadbeef
+
+struct fdt_property
+{
+ const char *name;
+ void *data;
+ uint32_t size;
+};
+
+/*
+ * Unflattened device tree structures.
+ */
+
+struct device_tree_region {
+ u64 addr;
+ u64 size;
+};
+
+struct device_tree_property
+{
+ struct fdt_property prop;
+
+ struct list_node list_node;
+};
+
+struct device_tree_node
+{
+ const char *name;
+ uint32_t phandle;
+
+ /* List of struct device_tree_property-s. */
+ struct list_node properties;
+ /* List of struct device_tree_nodes. */
+ struct list_node children;
+
+ struct list_node list_node;
+};
+
+struct device_tree_reserve_map_entry
+{
+ uint64_t start;
+ uint64_t size;
+
+ struct list_node list_node;
+};
+
+struct device_tree
+{
+ const void *header;
+ uint32_t header_size;
+ uint32_t max_phandle;
+
+ struct list_node reserve_map;
+
+ struct device_tree_node *root;
+};
+
+/*
+ * Flattened device tree functions. These generally return the number of bytes
+ * which were consumed reading the requested value.
+ */
+
+/* Checks if blob points to a valid FDT */
+bool fdt_is_valid(const void *blob);
+/* Read the property at offset, if any exists. */
+int fdt_next_property(const void *blob, uint32_t offset,
+ struct fdt_property *prop);
+/* Read the name of the node at offset, if any exists. */
+int fdt_node_name(const void *blob, uint32_t offset, const char **name);
+
+void fdt_print_node(const void *blob, uint32_t offset);
+int fdt_skip_node(const void *blob, uint32_t offset);
+
+/* Read property and put into fdt_prop. Returns offset to property */
+u32 fdt_read_prop(const void *blob, u32 node_offset, const char *prop_name,
+ struct fdt_property *fdt_prop);
+/* Read reg property and save regions inside 'regions'. Returns number of regions read */
+u32 fdt_read_reg_prop(const void *blob, u32 node_offset, u32 addr_cells, u32 size_cells,
+ struct device_tree_region regions[], size_t regions_count);
+/* Find a node by a given path and return the offset */
+u32 fdt_find_node_by_path(const void *blob, const char *path, u32 *addrcp, u32 *sizecp);
+/* Find multiple nodes matching a given pattern. Returns number of nodes found */
+size_t fdt_find_subnodes_by_prefix(const void *blob, u32 node_offset, const char *prefix,
+ u32 *addrcp, u32 *sizecp, u32 results[], size_t results_len);
+/* Find a node by a given alias and return its offset */
+u32 fdt_find_node_by_alias(const void *blob, const char *alias_name,
+ u32 *addr_cells, u32 *size_cells);
+/*
+ * Read the node name into 'name' of the node behind 'node_offset'
+ * and return total bytes used for name
+ */
+int fdt_next_node_name(const void *blob, uint32_t node_offset, const char **name);
+
+ /* Read memory regions from a flat device-tree. */
+size_t fdt_read_memory_regions(const void *blob, struct device_tree_region regions[],
+ size_t regions_count);
+ /* Find top of memory from a flat device-tree. */
+uint64_t fdt_get_memory_top(const void *blob);
+
+/* Read a flattened device tree into a hierarchical structure which refers to
+ the contents of the flattened tree in place. Modifying the flat tree
+ invalidates the unflattened one. */
+struct device_tree *fdt_unflatten(const void *blob);
+
+/*
+ * Unflattened device tree functions.
+ */
+
+/* Figure out how big a device tree would be if it were flattened. */
+uint32_t dt_flat_size(const struct device_tree *tree);
+/* Flatten a device tree into the buffer pointed to by dest. */
+void dt_flatten(const struct device_tree *tree, void *dest);
+void dt_print_node(const struct device_tree_node *node);
+/* Read #address-cells and #size-cells properties from a node. */
+void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp,
+ u32 *sizecp);
+/* Look up or create a node relative to a parent node, through its path
+ represented as an array of strings. */
+struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path,
+ u32 *addrcp, u32 *sizecp, int create);
+struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root,
+ uint32_t phandle);
+/* Look up or create a node in the tree, through its path
+ represented as a string of '/' separated node names. */
+struct device_tree_node *dt_find_node_by_path(struct device_tree *tree,
+ const char *path, u32 *addrcp, u32 *sizecp, int create);
+/* Look up a node through an alias. */
+struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree,
+ const char *alias);
+/* Look up a node relative to a parent node, through its compatible string. */
+struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible);
+/* Look up the next child of a parent node, through its compatible string. It
+ uses child pointer as the marker to find next. */
+struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *parent,
+ struct device_tree_node *child,
+ const char *compat);
+/* Look up a node relative to a parent node, through its property value. */
+struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name,
+ void *data, size_t size);
+/* Write src into *dest as a 'length'-byte big-endian integer. */
+void dt_write_int(u8 *dest, u64 src, size_t length);
+/* Delete a property */
+void dt_delete_prop(struct device_tree_node *node, const char *name);
+/* Add different kinds of properties to a node, or update existing ones. */
+void dt_add_bin_prop(struct device_tree_node *node, const char *name,
+ void *data, size_t size);
+void dt_add_string_prop(struct device_tree_node *node, const char *name,
+ const char *str);
+void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val);
+void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val);
+void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes,
+ int count, u32 addr_cells, u32 size_cells);
+int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path,
+ void *data, size_t size, int create);
+
+void dt_find_bin_prop(const struct device_tree_node *node, const char *name,
+ const void **data, size_t *size);
+const char *dt_find_string_prop(const struct device_tree_node *node,
+ const char *name);
+
+/* Apply an overlay to a base device tree. Ownership of the overlay data passes
+ to the newly combined base tree -- do not free() or access it afterwards! */
+int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay);
+
+/*
+ * Fixups to apply to a kernel's device tree before booting it.
+ */
+
+struct device_tree_fixup
+{
+ /**
+ * The function which does the fixing.
+ * 0 on success, non-zero on error.
+ */
+ int (*fixup)(struct device_tree_fixup *fixup,
+ struct device_tree *tree);
+
+ struct list_node list_node;
+};
+
+extern struct list_node device_tree_fixups;
+
+/**
+ * Function to apply fixups.
+ * 0 on success, non-zero on error.
+ */
+int dt_apply_fixups(struct device_tree *tree);
+
+/*
+ * Init/retrieve the /reserved-memory/ node.
+ */
+struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree);
+
+#endif /* __COMMONLIB_DEVICE_TREE_H__ */