blob: e7b79e1a94f11955b80324adcf0c0cdc2c552323 [file] [log] [blame]
Patrick Georgiafd4c872020-05-05 23:43:18 +02001/* Taken from depthcharge: src/base/device_tree.h */
Patrick Georgiac959032020-05-05 22:49:26 +02002/* SPDX-License-Identifier: GPL-2.0-or-later */
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02003
Patrick Rudolph666c1722018-04-03 09:57:33 +02004#ifndef __DEVICE_TREE_H__
5#define __DEVICE_TREE_H__
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02006
Elyes HAOUAS5817c562020-07-12 09:03:22 +02007#include <stddef.h>
Patrick Rudolph67aca3e2018-04-12 11:44:43 +02008#include <stdint.h>
Maximilian Brunea99b5802023-09-16 19:56:45 +02009#include <commonlib/list.h>
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020010
11/*
12 * Flattened device tree structures/constants.
13 */
14
Patrick Rudolph666c1722018-04-03 09:57:33 +020015struct fdt_header {
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020016 uint32_t magic;
17 uint32_t totalsize;
18 uint32_t structure_offset;
19 uint32_t strings_offset;
20 uint32_t reserve_map_offset;
21
22 uint32_t version;
Julius Werner73eaec82019-05-03 17:58:07 -070023 uint32_t last_comp_version;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020024
25 uint32_t boot_cpuid_phys;
26
27 uint32_t strings_size;
28 uint32_t structure_size;
Patrick Rudolph666c1722018-04-03 09:57:33 +020029};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020030
Patrick Rudolph666c1722018-04-03 09:57:33 +020031#define FDT_HEADER_MAGIC 0xd00dfeed
Julius Werner73eaec82019-05-03 17:58:07 -070032#define FDT_SUPPORTED_VERSION 17
Patrick Rudolph666c1722018-04-03 09:57:33 +020033#define FDT_TOKEN_BEGIN_NODE 1
34#define FDT_TOKEN_END_NODE 2
35#define FDT_TOKEN_PROPERTY 3
36#define FDT_TOKEN_END 9
Julius Werner6702b682019-05-03 18:13:53 -070037#define FDT_PHANDLE_ILLEGAL 0xdeadbeef
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020038
Patrick Rudolph666c1722018-04-03 09:57:33 +020039struct fdt_property
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020040{
41 const char *name;
Julius Werner0e9116f2019-05-13 17:30:31 -070042 void *data;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020043 uint32_t size;
Patrick Rudolph666c1722018-04-03 09:57:33 +020044};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020045
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020046/*
47 * Unflattened device tree structures.
48 */
49
Patrick Rudolph666c1722018-04-03 09:57:33 +020050struct device_tree_property
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020051{
Patrick Rudolph666c1722018-04-03 09:57:33 +020052 struct fdt_property prop;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020053
Patrick Rudolph666c1722018-04-03 09:57:33 +020054 struct list_node list_node;
55};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020056
Patrick Rudolph666c1722018-04-03 09:57:33 +020057struct device_tree_node
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020058{
59 const char *name;
Julius Werner6702b682019-05-03 18:13:53 -070060 uint32_t phandle;
61
Julius Werner23df4772019-05-17 22:50:18 -070062 /* List of struct device_tree_property-s. */
Patrick Rudolph666c1722018-04-03 09:57:33 +020063 struct list_node properties;
Julius Werner23df4772019-05-17 22:50:18 -070064 /* List of struct device_tree_nodes. */
Patrick Rudolph666c1722018-04-03 09:57:33 +020065 struct list_node children;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020066
Patrick Rudolph666c1722018-04-03 09:57:33 +020067 struct list_node list_node;
68};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020069
Patrick Rudolph666c1722018-04-03 09:57:33 +020070struct device_tree_reserve_map_entry
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020071{
72 uint64_t start;
73 uint64_t size;
74
Patrick Rudolph666c1722018-04-03 09:57:33 +020075 struct list_node list_node;
76};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020077
Patrick Rudolph666c1722018-04-03 09:57:33 +020078struct device_tree
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020079{
Patrick Rudolph0a7d6902018-08-22 09:55:15 +020080 const void *header;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020081 uint32_t header_size;
Julius Werner6702b682019-05-03 18:13:53 -070082 uint32_t max_phandle;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020083
Patrick Rudolph666c1722018-04-03 09:57:33 +020084 struct list_node reserve_map;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020085
Patrick Rudolph666c1722018-04-03 09:57:33 +020086 struct device_tree_node *root;
87};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020088
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020089/*
90 * Flattened device tree functions. These generally return the number of bytes
91 * which were consumed reading the requested value.
92 */
93
Alexander Goncharov893c3ae82023-02-04 15:20:37 +040094/* Read the property at offset, if any exists. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +020095int fdt_next_property(const void *blob, uint32_t offset,
96 struct fdt_property *prop);
Alexander Goncharov893c3ae82023-02-04 15:20:37 +040097/* Read the name of the node at offset, if any exists. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +020098int fdt_node_name(const void *blob, uint32_t offset, const char **name);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +020099
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200100void fdt_print_node(const void *blob, uint32_t offset);
101int fdt_skip_node(const void *blob, uint32_t offset);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200102
Elyes HAOUAS5f73e222020-01-15 21:13:45 +0100103/* Read a flattened device tree into a hierarchical structure which refers to
Julius Werner23df4772019-05-17 22:50:18 -0700104 the contents of the flattened tree in place. Modifying the flat tree
105 invalidates the unflattened one. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200106struct device_tree *fdt_unflatten(const void *blob);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200107
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200108/*
109 * Unflattened device tree functions.
110 */
111
Julius Werner23df4772019-05-17 22:50:18 -0700112/* Figure out how big a device tree would be if it were flattened. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200113uint32_t dt_flat_size(const struct device_tree *tree);
Julius Werner23df4772019-05-17 22:50:18 -0700114/* Flatten a device tree into the buffer pointed to by dest. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200115void dt_flatten(const struct device_tree *tree, void *dest);
116void dt_print_node(const struct device_tree_node *node);
Julius Werner23df4772019-05-17 22:50:18 -0700117/* Read #address-cells and #size-cells properties from a node. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200118void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp,
119 u32 *sizecp);
Julius Werner23df4772019-05-17 22:50:18 -0700120/* Look up or create a node relative to a parent node, through its path
121 represented as an array of strings. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200122struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200123 u32 *addrcp, u32 *sizecp, int create);
Julius Werner6702b682019-05-03 18:13:53 -0700124struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root,
125 uint32_t phandle);
Julius Werner23df4772019-05-17 22:50:18 -0700126/* Look up or create a node in the tree, through its path
127 represented as a string of '/' separated node names. */
Julius Wernerf36d53c2019-05-03 18:23:34 -0700128struct device_tree_node *dt_find_node_by_path(struct device_tree *tree,
129 const char *path, u32 *addrcp, u32 *sizecp, int create);
Julius Werner23df4772019-05-17 22:50:18 -0700130/* Look up a node through an alias. */
Julius Werner6d5695f2019-05-06 19:23:28 -0700131struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree,
132 const char *alias);
Julius Werner23df4772019-05-17 22:50:18 -0700133/* Look up a node relative to a parent node, through its compatible string. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200134struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible);
Julius Werner23df4772019-05-17 22:50:18 -0700135/* Look up the next child of a parent node, through its compatible string. It
136 uses child pointer as the marker to find next. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200137struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *parent,
138 struct device_tree_node *child,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200139 const char *compat);
Julius Werner23df4772019-05-17 22:50:18 -0700140/* Look up a node relative to a parent node, through its property value. */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200141struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200142 void *data, size_t size);
Julius Werner23df4772019-05-17 22:50:18 -0700143/* Write src into *dest as a 'length'-byte big-endian integer. */
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200144void dt_write_int(u8 *dest, u64 src, size_t length);
Julius Werner23df4772019-05-17 22:50:18 -0700145/* Delete a property */
Patrick Rudolph5ccc7312018-05-30 15:05:28 +0200146void dt_delete_prop(struct device_tree_node *node, const char *name);
Julius Werner23df4772019-05-17 22:50:18 -0700147/* Add different kinds of properties to a node, or update existing ones. */
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200148void dt_add_bin_prop(struct device_tree_node *node, const char *name,
Julius Werner0e9116f2019-05-13 17:30:31 -0700149 void *data, size_t size);
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200150void dt_add_string_prop(struct device_tree_node *node, const char *name,
151 const char *str);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200152void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val);
Patrick Rudolph3fca4ed2018-08-10 10:12:35 +0200153void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200154void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200155 int count, u32 addr_cells, u32 size_cells);
Patrick Rudolph666c1722018-04-03 09:57:33 +0200156int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path,
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200157 void *data, size_t size, int create);
158
Patrick Rudolph0a7d6902018-08-22 09:55:15 +0200159void dt_find_bin_prop(const struct device_tree_node *node, const char *name,
160 const void **data, size_t *size);
161const char *dt_find_string_prop(const struct device_tree_node *node,
162 const char *name);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200163
Julius Werner735ddc92019-05-07 17:05:28 -0700164/* Apply an overlay to a base device tree. Ownership of the overlay data passes
165 to the newly combined base tree -- do not free() or access it afterwards! */
166int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay);
167
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200168/*
169 * Fixups to apply to a kernel's device tree before booting it.
170 */
171
Patrick Rudolph666c1722018-04-03 09:57:33 +0200172struct device_tree_fixup
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200173{
Patrick Rudolph666c1722018-04-03 09:57:33 +0200174 /**
175 * The function which does the fixing.
176 * 0 on success, non-zero on error.
177 */
178 int (*fixup)(struct device_tree_fixup *fixup,
179 struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200180
Patrick Rudolph666c1722018-04-03 09:57:33 +0200181 struct list_node list_node;
182};
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200183
Patrick Rudolph666c1722018-04-03 09:57:33 +0200184extern struct list_node device_tree_fixups;
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200185
Patrick Rudolph666c1722018-04-03 09:57:33 +0200186/**
187 * Function to apply fixups.
188 * 0 on success, non-zero on error.
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200189 */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200190int dt_apply_fixups(struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200191
192/*
193 * Init/retrieve the /reserved-memory/ node.
194 */
Patrick Rudolph666c1722018-04-03 09:57:33 +0200195struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree);
Patrick Rudolph67aca3e2018-04-12 11:44:43 +0200196
Patrick Rudolph666c1722018-04-03 09:57:33 +0200197#endif /* __DEVICE_TREE_H__ */