MCPcopy Create free account
hub / github.com/coreboot/coreboot / dt_apply_overlay

Function dt_apply_overlay

src/commonlib/device_tree.c:2079–2155  ·  view source on GitHub ↗

* Apply a device tree overlay to a base device tree. This will * destroy/incorporate the overlay data, so it should not be freed or reused. * See dtc.git/Documentation/dt-object-internal.txt for overlay format details. * * @param tree Unflattened base device tree to add the overlay into. * @param overlay Unflattened overlay device tree to apply to the base. * * @return 0 on success, -1 on

Source from the content-addressed store, hash-verified

2077 * @return 0 on success, -1 on error.
2078 */
2079int dt_apply_overlay(struct device_tree *tree, struct device_tree *overlay)
2080{
2081 /*
2082 * First, we need to make sure phandles inside the overlay don't clash
2083 * with those in the base tree. We just define the highest phandle value
2084 * in the base tree as the "phandle offset" for this overlay and
2085 * increment all phandles in it by that value.
2086 */
2087 uint32_t phandle_base = tree->max_phandle;
2088 uint32_t new_max = dt_adjust_all_phandles(overlay->root, phandle_base);
2089 if (!new_max) {
2090 printk(BIOS_ERR, "invalid phandles in overlay\n");
2091 return -1;
2092 }
2093 tree->max_phandle = new_max;
2094
2095 /* Now that we changed phandles in the overlay, we need to update any
2096 nodes referring to them. Those are listed in /__local_fixups__. */
2097 struct device_tree_node *local_fixups = dt_find_node_by_path(overlay,
2098 "/__local_fixups__", NULL, NULL, 0);
2099 if (local_fixups && dt_fixup_locals(overlay->root, local_fixups,
2100 phandle_base) < 0) {
2101 printk(BIOS_ERR, "invalid local fixups in overlay\n");
2102 return -1;
2103 }
2104
2105 /*
2106 * Besides local phandle references (from nodes within the overlay to
2107 * other nodes within the overlay), the overlay may also contain phandle
2108 * references to the base tree. These are stored with invalid values and
2109 * must be updated now. /__symbols__ contains a list of all labels in
2110 * the base tree, and /__fixups__ describes all nodes in the overlay
2111 * that contain external phandle references.
2112 * We also take this opportunity to update all /fragment@X/__overlay__/
2113 * prefixes in the overlay's /__symbols__ node to the correct path that
2114 * the fragment will be placed in later, since this is the only step
2115 * where we have all necessary information for that easily available.
2116 */
2117 struct device_tree_node *symbols = dt_find_node_by_path(tree,
2118 "/__symbols__", NULL, NULL, 0);
2119 struct device_tree_node *fixups = dt_find_node_by_path(overlay,
2120 "/__fixups__", NULL, NULL, 0);
2121 struct device_tree_node *overlay_symbols = dt_find_node_by_path(overlay,
2122 "/__symbols__", NULL, NULL, 0);
2123 if (fixups && dt_fixup_all_externals(tree, symbols, overlay,
2124 fixups, overlay_symbols) < 0) {
2125 printk(BIOS_ERR, "cannot match external fixups from overlay\n");
2126 return -1;
2127 }
2128
2129 /* After all this fixing up, we can finally merge overlay into the tree
2130 (one fragment at a time, because for some reason it's split up). */
2131 struct device_tree_node *fragment;
2132 list_for_each(fragment, overlay->root->children, list_node)
2133 if (dt_import_fragment(tree, fragment, overlay_symbols) < 0) {
2134 printk(BIOS_ERR, "bad DT fragment '%s'\n",
2135 fragment->name);
2136 return -1;

Callers 2

fit_payloadFunction · 0.85
test_dt_apply_overlayFunction · 0.85

Calls 8

dt_adjust_all_phandlesFunction · 0.85
dt_find_node_by_pathFunction · 0.85
dt_fixup_localsFunction · 0.85
dt_fixup_all_externalsFunction · 0.85
dt_import_fragmentFunction · 0.85
dt_copy_subtreeFunction · 0.85
list_insert_afterFunction · 0.85
printkFunction · 0.50

Tested by 1

test_dt_apply_overlayFunction · 0.68