1 1.1.1.2 skrll /* $NetBSD: livetree.c,v 1.1.1.3 2019/12/22 12:34:03 skrll Exp $ */ 2 1.1.1.2 skrll 3 1.1.1.3 skrll // SPDX-License-Identifier: GPL-2.0-or-later 4 1.1 macallan /* 5 1.1 macallan * (C) Copyright David Gibson <dwg (at) au1.ibm.com>, IBM Corporation. 2005. 6 1.1 macallan */ 7 1.1 macallan 8 1.1 macallan #include "dtc.h" 9 1.1.1.3 skrll #include "srcpos.h" 10 1.1 macallan 11 1.1 macallan /* 12 1.1 macallan * Tree building functions 13 1.1 macallan */ 14 1.1 macallan 15 1.1 macallan void add_label(struct label **labels, char *label) 16 1.1 macallan { 17 1.1 macallan struct label *new; 18 1.1 macallan 19 1.1 macallan /* Make sure the label isn't already there */ 20 1.1 macallan for_each_label_withdel(*labels, new) 21 1.1 macallan if (streq(new->label, label)) { 22 1.1 macallan new->deleted = 0; 23 1.1 macallan return; 24 1.1 macallan } 25 1.1 macallan 26 1.1 macallan new = xmalloc(sizeof(*new)); 27 1.1 macallan memset(new, 0, sizeof(*new)); 28 1.1 macallan new->label = label; 29 1.1 macallan new->next = *labels; 30 1.1 macallan *labels = new; 31 1.1 macallan } 32 1.1 macallan 33 1.1 macallan void delete_labels(struct label **labels) 34 1.1 macallan { 35 1.1 macallan struct label *label; 36 1.1 macallan 37 1.1 macallan for_each_label(*labels, label) 38 1.1 macallan label->deleted = 1; 39 1.1 macallan } 40 1.1 macallan 41 1.1.1.3 skrll struct property *build_property(char *name, struct data val, 42 1.1.1.3 skrll struct srcpos *srcpos) 43 1.1 macallan { 44 1.1 macallan struct property *new = xmalloc(sizeof(*new)); 45 1.1 macallan 46 1.1 macallan memset(new, 0, sizeof(*new)); 47 1.1 macallan 48 1.1 macallan new->name = name; 49 1.1 macallan new->val = val; 50 1.1.1.3 skrll new->srcpos = srcpos_copy(srcpos); 51 1.1 macallan 52 1.1 macallan return new; 53 1.1 macallan } 54 1.1 macallan 55 1.1 macallan struct property *build_property_delete(char *name) 56 1.1 macallan { 57 1.1 macallan struct property *new = xmalloc(sizeof(*new)); 58 1.1 macallan 59 1.1 macallan memset(new, 0, sizeof(*new)); 60 1.1 macallan 61 1.1 macallan new->name = name; 62 1.1 macallan new->deleted = 1; 63 1.1 macallan 64 1.1 macallan return new; 65 1.1 macallan } 66 1.1 macallan 67 1.1 macallan struct property *chain_property(struct property *first, struct property *list) 68 1.1 macallan { 69 1.1 macallan assert(first->next == NULL); 70 1.1 macallan 71 1.1 macallan first->next = list; 72 1.1 macallan return first; 73 1.1 macallan } 74 1.1 macallan 75 1.1 macallan struct property *reverse_properties(struct property *first) 76 1.1 macallan { 77 1.1 macallan struct property *p = first; 78 1.1 macallan struct property *head = NULL; 79 1.1 macallan struct property *next; 80 1.1 macallan 81 1.1 macallan while (p) { 82 1.1 macallan next = p->next; 83 1.1 macallan p->next = head; 84 1.1 macallan head = p; 85 1.1 macallan p = next; 86 1.1 macallan } 87 1.1 macallan return head; 88 1.1 macallan } 89 1.1 macallan 90 1.1.1.3 skrll struct node *build_node(struct property *proplist, struct node *children, 91 1.1.1.3 skrll struct srcpos *srcpos) 92 1.1 macallan { 93 1.1 macallan struct node *new = xmalloc(sizeof(*new)); 94 1.1 macallan struct node *child; 95 1.1 macallan 96 1.1 macallan memset(new, 0, sizeof(*new)); 97 1.1 macallan 98 1.1 macallan new->proplist = reverse_properties(proplist); 99 1.1 macallan new->children = children; 100 1.1.1.3 skrll new->srcpos = srcpos_copy(srcpos); 101 1.1 macallan 102 1.1 macallan for_each_child(new, child) { 103 1.1 macallan child->parent = new; 104 1.1 macallan } 105 1.1 macallan 106 1.1 macallan return new; 107 1.1 macallan } 108 1.1 macallan 109 1.1.1.3 skrll struct node *build_node_delete(struct srcpos *srcpos) 110 1.1 macallan { 111 1.1 macallan struct node *new = xmalloc(sizeof(*new)); 112 1.1 macallan 113 1.1 macallan memset(new, 0, sizeof(*new)); 114 1.1 macallan 115 1.1 macallan new->deleted = 1; 116 1.1.1.3 skrll new->srcpos = srcpos_copy(srcpos); 117 1.1 macallan 118 1.1 macallan return new; 119 1.1 macallan } 120 1.1 macallan 121 1.1 macallan struct node *name_node(struct node *node, char *name) 122 1.1 macallan { 123 1.1 macallan assert(node->name == NULL); 124 1.1 macallan 125 1.1 macallan node->name = name; 126 1.1 macallan 127 1.1 macallan return node; 128 1.1 macallan } 129 1.1 macallan 130 1.1.1.3 skrll struct node *omit_node_if_unused(struct node *node) 131 1.1.1.3 skrll { 132 1.1.1.3 skrll node->omit_if_unused = 1; 133 1.1.1.3 skrll 134 1.1.1.3 skrll return node; 135 1.1.1.3 skrll } 136 1.1.1.3 skrll 137 1.1.1.3 skrll struct node *reference_node(struct node *node) 138 1.1.1.3 skrll { 139 1.1.1.3 skrll node->is_referenced = 1; 140 1.1.1.3 skrll 141 1.1.1.3 skrll return node; 142 1.1.1.3 skrll } 143 1.1.1.3 skrll 144 1.1 macallan struct node *merge_nodes(struct node *old_node, struct node *new_node) 145 1.1 macallan { 146 1.1 macallan struct property *new_prop, *old_prop; 147 1.1 macallan struct node *new_child, *old_child; 148 1.1 macallan struct label *l; 149 1.1 macallan 150 1.1 macallan old_node->deleted = 0; 151 1.1 macallan 152 1.1 macallan /* Add new node labels to old node */ 153 1.1 macallan for_each_label_withdel(new_node->labels, l) 154 1.1 macallan add_label(&old_node->labels, l->label); 155 1.1 macallan 156 1.1 macallan /* Move properties from the new node to the old node. If there 157 1.1 macallan * is a collision, replace the old value with the new */ 158 1.1 macallan while (new_node->proplist) { 159 1.1 macallan /* Pop the property off the list */ 160 1.1 macallan new_prop = new_node->proplist; 161 1.1 macallan new_node->proplist = new_prop->next; 162 1.1 macallan new_prop->next = NULL; 163 1.1 macallan 164 1.1 macallan if (new_prop->deleted) { 165 1.1 macallan delete_property_by_name(old_node, new_prop->name); 166 1.1 macallan free(new_prop); 167 1.1 macallan continue; 168 1.1 macallan } 169 1.1 macallan 170 1.1 macallan /* Look for a collision, set new value if there is */ 171 1.1 macallan for_each_property_withdel(old_node, old_prop) { 172 1.1 macallan if (streq(old_prop->name, new_prop->name)) { 173 1.1 macallan /* Add new labels to old property */ 174 1.1 macallan for_each_label_withdel(new_prop->labels, l) 175 1.1 macallan add_label(&old_prop->labels, l->label); 176 1.1 macallan 177 1.1 macallan old_prop->val = new_prop->val; 178 1.1 macallan old_prop->deleted = 0; 179 1.1.1.3 skrll free(old_prop->srcpos); 180 1.1.1.3 skrll old_prop->srcpos = new_prop->srcpos; 181 1.1 macallan free(new_prop); 182 1.1 macallan new_prop = NULL; 183 1.1 macallan break; 184 1.1 macallan } 185 1.1 macallan } 186 1.1 macallan 187 1.1 macallan /* if no collision occurred, add property to the old node. */ 188 1.1 macallan if (new_prop) 189 1.1 macallan add_property(old_node, new_prop); 190 1.1 macallan } 191 1.1 macallan 192 1.1 macallan /* Move the override child nodes into the primary node. If 193 1.1 macallan * there is a collision, then merge the nodes. */ 194 1.1 macallan while (new_node->children) { 195 1.1 macallan /* Pop the child node off the list */ 196 1.1 macallan new_child = new_node->children; 197 1.1 macallan new_node->children = new_child->next_sibling; 198 1.1 macallan new_child->parent = NULL; 199 1.1 macallan new_child->next_sibling = NULL; 200 1.1 macallan 201 1.1 macallan if (new_child->deleted) { 202 1.1 macallan delete_node_by_name(old_node, new_child->name); 203 1.1 macallan free(new_child); 204 1.1 macallan continue; 205 1.1 macallan } 206 1.1 macallan 207 1.1 macallan /* Search for a collision. Merge if there is */ 208 1.1 macallan for_each_child_withdel(old_node, old_child) { 209 1.1 macallan if (streq(old_child->name, new_child->name)) { 210 1.1 macallan merge_nodes(old_child, new_child); 211 1.1 macallan new_child = NULL; 212 1.1 macallan break; 213 1.1 macallan } 214 1.1 macallan } 215 1.1 macallan 216 1.1.1.2 skrll /* if no collision occurred, add child to the old node. */ 217 1.1 macallan if (new_child) 218 1.1 macallan add_child(old_node, new_child); 219 1.1 macallan } 220 1.1 macallan 221 1.1.1.3 skrll old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos); 222 1.1.1.3 skrll 223 1.1 macallan /* The new node contents are now merged into the old node. Free 224 1.1 macallan * the new node. */ 225 1.1 macallan free(new_node); 226 1.1 macallan 227 1.1 macallan return old_node; 228 1.1 macallan } 229 1.1 macallan 230 1.1.1.3 skrll struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) 231 1.1.1.3 skrll { 232 1.1.1.3 skrll static unsigned int next_orphan_fragment = 0; 233 1.1.1.3 skrll struct node *node; 234 1.1.1.3 skrll struct property *p; 235 1.1.1.3 skrll struct data d = empty_data; 236 1.1.1.3 skrll char *name; 237 1.1.1.3 skrll 238 1.1.1.3 skrll if (ref[0] == '/') { 239 1.1.1.3 skrll d = data_add_marker(d, TYPE_STRING, ref); 240 1.1.1.3 skrll d = data_append_data(d, ref, strlen(ref) + 1); 241 1.1.1.3 skrll 242 1.1.1.3 skrll p = build_property("target-path", d, NULL); 243 1.1.1.3 skrll } else { 244 1.1.1.3 skrll d = data_add_marker(d, REF_PHANDLE, ref); 245 1.1.1.3 skrll d = data_append_integer(d, 0xffffffff, 32); 246 1.1.1.3 skrll 247 1.1.1.3 skrll p = build_property("target", d, NULL); 248 1.1.1.3 skrll } 249 1.1.1.3 skrll 250 1.1.1.3 skrll xasprintf(&name, "fragment@%u", 251 1.1.1.3 skrll next_orphan_fragment++); 252 1.1.1.3 skrll name_node(new_node, "__overlay__"); 253 1.1.1.3 skrll node = build_node(p, new_node, NULL); 254 1.1.1.3 skrll name_node(node, name); 255 1.1.1.3 skrll 256 1.1.1.3 skrll add_child(dt, node); 257 1.1.1.3 skrll return dt; 258 1.1.1.3 skrll } 259 1.1.1.3 skrll 260 1.1 macallan struct node *chain_node(struct node *first, struct node *list) 261 1.1 macallan { 262 1.1 macallan assert(first->next_sibling == NULL); 263 1.1 macallan 264 1.1 macallan first->next_sibling = list; 265 1.1 macallan return first; 266 1.1 macallan } 267 1.1 macallan 268 1.1 macallan void add_property(struct node *node, struct property *prop) 269 1.1 macallan { 270 1.1 macallan struct property **p; 271 1.1 macallan 272 1.1 macallan prop->next = NULL; 273 1.1 macallan 274 1.1 macallan p = &node->proplist; 275 1.1 macallan while (*p) 276 1.1 macallan p = &((*p)->next); 277 1.1 macallan 278 1.1 macallan *p = prop; 279 1.1 macallan } 280 1.1 macallan 281 1.1 macallan void delete_property_by_name(struct node *node, char *name) 282 1.1 macallan { 283 1.1 macallan struct property *prop = node->proplist; 284 1.1 macallan 285 1.1 macallan while (prop) { 286 1.1.1.2 skrll if (streq(prop->name, name)) { 287 1.1 macallan delete_property(prop); 288 1.1 macallan return; 289 1.1 macallan } 290 1.1 macallan prop = prop->next; 291 1.1 macallan } 292 1.1 macallan } 293 1.1 macallan 294 1.1 macallan void delete_property(struct property *prop) 295 1.1 macallan { 296 1.1 macallan prop->deleted = 1; 297 1.1 macallan delete_labels(&prop->labels); 298 1.1 macallan } 299 1.1 macallan 300 1.1 macallan void add_child(struct node *parent, struct node *child) 301 1.1 macallan { 302 1.1 macallan struct node **p; 303 1.1 macallan 304 1.1 macallan child->next_sibling = NULL; 305 1.1 macallan child->parent = parent; 306 1.1 macallan 307 1.1 macallan p = &parent->children; 308 1.1 macallan while (*p) 309 1.1 macallan p = &((*p)->next_sibling); 310 1.1 macallan 311 1.1 macallan *p = child; 312 1.1 macallan } 313 1.1 macallan 314 1.1 macallan void delete_node_by_name(struct node *parent, char *name) 315 1.1 macallan { 316 1.1 macallan struct node *node = parent->children; 317 1.1 macallan 318 1.1 macallan while (node) { 319 1.1.1.2 skrll if (streq(node->name, name)) { 320 1.1 macallan delete_node(node); 321 1.1 macallan return; 322 1.1 macallan } 323 1.1 macallan node = node->next_sibling; 324 1.1 macallan } 325 1.1 macallan } 326 1.1 macallan 327 1.1 macallan void delete_node(struct node *node) 328 1.1 macallan { 329 1.1 macallan struct property *prop; 330 1.1 macallan struct node *child; 331 1.1 macallan 332 1.1 macallan node->deleted = 1; 333 1.1 macallan for_each_child(node, child) 334 1.1 macallan delete_node(child); 335 1.1 macallan for_each_property(node, prop) 336 1.1 macallan delete_property(prop); 337 1.1 macallan delete_labels(&node->labels); 338 1.1 macallan } 339 1.1 macallan 340 1.1.1.2 skrll void append_to_property(struct node *node, 341 1.1.1.3 skrll char *name, const void *data, int len, 342 1.1.1.3 skrll enum markertype type) 343 1.1.1.2 skrll { 344 1.1.1.2 skrll struct data d; 345 1.1.1.2 skrll struct property *p; 346 1.1.1.2 skrll 347 1.1.1.2 skrll p = get_property(node, name); 348 1.1.1.2 skrll if (p) { 349 1.1.1.3 skrll d = data_add_marker(p->val, type, name); 350 1.1.1.3 skrll d = data_append_data(d, data, len); 351 1.1.1.2 skrll p->val = d; 352 1.1.1.2 skrll } else { 353 1.1.1.3 skrll d = data_add_marker(empty_data, type, name); 354 1.1.1.3 skrll d = data_append_data(d, data, len); 355 1.1.1.3 skrll p = build_property(name, d, NULL); 356 1.1.1.2 skrll add_property(node, p); 357 1.1.1.2 skrll } 358 1.1.1.2 skrll } 359 1.1.1.2 skrll 360 1.1 macallan struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) 361 1.1 macallan { 362 1.1 macallan struct reserve_info *new = xmalloc(sizeof(*new)); 363 1.1 macallan 364 1.1 macallan memset(new, 0, sizeof(*new)); 365 1.1 macallan 366 1.1.1.2 skrll new->address = address; 367 1.1.1.2 skrll new->size = size; 368 1.1 macallan 369 1.1 macallan return new; 370 1.1 macallan } 371 1.1 macallan 372 1.1 macallan struct reserve_info *chain_reserve_entry(struct reserve_info *first, 373 1.1 macallan struct reserve_info *list) 374 1.1 macallan { 375 1.1 macallan assert(first->next == NULL); 376 1.1 macallan 377 1.1 macallan first->next = list; 378 1.1 macallan return first; 379 1.1 macallan } 380 1.1 macallan 381 1.1 macallan struct reserve_info *add_reserve_entry(struct reserve_info *list, 382 1.1 macallan struct reserve_info *new) 383 1.1 macallan { 384 1.1 macallan struct reserve_info *last; 385 1.1 macallan 386 1.1 macallan new->next = NULL; 387 1.1 macallan 388 1.1 macallan if (! list) 389 1.1 macallan return new; 390 1.1 macallan 391 1.1 macallan for (last = list; last->next; last = last->next) 392 1.1 macallan ; 393 1.1 macallan 394 1.1 macallan last->next = new; 395 1.1 macallan 396 1.1 macallan return list; 397 1.1 macallan } 398 1.1 macallan 399 1.1.1.2 skrll struct dt_info *build_dt_info(unsigned int dtsflags, 400 1.1.1.2 skrll struct reserve_info *reservelist, 401 1.1.1.2 skrll struct node *tree, uint32_t boot_cpuid_phys) 402 1.1.1.2 skrll { 403 1.1.1.2 skrll struct dt_info *dti; 404 1.1.1.2 skrll 405 1.1.1.2 skrll dti = xmalloc(sizeof(*dti)); 406 1.1.1.2 skrll dti->dtsflags = dtsflags; 407 1.1.1.2 skrll dti->reservelist = reservelist; 408 1.1.1.2 skrll dti->dt = tree; 409 1.1.1.2 skrll dti->boot_cpuid_phys = boot_cpuid_phys; 410 1.1 macallan 411 1.1.1.2 skrll return dti; 412 1.1 macallan } 413 1.1 macallan 414 1.1 macallan /* 415 1.1 macallan * Tree accessor functions 416 1.1 macallan */ 417 1.1 macallan 418 1.1 macallan const char *get_unitname(struct node *node) 419 1.1 macallan { 420 1.1 macallan if (node->name[node->basenamelen] == '\0') 421 1.1 macallan return ""; 422 1.1 macallan else 423 1.1 macallan return node->name + node->basenamelen + 1; 424 1.1 macallan } 425 1.1 macallan 426 1.1 macallan struct property *get_property(struct node *node, const char *propname) 427 1.1 macallan { 428 1.1 macallan struct property *prop; 429 1.1 macallan 430 1.1 macallan for_each_property(node, prop) 431 1.1 macallan if (streq(prop->name, propname)) 432 1.1 macallan return prop; 433 1.1 macallan 434 1.1 macallan return NULL; 435 1.1 macallan } 436 1.1 macallan 437 1.1 macallan cell_t propval_cell(struct property *prop) 438 1.1 macallan { 439 1.1 macallan assert(prop->val.len == sizeof(cell_t)); 440 1.1.1.2 skrll return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); 441 1.1 macallan } 442 1.1 macallan 443 1.1.1.3 skrll cell_t propval_cell_n(struct property *prop, int n) 444 1.1.1.3 skrll { 445 1.1.1.3 skrll assert(prop->val.len / sizeof(cell_t) >= n); 446 1.1.1.3 skrll return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); 447 1.1.1.3 skrll } 448 1.1.1.3 skrll 449 1.1 macallan struct property *get_property_by_label(struct node *tree, const char *label, 450 1.1 macallan struct node **node) 451 1.1 macallan { 452 1.1 macallan struct property *prop; 453 1.1 macallan struct node *c; 454 1.1 macallan 455 1.1 macallan *node = tree; 456 1.1 macallan 457 1.1 macallan for_each_property(tree, prop) { 458 1.1 macallan struct label *l; 459 1.1 macallan 460 1.1 macallan for_each_label(prop->labels, l) 461 1.1 macallan if (streq(l->label, label)) 462 1.1 macallan return prop; 463 1.1 macallan } 464 1.1 macallan 465 1.1 macallan for_each_child(tree, c) { 466 1.1 macallan prop = get_property_by_label(c, label, node); 467 1.1 macallan if (prop) 468 1.1 macallan return prop; 469 1.1 macallan } 470 1.1 macallan 471 1.1 macallan *node = NULL; 472 1.1 macallan return NULL; 473 1.1 macallan } 474 1.1 macallan 475 1.1 macallan struct marker *get_marker_label(struct node *tree, const char *label, 476 1.1 macallan struct node **node, struct property **prop) 477 1.1 macallan { 478 1.1 macallan struct marker *m; 479 1.1 macallan struct property *p; 480 1.1 macallan struct node *c; 481 1.1 macallan 482 1.1 macallan *node = tree; 483 1.1 macallan 484 1.1 macallan for_each_property(tree, p) { 485 1.1 macallan *prop = p; 486 1.1 macallan m = p->val.markers; 487 1.1 macallan for_each_marker_of_type(m, LABEL) 488 1.1 macallan if (streq(m->ref, label)) 489 1.1 macallan return m; 490 1.1 macallan } 491 1.1 macallan 492 1.1 macallan for_each_child(tree, c) { 493 1.1 macallan m = get_marker_label(c, label, node, prop); 494 1.1 macallan if (m) 495 1.1 macallan return m; 496 1.1 macallan } 497 1.1 macallan 498 1.1 macallan *prop = NULL; 499 1.1 macallan *node = NULL; 500 1.1 macallan return NULL; 501 1.1 macallan } 502 1.1 macallan 503 1.1 macallan struct node *get_subnode(struct node *node, const char *nodename) 504 1.1 macallan { 505 1.1 macallan struct node *child; 506 1.1 macallan 507 1.1 macallan for_each_child(node, child) 508 1.1 macallan if (streq(child->name, nodename)) 509 1.1 macallan return child; 510 1.1 macallan 511 1.1 macallan return NULL; 512 1.1 macallan } 513 1.1 macallan 514 1.1 macallan struct node *get_node_by_path(struct node *tree, const char *path) 515 1.1 macallan { 516 1.1 macallan const char *p; 517 1.1 macallan struct node *child; 518 1.1 macallan 519 1.1 macallan if (!path || ! (*path)) { 520 1.1 macallan if (tree->deleted) 521 1.1 macallan return NULL; 522 1.1 macallan return tree; 523 1.1 macallan } 524 1.1 macallan 525 1.1 macallan while (path[0] == '/') 526 1.1 macallan path++; 527 1.1 macallan 528 1.1 macallan p = strchr(path, '/'); 529 1.1 macallan 530 1.1 macallan for_each_child(tree, child) { 531 1.1.1.3 skrll if (p && strprefixeq(path, p - path, child->name)) 532 1.1 macallan return get_node_by_path(child, p+1); 533 1.1 macallan else if (!p && streq(path, child->name)) 534 1.1 macallan return child; 535 1.1 macallan } 536 1.1 macallan 537 1.1 macallan return NULL; 538 1.1 macallan } 539 1.1 macallan 540 1.1 macallan struct node *get_node_by_label(struct node *tree, const char *label) 541 1.1 macallan { 542 1.1 macallan struct node *child, *node; 543 1.1 macallan struct label *l; 544 1.1 macallan 545 1.1 macallan assert(label && (strlen(label) > 0)); 546 1.1 macallan 547 1.1 macallan for_each_label(tree->labels, l) 548 1.1 macallan if (streq(l->label, label)) 549 1.1 macallan return tree; 550 1.1 macallan 551 1.1 macallan for_each_child(tree, child) { 552 1.1 macallan node = get_node_by_label(child, label); 553 1.1 macallan if (node) 554 1.1 macallan return node; 555 1.1 macallan } 556 1.1 macallan 557 1.1 macallan return NULL; 558 1.1 macallan } 559 1.1 macallan 560 1.1 macallan struct node *get_node_by_phandle(struct node *tree, cell_t phandle) 561 1.1 macallan { 562 1.1 macallan struct node *child, *node; 563 1.1 macallan 564 1.1.1.3 skrll if ((phandle == 0) || (phandle == -1)) { 565 1.1.1.3 skrll assert(generate_fixups); 566 1.1.1.3 skrll return NULL; 567 1.1.1.3 skrll } 568 1.1 macallan 569 1.1 macallan if (tree->phandle == phandle) { 570 1.1 macallan if (tree->deleted) 571 1.1 macallan return NULL; 572 1.1 macallan return tree; 573 1.1 macallan } 574 1.1 macallan 575 1.1 macallan for_each_child(tree, child) { 576 1.1 macallan node = get_node_by_phandle(child, phandle); 577 1.1 macallan if (node) 578 1.1 macallan return node; 579 1.1 macallan } 580 1.1 macallan 581 1.1 macallan return NULL; 582 1.1 macallan } 583 1.1 macallan 584 1.1 macallan struct node *get_node_by_ref(struct node *tree, const char *ref) 585 1.1 macallan { 586 1.1 macallan if (streq(ref, "/")) 587 1.1 macallan return tree; 588 1.1 macallan else if (ref[0] == '/') 589 1.1 macallan return get_node_by_path(tree, ref); 590 1.1 macallan else 591 1.1 macallan return get_node_by_label(tree, ref); 592 1.1 macallan } 593 1.1 macallan 594 1.1 macallan cell_t get_node_phandle(struct node *root, struct node *node) 595 1.1 macallan { 596 1.1 macallan static cell_t phandle = 1; /* FIXME: ick, static local */ 597 1.1.1.3 skrll struct data d = empty_data; 598 1.1 macallan 599 1.1 macallan if ((node->phandle != 0) && (node->phandle != -1)) 600 1.1 macallan return node->phandle; 601 1.1 macallan 602 1.1 macallan while (get_node_by_phandle(root, phandle)) 603 1.1 macallan phandle++; 604 1.1 macallan 605 1.1 macallan node->phandle = phandle; 606 1.1 macallan 607 1.1.1.3 skrll d = data_add_marker(d, TYPE_UINT32, NULL); 608 1.1.1.3 skrll d = data_append_cell(d, phandle); 609 1.1.1.3 skrll 610 1.1 macallan if (!get_property(node, "linux,phandle") 611 1.1 macallan && (phandle_format & PHANDLE_LEGACY)) 612 1.1.1.3 skrll add_property(node, build_property("linux,phandle", d, NULL)); 613 1.1 macallan 614 1.1 macallan if (!get_property(node, "phandle") 615 1.1 macallan && (phandle_format & PHANDLE_EPAPR)) 616 1.1.1.3 skrll add_property(node, build_property("phandle", d, NULL)); 617 1.1 macallan 618 1.1 macallan /* If the node *does* have a phandle property, we must 619 1.1 macallan * be dealing with a self-referencing phandle, which will be 620 1.1 macallan * fixed up momentarily in the caller */ 621 1.1 macallan 622 1.1 macallan return node->phandle; 623 1.1 macallan } 624 1.1 macallan 625 1.1 macallan uint32_t guess_boot_cpuid(struct node *tree) 626 1.1 macallan { 627 1.1 macallan struct node *cpus, *bootcpu; 628 1.1 macallan struct property *reg; 629 1.1 macallan 630 1.1 macallan cpus = get_node_by_path(tree, "/cpus"); 631 1.1 macallan if (!cpus) 632 1.1 macallan return 0; 633 1.1 macallan 634 1.1 macallan 635 1.1 macallan bootcpu = cpus->children; 636 1.1 macallan if (!bootcpu) 637 1.1 macallan return 0; 638 1.1 macallan 639 1.1 macallan reg = get_property(bootcpu, "reg"); 640 1.1 macallan if (!reg || (reg->val.len != sizeof(uint32_t))) 641 1.1 macallan return 0; 642 1.1 macallan 643 1.1 macallan /* FIXME: Sanity check node? */ 644 1.1 macallan 645 1.1 macallan return propval_cell(reg); 646 1.1 macallan } 647 1.1 macallan 648 1.1 macallan static int cmp_reserve_info(const void *ax, const void *bx) 649 1.1 macallan { 650 1.1 macallan const struct reserve_info *a, *b; 651 1.1 macallan 652 1.1 macallan a = *((const struct reserve_info * const *)ax); 653 1.1 macallan b = *((const struct reserve_info * const *)bx); 654 1.1 macallan 655 1.1.1.2 skrll if (a->address < b->address) 656 1.1 macallan return -1; 657 1.1.1.2 skrll else if (a->address > b->address) 658 1.1 macallan return 1; 659 1.1.1.2 skrll else if (a->size < b->size) 660 1.1 macallan return -1; 661 1.1.1.2 skrll else if (a->size > b->size) 662 1.1 macallan return 1; 663 1.1 macallan else 664 1.1 macallan return 0; 665 1.1 macallan } 666 1.1 macallan 667 1.1.1.2 skrll static void sort_reserve_entries(struct dt_info *dti) 668 1.1 macallan { 669 1.1 macallan struct reserve_info *ri, **tbl; 670 1.1 macallan int n = 0, i = 0; 671 1.1 macallan 672 1.1.1.2 skrll for (ri = dti->reservelist; 673 1.1 macallan ri; 674 1.1 macallan ri = ri->next) 675 1.1 macallan n++; 676 1.1 macallan 677 1.1 macallan if (n == 0) 678 1.1 macallan return; 679 1.1 macallan 680 1.1 macallan tbl = xmalloc(n * sizeof(*tbl)); 681 1.1 macallan 682 1.1.1.2 skrll for (ri = dti->reservelist; 683 1.1 macallan ri; 684 1.1 macallan ri = ri->next) 685 1.1 macallan tbl[i++] = ri; 686 1.1 macallan 687 1.1 macallan qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); 688 1.1 macallan 689 1.1.1.2 skrll dti->reservelist = tbl[0]; 690 1.1 macallan for (i = 0; i < (n-1); i++) 691 1.1 macallan tbl[i]->next = tbl[i+1]; 692 1.1 macallan tbl[n-1]->next = NULL; 693 1.1 macallan 694 1.1 macallan free(tbl); 695 1.1 macallan } 696 1.1 macallan 697 1.1 macallan static int cmp_prop(const void *ax, const void *bx) 698 1.1 macallan { 699 1.1 macallan const struct property *a, *b; 700 1.1 macallan 701 1.1 macallan a = *((const struct property * const *)ax); 702 1.1 macallan b = *((const struct property * const *)bx); 703 1.1 macallan 704 1.1 macallan return strcmp(a->name, b->name); 705 1.1 macallan } 706 1.1 macallan 707 1.1 macallan static void sort_properties(struct node *node) 708 1.1 macallan { 709 1.1 macallan int n = 0, i = 0; 710 1.1 macallan struct property *prop, **tbl; 711 1.1 macallan 712 1.1 macallan for_each_property_withdel(node, prop) 713 1.1 macallan n++; 714 1.1 macallan 715 1.1 macallan if (n == 0) 716 1.1 macallan return; 717 1.1 macallan 718 1.1 macallan tbl = xmalloc(n * sizeof(*tbl)); 719 1.1 macallan 720 1.1 macallan for_each_property_withdel(node, prop) 721 1.1 macallan tbl[i++] = prop; 722 1.1 macallan 723 1.1 macallan qsort(tbl, n, sizeof(*tbl), cmp_prop); 724 1.1 macallan 725 1.1 macallan node->proplist = tbl[0]; 726 1.1 macallan for (i = 0; i < (n-1); i++) 727 1.1 macallan tbl[i]->next = tbl[i+1]; 728 1.1 macallan tbl[n-1]->next = NULL; 729 1.1 macallan 730 1.1 macallan free(tbl); 731 1.1 macallan } 732 1.1 macallan 733 1.1 macallan static int cmp_subnode(const void *ax, const void *bx) 734 1.1 macallan { 735 1.1 macallan const struct node *a, *b; 736 1.1 macallan 737 1.1 macallan a = *((const struct node * const *)ax); 738 1.1 macallan b = *((const struct node * const *)bx); 739 1.1 macallan 740 1.1 macallan return strcmp(a->name, b->name); 741 1.1 macallan } 742 1.1 macallan 743 1.1 macallan static void sort_subnodes(struct node *node) 744 1.1 macallan { 745 1.1 macallan int n = 0, i = 0; 746 1.1 macallan struct node *subnode, **tbl; 747 1.1 macallan 748 1.1 macallan for_each_child_withdel(node, subnode) 749 1.1 macallan n++; 750 1.1 macallan 751 1.1 macallan if (n == 0) 752 1.1 macallan return; 753 1.1 macallan 754 1.1 macallan tbl = xmalloc(n * sizeof(*tbl)); 755 1.1 macallan 756 1.1 macallan for_each_child_withdel(node, subnode) 757 1.1 macallan tbl[i++] = subnode; 758 1.1 macallan 759 1.1 macallan qsort(tbl, n, sizeof(*tbl), cmp_subnode); 760 1.1 macallan 761 1.1 macallan node->children = tbl[0]; 762 1.1 macallan for (i = 0; i < (n-1); i++) 763 1.1 macallan tbl[i]->next_sibling = tbl[i+1]; 764 1.1 macallan tbl[n-1]->next_sibling = NULL; 765 1.1 macallan 766 1.1 macallan free(tbl); 767 1.1 macallan } 768 1.1 macallan 769 1.1 macallan static void sort_node(struct node *node) 770 1.1 macallan { 771 1.1 macallan struct node *c; 772 1.1 macallan 773 1.1 macallan sort_properties(node); 774 1.1 macallan sort_subnodes(node); 775 1.1 macallan for_each_child_withdel(node, c) 776 1.1 macallan sort_node(c); 777 1.1 macallan } 778 1.1 macallan 779 1.1.1.2 skrll void sort_tree(struct dt_info *dti) 780 1.1.1.2 skrll { 781 1.1.1.2 skrll sort_reserve_entries(dti); 782 1.1.1.2 skrll sort_node(dti->dt); 783 1.1.1.2 skrll } 784 1.1.1.2 skrll 785 1.1.1.2 skrll /* utility helper to avoid code duplication */ 786 1.1.1.2 skrll static struct node *build_and_name_child_node(struct node *parent, char *name) 787 1.1.1.2 skrll { 788 1.1.1.2 skrll struct node *node; 789 1.1.1.2 skrll 790 1.1.1.3 skrll node = build_node(NULL, NULL, NULL); 791 1.1.1.2 skrll name_node(node, xstrdup(name)); 792 1.1.1.2 skrll add_child(parent, node); 793 1.1.1.2 skrll 794 1.1.1.2 skrll return node; 795 1.1.1.2 skrll } 796 1.1.1.2 skrll 797 1.1.1.2 skrll static struct node *build_root_node(struct node *dt, char *name) 798 1.1.1.2 skrll { 799 1.1.1.2 skrll struct node *an; 800 1.1.1.2 skrll 801 1.1.1.2 skrll an = get_subnode(dt, name); 802 1.1.1.2 skrll if (!an) 803 1.1.1.2 skrll an = build_and_name_child_node(dt, name); 804 1.1.1.2 skrll 805 1.1.1.2 skrll if (!an) 806 1.1.1.2 skrll die("Could not build root node /%s\n", name); 807 1.1.1.2 skrll 808 1.1.1.2 skrll return an; 809 1.1.1.2 skrll } 810 1.1.1.2 skrll 811 1.1.1.2 skrll static bool any_label_tree(struct dt_info *dti, struct node *node) 812 1.1.1.2 skrll { 813 1.1.1.2 skrll struct node *c; 814 1.1.1.2 skrll 815 1.1.1.2 skrll if (node->labels) 816 1.1.1.2 skrll return true; 817 1.1.1.2 skrll 818 1.1.1.2 skrll for_each_child(node, c) 819 1.1.1.2 skrll if (any_label_tree(dti, c)) 820 1.1.1.2 skrll return true; 821 1.1.1.2 skrll 822 1.1.1.2 skrll return false; 823 1.1.1.2 skrll } 824 1.1.1.2 skrll 825 1.1.1.2 skrll static void generate_label_tree_internal(struct dt_info *dti, 826 1.1.1.2 skrll struct node *an, struct node *node, 827 1.1.1.2 skrll bool allocph) 828 1.1.1.2 skrll { 829 1.1.1.2 skrll struct node *dt = dti->dt; 830 1.1.1.2 skrll struct node *c; 831 1.1.1.2 skrll struct property *p; 832 1.1.1.2 skrll struct label *l; 833 1.1.1.2 skrll 834 1.1.1.2 skrll /* if there are labels */ 835 1.1.1.2 skrll if (node->labels) { 836 1.1.1.2 skrll 837 1.1.1.2 skrll /* now add the label in the node */ 838 1.1.1.2 skrll for_each_label(node->labels, l) { 839 1.1.1.2 skrll 840 1.1.1.2 skrll /* check whether the label already exists */ 841 1.1.1.2 skrll p = get_property(an, l->label); 842 1.1.1.2 skrll if (p) { 843 1.1.1.2 skrll fprintf(stderr, "WARNING: label %s already" 844 1.1.1.2 skrll " exists in /%s", l->label, 845 1.1.1.2 skrll an->name); 846 1.1.1.2 skrll continue; 847 1.1.1.2 skrll } 848 1.1.1.2 skrll 849 1.1.1.2 skrll /* insert it */ 850 1.1.1.2 skrll p = build_property(l->label, 851 1.1.1.3 skrll data_copy_escape_string(node->fullpath, 852 1.1.1.3 skrll strlen(node->fullpath)), 853 1.1.1.3 skrll NULL); 854 1.1.1.2 skrll add_property(an, p); 855 1.1.1.2 skrll } 856 1.1.1.2 skrll 857 1.1.1.2 skrll /* force allocation of a phandle for this node */ 858 1.1.1.2 skrll if (allocph) 859 1.1.1.2 skrll (void)get_node_phandle(dt, node); 860 1.1.1.2 skrll } 861 1.1.1.2 skrll 862 1.1.1.2 skrll for_each_child(node, c) 863 1.1.1.2 skrll generate_label_tree_internal(dti, an, c, allocph); 864 1.1.1.2 skrll } 865 1.1.1.2 skrll 866 1.1.1.2 skrll static bool any_fixup_tree(struct dt_info *dti, struct node *node) 867 1.1.1.2 skrll { 868 1.1.1.2 skrll struct node *c; 869 1.1.1.2 skrll struct property *prop; 870 1.1.1.2 skrll struct marker *m; 871 1.1.1.2 skrll 872 1.1.1.2 skrll for_each_property(node, prop) { 873 1.1.1.2 skrll m = prop->val.markers; 874 1.1.1.2 skrll for_each_marker_of_type(m, REF_PHANDLE) { 875 1.1.1.2 skrll if (!get_node_by_ref(dti->dt, m->ref)) 876 1.1.1.2 skrll return true; 877 1.1.1.2 skrll } 878 1.1.1.2 skrll } 879 1.1.1.2 skrll 880 1.1.1.2 skrll for_each_child(node, c) { 881 1.1.1.2 skrll if (any_fixup_tree(dti, c)) 882 1.1.1.2 skrll return true; 883 1.1.1.2 skrll } 884 1.1.1.2 skrll 885 1.1.1.2 skrll return false; 886 1.1.1.2 skrll } 887 1.1.1.2 skrll 888 1.1.1.2 skrll static void add_fixup_entry(struct dt_info *dti, struct node *fn, 889 1.1.1.2 skrll struct node *node, struct property *prop, 890 1.1.1.2 skrll struct marker *m) 891 1.1 macallan { 892 1.1.1.2 skrll char *entry; 893 1.1.1.2 skrll 894 1.1.1.2 skrll /* m->ref can only be a REF_PHANDLE, but check anyway */ 895 1.1.1.2 skrll assert(m->type == REF_PHANDLE); 896 1.1.1.2 skrll 897 1.1.1.2 skrll /* there shouldn't be any ':' in the arguments */ 898 1.1.1.2 skrll if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) 899 1.1.1.2 skrll die("arguments should not contain ':'\n"); 900 1.1.1.2 skrll 901 1.1.1.2 skrll xasprintf(&entry, "%s:%s:%u", 902 1.1.1.2 skrll node->fullpath, prop->name, m->offset); 903 1.1.1.3 skrll append_to_property(fn, m->ref, entry, strlen(entry) + 1, TYPE_STRING); 904 1.1.1.2 skrll 905 1.1.1.2 skrll free(entry); 906 1.1.1.2 skrll } 907 1.1.1.2 skrll 908 1.1.1.2 skrll static void generate_fixups_tree_internal(struct dt_info *dti, 909 1.1.1.2 skrll struct node *fn, 910 1.1.1.2 skrll struct node *node) 911 1.1.1.2 skrll { 912 1.1.1.2 skrll struct node *dt = dti->dt; 913 1.1.1.2 skrll struct node *c; 914 1.1.1.2 skrll struct property *prop; 915 1.1.1.2 skrll struct marker *m; 916 1.1.1.2 skrll struct node *refnode; 917 1.1.1.2 skrll 918 1.1.1.2 skrll for_each_property(node, prop) { 919 1.1.1.2 skrll m = prop->val.markers; 920 1.1.1.2 skrll for_each_marker_of_type(m, REF_PHANDLE) { 921 1.1.1.2 skrll refnode = get_node_by_ref(dt, m->ref); 922 1.1.1.2 skrll if (!refnode) 923 1.1.1.2 skrll add_fixup_entry(dti, fn, node, prop, m); 924 1.1.1.2 skrll } 925 1.1.1.2 skrll } 926 1.1.1.2 skrll 927 1.1.1.2 skrll for_each_child(node, c) 928 1.1.1.2 skrll generate_fixups_tree_internal(dti, fn, c); 929 1.1.1.2 skrll } 930 1.1.1.2 skrll 931 1.1.1.2 skrll static bool any_local_fixup_tree(struct dt_info *dti, struct node *node) 932 1.1.1.2 skrll { 933 1.1.1.2 skrll struct node *c; 934 1.1.1.2 skrll struct property *prop; 935 1.1.1.2 skrll struct marker *m; 936 1.1.1.2 skrll 937 1.1.1.2 skrll for_each_property(node, prop) { 938 1.1.1.2 skrll m = prop->val.markers; 939 1.1.1.2 skrll for_each_marker_of_type(m, REF_PHANDLE) { 940 1.1.1.2 skrll if (get_node_by_ref(dti->dt, m->ref)) 941 1.1.1.2 skrll return true; 942 1.1.1.2 skrll } 943 1.1.1.2 skrll } 944 1.1.1.2 skrll 945 1.1.1.2 skrll for_each_child(node, c) { 946 1.1.1.2 skrll if (any_local_fixup_tree(dti, c)) 947 1.1.1.2 skrll return true; 948 1.1.1.2 skrll } 949 1.1.1.2 skrll 950 1.1.1.2 skrll return false; 951 1.1.1.2 skrll } 952 1.1.1.2 skrll 953 1.1.1.2 skrll static void add_local_fixup_entry(struct dt_info *dti, 954 1.1.1.2 skrll struct node *lfn, struct node *node, 955 1.1.1.2 skrll struct property *prop, struct marker *m, 956 1.1.1.2 skrll struct node *refnode) 957 1.1.1.2 skrll { 958 1.1.1.2 skrll struct node *wn, *nwn; /* local fixup node, walk node, new */ 959 1.1.1.2 skrll fdt32_t value_32; 960 1.1.1.2 skrll char **compp; 961 1.1.1.2 skrll int i, depth; 962 1.1.1.2 skrll 963 1.1.1.3 skrll /* walk back retrieving depth */ 964 1.1.1.2 skrll depth = 0; 965 1.1.1.2 skrll for (wn = node; wn; wn = wn->parent) 966 1.1.1.2 skrll depth++; 967 1.1.1.2 skrll 968 1.1.1.2 skrll /* allocate name array */ 969 1.1.1.2 skrll compp = xmalloc(sizeof(*compp) * depth); 970 1.1.1.2 skrll 971 1.1.1.2 skrll /* store names in the array */ 972 1.1.1.2 skrll for (wn = node, i = depth - 1; wn; wn = wn->parent, i--) 973 1.1.1.2 skrll compp[i] = wn->name; 974 1.1.1.2 skrll 975 1.1.1.2 skrll /* walk the path components creating nodes if they don't exist */ 976 1.1.1.2 skrll for (wn = lfn, i = 1; i < depth; i++, wn = nwn) { 977 1.1.1.2 skrll /* if no node exists, create it */ 978 1.1.1.2 skrll nwn = get_subnode(wn, compp[i]); 979 1.1.1.2 skrll if (!nwn) 980 1.1.1.2 skrll nwn = build_and_name_child_node(wn, compp[i]); 981 1.1.1.2 skrll } 982 1.1.1.2 skrll 983 1.1.1.2 skrll free(compp); 984 1.1.1.2 skrll 985 1.1.1.2 skrll value_32 = cpu_to_fdt32(m->offset); 986 1.1.1.3 skrll append_to_property(wn, prop->name, &value_32, sizeof(value_32), TYPE_UINT32); 987 1.1.1.2 skrll } 988 1.1.1.2 skrll 989 1.1.1.2 skrll static void generate_local_fixups_tree_internal(struct dt_info *dti, 990 1.1.1.2 skrll struct node *lfn, 991 1.1.1.2 skrll struct node *node) 992 1.1.1.2 skrll { 993 1.1.1.2 skrll struct node *dt = dti->dt; 994 1.1.1.2 skrll struct node *c; 995 1.1.1.2 skrll struct property *prop; 996 1.1.1.2 skrll struct marker *m; 997 1.1.1.2 skrll struct node *refnode; 998 1.1.1.2 skrll 999 1.1.1.2 skrll for_each_property(node, prop) { 1000 1.1.1.2 skrll m = prop->val.markers; 1001 1.1.1.2 skrll for_each_marker_of_type(m, REF_PHANDLE) { 1002 1.1.1.2 skrll refnode = get_node_by_ref(dt, m->ref); 1003 1.1.1.2 skrll if (refnode) 1004 1.1.1.2 skrll add_local_fixup_entry(dti, lfn, node, prop, m, refnode); 1005 1.1.1.2 skrll } 1006 1.1.1.2 skrll } 1007 1.1.1.2 skrll 1008 1.1.1.2 skrll for_each_child(node, c) 1009 1.1.1.2 skrll generate_local_fixups_tree_internal(dti, lfn, c); 1010 1.1.1.2 skrll } 1011 1.1.1.2 skrll 1012 1.1.1.2 skrll void generate_label_tree(struct dt_info *dti, char *name, bool allocph) 1013 1.1.1.2 skrll { 1014 1.1.1.2 skrll if (!any_label_tree(dti, dti->dt)) 1015 1.1.1.2 skrll return; 1016 1.1.1.2 skrll generate_label_tree_internal(dti, build_root_node(dti->dt, name), 1017 1.1.1.2 skrll dti->dt, allocph); 1018 1.1.1.2 skrll } 1019 1.1.1.2 skrll 1020 1.1.1.2 skrll void generate_fixups_tree(struct dt_info *dti, char *name) 1021 1.1.1.2 skrll { 1022 1.1.1.2 skrll if (!any_fixup_tree(dti, dti->dt)) 1023 1.1.1.2 skrll return; 1024 1.1.1.2 skrll generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), 1025 1.1.1.2 skrll dti->dt); 1026 1.1.1.2 skrll } 1027 1.1.1.2 skrll 1028 1.1.1.2 skrll void generate_local_fixups_tree(struct dt_info *dti, char *name) 1029 1.1.1.2 skrll { 1030 1.1.1.2 skrll if (!any_local_fixup_tree(dti, dti->dt)) 1031 1.1.1.2 skrll return; 1032 1.1.1.2 skrll generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), 1033 1.1.1.2 skrll dti->dt); 1034 1.1 macallan } 1035