coreboot-kgpe-d16/src/include/device_tree.h
Julius Werner f36d53c653 device_tree: Drop sub-node path lookup from dt_find_node_by_path()
Besides looking up a node with an absolute path dt_find_node_by_path()
currently also supports finding a sub-node of a non-root node. All
callers of the function pass the root node though, so it seems there
is no real need for this functionality. Also it is planned to support
DT path names with aliases, which would become messy in combination with
the lookup from a sub-node.

Change the interface of dt_find_node_by_path() to receive the DT tree
object instead of a parent node and adapt all callers accordingly.

This patch was adapted from depthcharge's http://crosreview.com/1252769

Change-Id: Iff56be4da2461ae73a7301dcaa315758d2a8c999
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/32864
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2019-06-04 11:23:12 +00:00

209 lines
6.1 KiB
C

/*
* Copyright 2013 Google Inc.
* Copyright 2018-present Facebook, Inc.
*
* Taken from depthcharge: src/base/device_tree.h
*
* This program 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 2 of
* the License, or (at your option) any later version.
*
* This program 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.
*/
#ifndef __DEVICE_TREE_H__
#define __DEVICE_TREE_H__
#include <stdint.h>
#include <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_END 9
#define FDT_PHANDLE_ILLEGAL 0xdeadbeef
struct fdt_property
{
const char *name;
const void *data;
uint32_t size;
};
/*
* Unflattened device tree structures.
*/
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.
*/
// Read the property, if any, at offset offset.
int fdt_next_property(const void *blob, uint32_t offset,
struct fdt_property *prop);
// Read the name of the node, if any, at offset offset.
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 a flattened device tree into a heirarchical 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 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,
const 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);
/*
* 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 /* __DEVICE_TREE_H__ */