| /* |
| * Copyright 2013 Google Inc. |
| * |
| * See file CREDITS for list of people who contributed to this |
| * project. |
| * |
| * 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. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| * MA 02111-1307 USA |
| */ |
| |
| #ifndef __BASE_DEVICE_TREE_H__ |
| #define __BASE_DEVICE_TREE_H__ |
| |
| #include <stdint.h> |
| |
| #include "base/list.h" |
| |
| /* |
| * Flattened device tree structures/constants. |
| */ |
| |
| typedef struct FdtHeader { |
| 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_compatible_version; |
| |
| uint32_t boot_cpuid_phys; |
| |
| uint32_t strings_size; |
| uint32_t structure_size; |
| } FdtHeader; |
| |
| static const uint32_t FdtMagic = 0xd00dfeed; |
| |
| static const uint32_t TokenBeginNode = 1; |
| static const uint32_t TokenEndNode = 2; |
| static const uint32_t TokenProperty = 3; |
| static const uint32_t TokenEnd = 9; |
| |
| typedef struct FdtProperty |
| { |
| const char *name; |
| void *data; |
| uint32_t size; |
| } FdtProperty; |
| |
| |
| |
| /* |
| * Unflattened device tree structures. |
| */ |
| |
| typedef struct DeviceTreeProperty |
| { |
| FdtProperty prop; |
| |
| ListNode list_node; |
| } DeviceTreeProperty; |
| |
| typedef struct DeviceTreeNode |
| { |
| const char *name; |
| // List of DeviceTreeProperty-s. |
| ListNode properties; |
| // List of DeviceTreeNodes. |
| ListNode children; |
| |
| ListNode list_node; |
| } DeviceTreeNode; |
| |
| typedef struct DeviceTreeReserveMapEntry |
| { |
| uint64_t start; |
| uint64_t size; |
| |
| ListNode list_node; |
| } DeviceTreeReserveMapEntry; |
| |
| typedef struct DeviceTree |
| { |
| void *header; |
| uint32_t header_size; |
| |
| ListNode reserve_map; |
| |
| DeviceTreeNode *root; |
| } DeviceTree; |
| |
| |
| |
| /* |
| * 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(void *blob, uint32_t offset, FdtProperty *prop); |
| // Read the name of the node, if any, at offset offset. |
| int fdt_node_name(void *blob, uint32_t offset, const char **name); |
| |
| void fdt_print_node(void *blob, uint32_t offset); |
| int fdt_skip_node(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. |
| DeviceTree *fdt_unflatten(void *blob); |
| |
| |
| |
| /* |
| * Unflattened device tree functions. |
| */ |
| |
| // Figure out how big a device tree would be if it were flattened. |
| uint32_t dt_flat_size(DeviceTree *tree); |
| // Flatten a device tree into the buffer pointed to by dest. |
| void dt_flatten(DeviceTree *tree, void *dest); |
| void dt_print_node(DeviceTreeNode *node); |
| // Read #address-cells and #size-cells properties from a node. |
| void dt_read_cell_props(DeviceTreeNode *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. |
| DeviceTreeNode *dt_find_node(DeviceTreeNode *parent, const char **path, |
| u32 *addrcp, u32 *sizecp, int create); |
| // Look up or create a node relative to a parent node, through its path |
| // represented as a string of '/' separated node names. |
| DeviceTreeNode *dt_find_node_by_path(DeviceTreeNode *parent, const char *path, |
| u32 *addrcp, u32 *sizecp, int create); |
| // Look up a node relative to a parent node, through its compatible string. |
| DeviceTreeNode *dt_find_compat(DeviceTreeNode *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. |
| DeviceTreeNode *dt_find_next_compat_child(DeviceTreeNode *parent, |
| DeviceTreeNode *child, |
| const char *compat); |
| // Look up a node relative to a parent node, through its property value. |
| DeviceTreeNode *dt_find_prop_value(DeviceTreeNode *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); |
| // Add different kinds of properties to a node, or update existing ones. |
| void dt_add_bin_prop(DeviceTreeNode *node, char *name, void *data, size_t size); |
| void dt_add_string_prop(DeviceTreeNode *node, char *name, char *str); |
| void dt_add_u32_prop(DeviceTreeNode *node, char *name, u32 val); |
| void dt_add_reg_prop(DeviceTreeNode *node, u64 *addrs, u64 *sizes, |
| int count, u32 addr_cells, u32 size_cells); |
| int dt_set_bin_prop_by_path(DeviceTree *tree, const char *path, |
| void *data, size_t size, int create); |
| |
| void dt_find_bin_prop(DeviceTreeNode *node, const char *name, void **data, |
| size_t *size); |
| const char *dt_find_string_prop(DeviceTreeNode *node, const char *name); |
| |
| /* |
| * Fixups to apply to a kernel's device tree before booting it. |
| */ |
| |
| typedef struct DeviceTreeFixup |
| { |
| // The function which does the fixing. |
| int (*fixup)(struct DeviceTreeFixup *fixup, DeviceTree *tree); |
| |
| ListNode list_node; |
| } DeviceTreeFixup; |
| |
| extern ListNode device_tree_fixups; |
| |
| int dt_apply_fixups(DeviceTree *tree); |
| |
| /* |
| * Structure defining mapping between arbitrary objects and the device tree |
| * path to the property corresponding to the object. |
| */ |
| typedef struct { |
| int force_create; /* If false - do not create a new node. */ |
| const char *dt_path; |
| const char *key; |
| } DtPathMap; |
| |
| /* |
| * Copy mac addresses from sysinfo table into the device tree. The mapping |
| * between the dt_maps entries and sysinfo mac address table elements is |
| * implicit, i.e. the device tree node found in the maps entry, gets assinged |
| * the mac address found in the sysinfo table, in the same order. |
| */ |
| int dt_set_mac_addresses(DeviceTree *tree, const DtPathMap *dt_maps); |
| |
| /* |
| * Copy WIFI calibration data from sysinfo table into the device tree. Each |
| * WIFI calibration blob stored the sysinfo table contains key and data. The |
| * key is used for mapping into the device tree path. The data becomes the |
| * contents of the device tree property at that path. |
| */ |
| int dt_set_wifi_calibration(DeviceTree *tree, const DtPathMap *maps); |
| |
| #endif /* __BASE_DEVICE_TREE_H__ */ |