1 /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ 2 #ifndef LIBFDT_H 3 #define LIBFDT_H 4 /* 5 * libfdt - Flat Device Tree manipulation 6 * Copyright (C) 2006 David Gibson, IBM Corporation. 7 */ 8 9 #include "libfdt_env.h" 10 #include "fdt.h" 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 #define FDT_FIRST_SUPPORTED_VERSION 0x02 17 #define FDT_LAST_COMPATIBLE_VERSION 0x10 18 #define FDT_LAST_SUPPORTED_VERSION 0x11 19 20 /* Error codes: informative error codes */ 21 #define FDT_ERR_NOTFOUND 1 22 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ 23 #define FDT_ERR_EXISTS 2 24 /* FDT_ERR_EXISTS: Attempted to create a node or property which 25 * already exists */ 26 #define FDT_ERR_NOSPACE 3 27 /* FDT_ERR_NOSPACE: Operation needed to expand the device 28 * tree, but its buffer did not have sufficient space to 29 * contain the expanded tree. Use fdt_open_into() to move the 30 * device tree to a buffer with more space. */ 31 32 /* Error codes: codes for bad parameters */ 33 #define FDT_ERR_BADOFFSET 4 34 /* FDT_ERR_BADOFFSET: Function was passed a structure block 35 * offset which is out-of-bounds, or which points to an 36 * unsuitable part of the structure for the operation. */ 37 #define FDT_ERR_BADPATH 5 38 /* FDT_ERR_BADPATH: Function was passed a badly formatted path 39 * (e.g. missing a leading / for a function which requires an 40 * absolute path) */ 41 #define FDT_ERR_BADPHANDLE 6 42 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. 43 * This can be caused either by an invalid phandle property 44 * length, or the phandle value was either 0 or -1, which are 45 * not permitted. */ 46 #define FDT_ERR_BADSTATE 7 47 /* FDT_ERR_BADSTATE: Function was passed an incomplete device 48 * tree created by the sequential-write functions, which is 49 * not sufficiently complete for the requested operation. */ 50 51 /* Error codes: codes for bad device tree blobs */ 52 #define FDT_ERR_TRUNCATED 8 53 /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly 54 * terminated (overflows, goes outside allowed bounds, or 55 * isn't properly terminated). */ 56 #define FDT_ERR_BADMAGIC 9 57 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a 58 * device tree at all - it is missing the flattened device 59 * tree magic number. */ 60 #define FDT_ERR_BADVERSION 10 61 /* FDT_ERR_BADVERSION: Given device tree has a version which 62 * can't be handled by the requested operation. For 63 * read-write functions, this may mean that fdt_open_into() is 64 * required to convert the tree to the expected version. */ 65 #define FDT_ERR_BADSTRUCTURE 11 66 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt 67 * structure block or other serious error (e.g. misnested 68 * nodes, or subnodes preceding properties). */ 69 #define FDT_ERR_BADLAYOUT 12 70 /* FDT_ERR_BADLAYOUT: For read-write functions, the given 71 * device tree has it's sub-blocks in an order that the 72 * function can't handle (memory reserve map, then structure, 73 * then strings). Use fdt_open_into() to reorganize the tree 74 * into a form suitable for the read-write operations. */ 75 76 /* "Can't happen" error indicating a bug in libfdt */ 77 #define FDT_ERR_INTERNAL 13 78 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. 79 * Should never be returned, if it is, it indicates a bug in 80 * libfdt itself. */ 81 82 /* Errors in device tree content */ 83 #define FDT_ERR_BADNCELLS 14 84 /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells 85 * or similar property with a bad format or value */ 86 87 #define FDT_ERR_BADVALUE 15 88 /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected 89 * value. For example: a property expected to contain a string list 90 * is not NUL-terminated within the length of its value. */ 91 92 #define FDT_ERR_BADOVERLAY 16 93 /* FDT_ERR_BADOVERLAY: The device tree overlay, while 94 * correctly structured, cannot be applied due to some 95 * unexpected or missing value, property or node. */ 96 97 #define FDT_ERR_NOPHANDLES 17 98 /* FDT_ERR_NOPHANDLES: The device tree doesn't have any 99 * phandle available anymore without causing an overflow */ 100 101 #define FDT_ERR_BADFLAGS 18 102 /* FDT_ERR_BADFLAGS: The function was passed a flags field that 103 * contains invalid flags or an invalid combination of flags. */ 104 105 #define FDT_ERR_ALIGNMENT 19 106 /* FDT_ERR_ALIGNMENT: The device tree base address is not 8-byte 107 * aligned. */ 108 109 #define FDT_ERR_MAX 19 110 111 /* constants */ 112 #define FDT_MAX_PHANDLE 0xfffffffe 113 /* Valid values for phandles range from 1 to 2^32-2. */ 114 115 /**********************************************************************/ 116 /* Low-level functions (you probably don't need these) */ 117 /**********************************************************************/ 118 119 #ifndef SWIG /* This function is not useful in Python */ 120 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); 121 #endif 122 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) 123 { 124 return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); 125 } 126 127 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); 128 129 /* 130 * External helpers to access words from a device tree blob. They're built 131 * to work even with unaligned pointers on platforms (such as ARMv5) that don't 132 * like unaligned loads and stores. 133 */ 134 static inline uint16_t fdt16_ld(const fdt16_t *p) 135 { 136 const uint8_t *bp = (const uint8_t *)p; 137 138 return ((uint16_t)bp[0] << 8) | bp[1]; 139 } 140 141 static inline uint32_t fdt32_ld(const fdt32_t *p) 142 { 143 const uint8_t *bp = (const uint8_t *)p; 144 145 return ((uint32_t)bp[0] << 24) 146 | ((uint32_t)bp[1] << 16) 147 | ((uint32_t)bp[2] << 8) 148 | bp[3]; 149 } 150 151 static inline void fdt32_st(void *property, uint32_t value) 152 { 153 uint8_t *bp = (uint8_t *)property; 154 155 bp[0] = value >> 24; 156 bp[1] = (value >> 16) & 0xff; 157 bp[2] = (value >> 8) & 0xff; 158 bp[3] = value & 0xff; 159 } 160 161 static inline uint64_t fdt64_ld(const fdt64_t *p) 162 { 163 const uint8_t *bp = (const uint8_t *)p; 164 165 return ((uint64_t)bp[0] << 56) 166 | ((uint64_t)bp[1] << 48) 167 | ((uint64_t)bp[2] << 40) 168 | ((uint64_t)bp[3] << 32) 169 | ((uint64_t)bp[4] << 24) 170 | ((uint64_t)bp[5] << 16) 171 | ((uint64_t)bp[6] << 8) 172 | bp[7]; 173 } 174 175 static inline void fdt64_st(void *property, uint64_t value) 176 { 177 uint8_t *bp = (uint8_t *)property; 178 179 bp[0] = value >> 56; 180 bp[1] = (value >> 48) & 0xff; 181 bp[2] = (value >> 40) & 0xff; 182 bp[3] = (value >> 32) & 0xff; 183 bp[4] = (value >> 24) & 0xff; 184 bp[5] = (value >> 16) & 0xff; 185 bp[6] = (value >> 8) & 0xff; 186 bp[7] = value & 0xff; 187 } 188 189 /**********************************************************************/ 190 /* Traversal functions */ 191 /**********************************************************************/ 192 193 int fdt_next_node(const void *fdt, int offset, int *depth); 194 195 /** 196 * fdt_first_subnode() - get offset of first direct subnode 197 * @fdt: FDT blob 198 * @offset: Offset of node to check 199 * 200 * Return: offset of first subnode, or -FDT_ERR_NOTFOUND if there is none 201 */ 202 int fdt_first_subnode(const void *fdt, int offset); 203 204 /** 205 * fdt_next_subnode() - get offset of next direct subnode 206 * @fdt: FDT blob 207 * @offset: Offset of previous subnode 208 * 209 * After first calling fdt_first_subnode(), call this function repeatedly to 210 * get direct subnodes of a parent node. 211 * 212 * Return: offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more 213 * subnodes 214 */ 215 int fdt_next_subnode(const void *fdt, int offset); 216 217 /** 218 * fdt_for_each_subnode - iterate over all subnodes of a parent 219 * 220 * @node: child node (int, lvalue) 221 * @fdt: FDT blob (const void *) 222 * @parent: parent node (int) 223 * 224 * This is actually a wrapper around a for loop and would be used like so: 225 * 226 * fdt_for_each_subnode(node, fdt, parent) { 227 * Use node 228 * ... 229 * } 230 * 231 * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { 232 * Error handling 233 * } 234 * 235 * Note that this is implemented as a macro and @node is used as 236 * iterator in the loop. The parent variable be constant or even a 237 * literal. 238 */ 239 #define fdt_for_each_subnode(node, fdt, parent) \ 240 for (node = fdt_first_subnode(fdt, parent); \ 241 node >= 0; \ 242 node = fdt_next_subnode(fdt, node)) 243 244 /**********************************************************************/ 245 /* General functions */ 246 /**********************************************************************/ 247 #define fdt_get_header(fdt, field) \ 248 (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) 249 #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) 250 #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) 251 #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) 252 #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) 253 #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) 254 #define fdt_version(fdt) (fdt_get_header(fdt, version)) 255 #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) 256 #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) 257 #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) 258 #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) 259 260 #define fdt_set_hdr_(name) \ 261 static inline void fdt_set_##name(void *fdt, uint32_t val) \ 262 { \ 263 struct fdt_header *fdth = (struct fdt_header *)fdt; \ 264 fdth->name = cpu_to_fdt32(val); \ 265 } 266 fdt_set_hdr_(magic) 267 fdt_set_hdr_(totalsize) 268 fdt_set_hdr_(off_dt_struct) 269 fdt_set_hdr_(off_dt_strings) 270 fdt_set_hdr_(off_mem_rsvmap) 271 fdt_set_hdr_(version) 272 fdt_set_hdr_(last_comp_version) 273 fdt_set_hdr_(boot_cpuid_phys) 274 fdt_set_hdr_(size_dt_strings) 275 fdt_set_hdr_(size_dt_struct) 276 #undef fdt_set_hdr_ 277 278 /** 279 * fdt_header_size - return the size of the tree's header 280 * @fdt: pointer to a flattened device tree 281 * 282 * Return: size of DTB header in bytes 283 */ 284 size_t fdt_header_size(const void *fdt); 285 286 /** 287 * fdt_header_size_ - internal function to get header size from a version number 288 * @version: device tree version number 289 * 290 * Return: size of DTB header in bytes 291 */ 292 size_t fdt_header_size_(uint32_t version); 293 294 /** 295 * fdt_check_header - sanity check a device tree header 296 * @fdt: pointer to data which might be a flattened device tree 297 * 298 * fdt_check_header() checks that the given buffer contains what 299 * appears to be a flattened device tree, and that the header contains 300 * valid information (to the extent that can be determined from the 301 * header alone). 302 * 303 * returns: 304 * 0, if the buffer appears to contain a valid device tree 305 * -FDT_ERR_BADMAGIC, 306 * -FDT_ERR_BADVERSION, 307 * -FDT_ERR_BADSTATE, 308 * -FDT_ERR_TRUNCATED, standard meanings, as above 309 */ 310 int fdt_check_header(const void *fdt); 311 312 /** 313 * fdt_move - move a device tree around in memory 314 * @fdt: pointer to the device tree to move 315 * @buf: pointer to memory where the device is to be moved 316 * @bufsize: size of the memory space at buf 317 * 318 * fdt_move() relocates, if possible, the device tree blob located at 319 * fdt to the buffer at buf of size bufsize. The buffer may overlap 320 * with the existing device tree blob at fdt. Therefore, 321 * fdt_move(fdt, fdt, fdt_totalsize(fdt)) 322 * should always succeed. 323 * 324 * returns: 325 * 0, on success 326 * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree 327 * -FDT_ERR_BADMAGIC, 328 * -FDT_ERR_BADVERSION, 329 * -FDT_ERR_BADSTATE, standard meanings 330 */ 331 int fdt_move(const void *fdt, void *buf, int bufsize); 332 333 /**********************************************************************/ 334 /* Read-only functions */ 335 /**********************************************************************/ 336 337 int fdt_check_full(const void *fdt, size_t bufsize); 338 339 /** 340 * fdt_get_string - retrieve a string from the strings block of a device tree 341 * @fdt: pointer to the device tree blob 342 * @stroffset: offset of the string within the strings block (native endian) 343 * @lenp: optional pointer to return the string's length 344 * 345 * fdt_get_string() retrieves a pointer to a single string from the 346 * strings block of the device tree blob at fdt, and optionally also 347 * returns the string's length in *lenp. 348 * 349 * returns: 350 * a pointer to the string, on success 351 * NULL, if stroffset is out of bounds, or doesn't point to a valid string 352 */ 353 const char *fdt_get_string(const void *fdt, int stroffset, int *lenp); 354 355 /** 356 * fdt_string - retrieve a string from the strings block of a device tree 357 * @fdt: pointer to the device tree blob 358 * @stroffset: offset of the string within the strings block (native endian) 359 * 360 * fdt_string() retrieves a pointer to a single string from the 361 * strings block of the device tree blob at fdt. 362 * 363 * returns: 364 * a pointer to the string, on success 365 * NULL, if stroffset is out of bounds, or doesn't point to a valid string 366 */ 367 const char *fdt_string(const void *fdt, int stroffset); 368 369 /** 370 * fdt_find_max_phandle - find and return the highest phandle in a tree 371 * @fdt: pointer to the device tree blob 372 * @phandle: return location for the highest phandle value found in the tree 373 * 374 * fdt_find_max_phandle() finds the highest phandle value in the given device 375 * tree. The value returned in @phandle is only valid if the function returns 376 * success. 377 * 378 * returns: 379 * 0 on success or a negative error code on failure 380 */ 381 int fdt_find_max_phandle(const void *fdt, uint32_t *phandle); 382 383 /** 384 * fdt_get_max_phandle - retrieves the highest phandle in a tree 385 * @fdt: pointer to the device tree blob 386 * 387 * fdt_get_max_phandle retrieves the highest phandle in the given 388 * device tree. This will ignore badly formatted phandles, or phandles 389 * with a value of 0 or -1. 390 * 391 * This function is deprecated in favour of fdt_find_max_phandle(). 392 * 393 * returns: 394 * the highest phandle on success 395 * 0, if no phandle was found in the device tree 396 * -1, if an error occurred 397 */ 398 static inline uint32_t fdt_get_max_phandle(const void *fdt) 399 { 400 uint32_t phandle; 401 int err; 402 403 err = fdt_find_max_phandle(fdt, &phandle); 404 if (err < 0) 405 return (uint32_t)-1; 406 407 return phandle; 408 } 409 410 /** 411 * fdt_generate_phandle - return a new, unused phandle for a device tree blob 412 * @fdt: pointer to the device tree blob 413 * @phandle: return location for the new phandle 414 * 415 * Walks the device tree blob and looks for the highest phandle value. On 416 * success, the new, unused phandle value (one higher than the previously 417 * highest phandle value in the device tree blob) will be returned in the 418 * @phandle parameter. 419 * 420 * Return: 0 on success or a negative error-code on failure 421 */ 422 int fdt_generate_phandle(const void *fdt, uint32_t *phandle); 423 424 /** 425 * fdt_num_mem_rsv - retrieve the number of memory reserve map entries 426 * @fdt: pointer to the device tree blob 427 * 428 * Returns the number of entries in the device tree blob's memory 429 * reservation map. This does not include the terminating 0,0 entry 430 * or any other (0,0) entries reserved for expansion. 431 * 432 * returns: 433 * the number of entries 434 */ 435 int fdt_num_mem_rsv(const void *fdt); 436 437 /** 438 * fdt_get_mem_rsv - retrieve one memory reserve map entry 439 * @fdt: pointer to the device tree blob 440 * @n: index of reserve map entry 441 * @address: pointer to 64-bit variable to hold the start address 442 * @size: pointer to 64-bit variable to hold the size of the entry 443 * 444 * On success, @address and @size will contain the address and size of 445 * the n-th reserve map entry from the device tree blob, in 446 * native-endian format. 447 * 448 * returns: 449 * 0, on success 450 * -FDT_ERR_BADMAGIC, 451 * -FDT_ERR_BADVERSION, 452 * -FDT_ERR_BADSTATE, standard meanings 453 */ 454 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); 455 456 /** 457 * fdt_subnode_offset_namelen - find a subnode based on substring 458 * @fdt: pointer to the device tree blob 459 * @parentoffset: structure block offset of a node 460 * @name: name of the subnode to locate 461 * @namelen: number of characters of name to consider 462 * 463 * Identical to fdt_subnode_offset(), but only examine the first 464 * namelen characters of name for matching the subnode name. This is 465 * useful for finding subnodes based on a portion of a larger string, 466 * such as a full path. 467 * 468 * Return: offset of the subnode or -FDT_ERR_NOTFOUND if name not found. 469 */ 470 #ifndef SWIG /* Not available in Python */ 471 int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, 472 const char *name, int namelen); 473 #endif 474 /** 475 * fdt_subnode_offset - find a subnode of a given node 476 * @fdt: pointer to the device tree blob 477 * @parentoffset: structure block offset of a node 478 * @name: name of the subnode to locate 479 * 480 * fdt_subnode_offset() finds a subnode of the node at structure block 481 * offset parentoffset with the given name. name may include a unit 482 * address, in which case fdt_subnode_offset() will find the subnode 483 * with that unit address, or the unit address may be omitted, in 484 * which case fdt_subnode_offset() will find an arbitrary subnode 485 * whose name excluding unit address matches the given name. 486 * 487 * returns: 488 * structure block offset of the requested subnode (>=0), on success 489 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist 490 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE 491 * tag 492 * -FDT_ERR_BADMAGIC, 493 * -FDT_ERR_BADVERSION, 494 * -FDT_ERR_BADSTATE, 495 * -FDT_ERR_BADSTRUCTURE, 496 * -FDT_ERR_TRUNCATED, standard meanings. 497 */ 498 int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); 499 500 /** 501 * fdt_path_offset_namelen - find a tree node by its full path 502 * @fdt: pointer to the device tree blob 503 * @path: full path of the node to locate 504 * @namelen: number of characters of path to consider 505 * 506 * Identical to fdt_path_offset(), but only consider the first namelen 507 * characters of path as the path name. 508 * 509 * Return: offset of the node or negative libfdt error value otherwise 510 */ 511 #ifndef SWIG /* Not available in Python */ 512 int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); 513 #endif 514 515 /** 516 * fdt_path_offset - find a tree node by its full path 517 * @fdt: pointer to the device tree blob 518 * @path: full path of the node to locate 519 * 520 * fdt_path_offset() finds a node of a given path in the device tree. 521 * Each path component may omit the unit address portion, but the 522 * results of this are undefined if any such path component is 523 * ambiguous (that is if there are multiple nodes at the relevant 524 * level matching the given component, differentiated only by unit 525 * address). 526 * 527 * If the path is not absolute (i.e. does not begin with '/'), the 528 * first component is treated as an alias. That is, the property by 529 * that name is looked up in the /aliases node, and the value of that 530 * property used in place of that first component. 531 * 532 * For example, for this small fragment 533 * 534 * / { 535 * aliases { 536 * i2c2 = &foo; // RHS compiles to "/soc@0/i2c@30a40000/eeprom@52" 537 * }; 538 * soc@0 { 539 * foo: i2c@30a40000 { 540 * bar: eeprom@52 { 541 * }; 542 * }; 543 * }; 544 * }; 545 * 546 * these would be equivalent: 547 * 548 * /soc@0/i2c@30a40000/eeprom@52 549 * i2c2/eeprom@52 550 * 551 * returns: 552 * structure block offset of the node with the requested path (>=0), on 553 * success 554 * -FDT_ERR_BADPATH, given path does not begin with '/' and the first 555 * component is not a valid alias 556 * -FDT_ERR_NOTFOUND, if the requested node does not exist 557 * -FDT_ERR_BADMAGIC, 558 * -FDT_ERR_BADVERSION, 559 * -FDT_ERR_BADSTATE, 560 * -FDT_ERR_BADSTRUCTURE, 561 * -FDT_ERR_TRUNCATED, standard meanings. 562 */ 563 int fdt_path_offset(const void *fdt, const char *path); 564 565 /** 566 * fdt_get_name - retrieve the name of a given node 567 * @fdt: pointer to the device tree blob 568 * @nodeoffset: structure block offset of the starting node 569 * @lenp: pointer to an integer variable (will be overwritten) or NULL 570 * 571 * fdt_get_name() retrieves the name (including unit address) of the 572 * device tree node at structure block offset nodeoffset. If lenp is 573 * non-NULL, the length of this name is also returned, in the integer 574 * pointed to by lenp. 575 * 576 * returns: 577 * pointer to the node's name, on success 578 * If lenp is non-NULL, *lenp contains the length of that name 579 * (>=0) 580 * NULL, on error 581 * if lenp is non-NULL *lenp contains an error code (<0): 582 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE 583 * tag 584 * -FDT_ERR_BADMAGIC, 585 * -FDT_ERR_BADVERSION, 586 * -FDT_ERR_BADSTATE, standard meanings 587 */ 588 const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); 589 590 /** 591 * fdt_first_property_offset - find the offset of a node's first property 592 * @fdt: pointer to the device tree blob 593 * @nodeoffset: structure block offset of a node 594 * 595 * fdt_first_property_offset() finds the first property of the node at 596 * the given structure block offset. 597 * 598 * returns: 599 * structure block offset of the property (>=0), on success 600 * -FDT_ERR_NOTFOUND, if the requested node has no properties 601 * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag 602 * -FDT_ERR_BADMAGIC, 603 * -FDT_ERR_BADVERSION, 604 * -FDT_ERR_BADSTATE, 605 * -FDT_ERR_BADSTRUCTURE, 606 * -FDT_ERR_TRUNCATED, standard meanings. 607 */ 608 int fdt_first_property_offset(const void *fdt, int nodeoffset); 609 610 /** 611 * fdt_next_property_offset - step through a node's properties 612 * @fdt: pointer to the device tree blob 613 * @offset: structure block offset of a property 614 * 615 * fdt_next_property_offset() finds the property immediately after the 616 * one at the given structure block offset. This will be a property 617 * of the same node as the given property. 618 * 619 * returns: 620 * structure block offset of the next property (>=0), on success 621 * -FDT_ERR_NOTFOUND, if the given property is the last in its node 622 * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag 623 * -FDT_ERR_BADMAGIC, 624 * -FDT_ERR_BADVERSION, 625 * -FDT_ERR_BADSTATE, 626 * -FDT_ERR_BADSTRUCTURE, 627 * -FDT_ERR_TRUNCATED, standard meanings. 628 */ 629 int fdt_next_property_offset(const void *fdt, int offset); 630 631 /** 632 * fdt_for_each_property_offset - iterate over all properties of a node 633 * 634 * @property: property offset (int, lvalue) 635 * @fdt: FDT blob (const void *) 636 * @node: node offset (int) 637 * 638 * This is actually a wrapper around a for loop and would be used like so: 639 * 640 * fdt_for_each_property_offset(property, fdt, node) { 641 * Use property 642 * ... 643 * } 644 * 645 * if ((property < 0) && (property != -FDT_ERR_NOTFOUND)) { 646 * Error handling 647 * } 648 * 649 * Note that this is implemented as a macro and property is used as 650 * iterator in the loop. The node variable can be constant or even a 651 * literal. 652 */ 653 #define fdt_for_each_property_offset(property, fdt, node) \ 654 for (property = fdt_first_property_offset(fdt, node); \ 655 property >= 0; \ 656 property = fdt_next_property_offset(fdt, property)) 657 658 /** 659 * fdt_get_property_by_offset - retrieve the property at a given offset 660 * @fdt: pointer to the device tree blob 661 * @offset: offset of the property to retrieve 662 * @lenp: pointer to an integer variable (will be overwritten) or NULL 663 * 664 * fdt_get_property_by_offset() retrieves a pointer to the 665 * fdt_property structure within the device tree blob at the given 666 * offset. If lenp is non-NULL, the length of the property value is 667 * also returned, in the integer pointed to by lenp. 668 * 669 * Note that this code only works on device tree versions >= 16. fdt_getprop() 670 * works on all versions. 671 * 672 * returns: 673 * pointer to the structure representing the property 674 * if lenp is non-NULL, *lenp contains the length of the property 675 * value (>=0) 676 * NULL, on error 677 * if lenp is non-NULL, *lenp contains an error code (<0): 678 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag 679 * -FDT_ERR_BADMAGIC, 680 * -FDT_ERR_BADVERSION, 681 * -FDT_ERR_BADSTATE, 682 * -FDT_ERR_BADSTRUCTURE, 683 * -FDT_ERR_TRUNCATED, standard meanings 684 */ 685 const struct fdt_property *fdt_get_property_by_offset(const void *fdt, 686 int offset, 687 int *lenp); 688 static inline struct fdt_property *fdt_get_property_by_offset_w(void *fdt, 689 int offset, 690 int *lenp) 691 { 692 return (struct fdt_property *)(uintptr_t) 693 fdt_get_property_by_offset(fdt, offset, lenp); 694 } 695 696 /** 697 * fdt_get_property_namelen - find a property based on substring 698 * @fdt: pointer to the device tree blob 699 * @nodeoffset: offset of the node whose property to find 700 * @name: name of the property to find 701 * @namelen: number of characters of name to consider 702 * @lenp: pointer to an integer variable (will be overwritten) or NULL 703 * 704 * Identical to fdt_get_property(), but only examine the first namelen 705 * characters of name for matching the property name. 706 * 707 * Return: pointer to the structure representing the property, or NULL 708 * if not found 709 */ 710 #ifndef SWIG /* Not available in Python */ 711 const struct fdt_property *fdt_get_property_namelen(const void *fdt, 712 int nodeoffset, 713 const char *name, 714 int namelen, int *lenp); 715 static inline struct fdt_property * 716 fdt_get_property_namelen_w(void *fdt, int nodeoffset, const char *name, 717 int namelen, int *lenp) 718 { 719 return (struct fdt_property *)(uintptr_t)fdt_get_property_namelen( 720 fdt, nodeoffset, name, namelen, lenp); 721 } 722 #endif 723 724 /** 725 * fdt_get_property - find a given property in a given node 726 * @fdt: pointer to the device tree blob 727 * @nodeoffset: offset of the node whose property to find 728 * @name: name of the property to find 729 * @lenp: pointer to an integer variable (will be overwritten) or NULL 730 * 731 * fdt_get_property() retrieves a pointer to the fdt_property 732 * structure within the device tree blob corresponding to the property 733 * named 'name' of the node at offset nodeoffset. If lenp is 734 * non-NULL, the length of the property value is also returned, in the 735 * integer pointed to by lenp. 736 * 737 * returns: 738 * pointer to the structure representing the property 739 * if lenp is non-NULL, *lenp contains the length of the property 740 * value (>=0) 741 * NULL, on error 742 * if lenp is non-NULL, *lenp contains an error code (<0): 743 * -FDT_ERR_NOTFOUND, node does not have named property 744 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE 745 * tag 746 * -FDT_ERR_BADMAGIC, 747 * -FDT_ERR_BADVERSION, 748 * -FDT_ERR_BADSTATE, 749 * -FDT_ERR_BADSTRUCTURE, 750 * -FDT_ERR_TRUNCATED, standard meanings 751 */ 752 const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, 753 const char *name, int *lenp); 754 static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, 755 const char *name, 756 int *lenp) 757 { 758 return (struct fdt_property *)(uintptr_t) 759 fdt_get_property(fdt, nodeoffset, name, lenp); 760 } 761 762 /** 763 * fdt_getprop_by_offset - retrieve the value of a property at a given offset 764 * @fdt: pointer to the device tree blob 765 * @offset: offset of the property to read 766 * @namep: pointer to a string variable (will be overwritten) or NULL 767 * @lenp: pointer to an integer variable (will be overwritten) or NULL 768 * 769 * fdt_getprop_by_offset() retrieves a pointer to the value of the 770 * property at structure block offset 'offset' (this will be a pointer 771 * to within the device blob itself, not a copy of the value). If 772 * lenp is non-NULL, the length of the property value is also 773 * returned, in the integer pointed to by lenp. If namep is non-NULL, 774 * the property's name will also be returned in the char * pointed to 775 * by namep (this will be a pointer to within the device tree's string 776 * block, not a new copy of the name). 777 * 778 * returns: 779 * pointer to the property's value 780 * if lenp is non-NULL, *lenp contains the length of the property 781 * value (>=0) 782 * if namep is non-NULL *namep contains a pointer to the property 783 * name. 784 * NULL, on error 785 * if lenp is non-NULL, *lenp contains an error code (<0): 786 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag 787 * -FDT_ERR_BADMAGIC, 788 * -FDT_ERR_BADVERSION, 789 * -FDT_ERR_BADSTATE, 790 * -FDT_ERR_BADSTRUCTURE, 791 * -FDT_ERR_TRUNCATED, standard meanings 792 */ 793 #ifndef SWIG /* This function is not useful in Python */ 794 const void *fdt_getprop_by_offset(const void *fdt, int offset, 795 const char **namep, int *lenp); 796 #endif 797 798 /** 799 * fdt_getprop_namelen - get property value based on substring 800 * @fdt: pointer to the device tree blob 801 * @nodeoffset: offset of the node whose property to find 802 * @name: name of the property to find 803 * @namelen: number of characters of name to consider 804 * @lenp: pointer to an integer variable (will be overwritten) or NULL 805 * 806 * Identical to fdt_getprop(), but only examine the first namelen 807 * characters of name for matching the property name. 808 * 809 * Return: pointer to the property's value or NULL on error 810 */ 811 #ifndef SWIG /* Not available in Python */ 812 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, 813 const char *name, int namelen, int *lenp); 814 static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, 815 const char *name, int namelen, 816 int *lenp) 817 { 818 return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, 819 namelen, lenp); 820 } 821 #endif 822 823 /** 824 * fdt_getprop - retrieve the value of a given property 825 * @fdt: pointer to the device tree blob 826 * @nodeoffset: offset of the node whose property to find 827 * @name: name of the property to find 828 * @lenp: pointer to an integer variable (will be overwritten) or NULL 829 * 830 * fdt_getprop() retrieves a pointer to the value of the property 831 * named @name of the node at offset @nodeoffset (this will be a 832 * pointer to within the device blob itself, not a copy of the value). 833 * If @lenp is non-NULL, the length of the property value is also 834 * returned, in the integer pointed to by @lenp. 835 * 836 * returns: 837 * pointer to the property's value 838 * if lenp is non-NULL, *lenp contains the length of the property 839 * value (>=0) 840 * NULL, on error 841 * if lenp is non-NULL, *lenp contains an error code (<0): 842 * -FDT_ERR_NOTFOUND, node does not have named property 843 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE 844 * tag 845 * -FDT_ERR_BADMAGIC, 846 * -FDT_ERR_BADVERSION, 847 * -FDT_ERR_BADSTATE, 848 * -FDT_ERR_BADSTRUCTURE, 849 * -FDT_ERR_TRUNCATED, standard meanings 850 */ 851 const void *fdt_getprop(const void *fdt, int nodeoffset, 852 const char *name, int *lenp); 853 static inline void *fdt_getprop_w(void *fdt, int nodeoffset, 854 const char *name, int *lenp) 855 { 856 return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); 857 } 858 859 /** 860 * fdt_get_phandle - retrieve the phandle of a given node 861 * @fdt: pointer to the device tree blob 862 * @nodeoffset: structure block offset of the node 863 * 864 * fdt_get_phandle() retrieves the phandle of the device tree node at 865 * structure block offset nodeoffset. 866 * 867 * returns: 868 * the phandle of the node at nodeoffset, on success (!= 0, != -1) 869 * 0, if the node has no phandle, or another error occurs 870 */ 871 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); 872 873 /** 874 * fdt_get_alias_namelen - get alias based on substring 875 * @fdt: pointer to the device tree blob 876 * @name: name of the alias to look up 877 * @namelen: number of characters of name to consider 878 * 879 * Identical to fdt_get_alias(), but only examine the first @namelen 880 * characters of @name for matching the alias name. 881 * 882 * Return: a pointer to the expansion of the alias named @name, if it exists, 883 * NULL otherwise 884 */ 885 #ifndef SWIG /* Not available in Python */ 886 const char *fdt_get_alias_namelen(const void *fdt, 887 const char *name, int namelen); 888 #endif 889 890 /** 891 * fdt_get_alias - retrieve the path referenced by a given alias 892 * @fdt: pointer to the device tree blob 893 * @name: name of the alias to look up 894 * 895 * fdt_get_alias() retrieves the value of a given alias. That is, the 896 * value of the property named @name in the node /aliases. 897 * 898 * returns: 899 * a pointer to the expansion of the alias named 'name', if it exists 900 * NULL, if the given alias or the /aliases node does not exist 901 */ 902 const char *fdt_get_alias(const void *fdt, const char *name); 903 904 /** 905 * fdt_get_symbol_namelen - get symbol based on substring 906 * @fdt: pointer to the device tree blob 907 * @name: name of the symbol to look up 908 * @namelen: number of characters of name to consider 909 * 910 * Identical to fdt_get_symbol(), but only examine the first @namelen 911 * characters of @name for matching the symbol name. 912 * 913 * Return: a pointer to the expansion of the symbol named @name, if it exists, 914 * NULL otherwise 915 */ 916 #ifndef SWIG /* Not available in Python */ 917 const char *fdt_get_symbol_namelen(const void *fdt, 918 const char *name, int namelen); 919 #endif 920 921 /** 922 * fdt_get_symbol - retrieve the path referenced by a given symbol 923 * @fdt: pointer to the device tree blob 924 * @name: name of the symbol to look up 925 * 926 * fdt_get_symbol() retrieves the value of a given symbol. That is, 927 * the value of the property named @name in the node 928 * /__symbols__. Such a node exists only for a device tree blob that 929 * has been compiled with the -@ dtc option. Each property corresponds 930 * to a label appearing in the device tree source, with the name of 931 * the property being the label and the value being the full path of 932 * the node it is attached to. 933 * 934 * returns: 935 * a pointer to the expansion of the symbol named 'name', if it exists 936 * NULL, if the given symbol or the /__symbols__ node does not exist 937 */ 938 const char *fdt_get_symbol(const void *fdt, const char *name); 939 940 /** 941 * fdt_get_path - determine the full path of a node 942 * @fdt: pointer to the device tree blob 943 * @nodeoffset: offset of the node whose path to find 944 * @buf: character buffer to contain the returned path (will be overwritten) 945 * @buflen: size of the character buffer at buf 946 * 947 * fdt_get_path() computes the full path of the node at offset 948 * nodeoffset, and records that path in the buffer at buf. 949 * 950 * NOTE: This function is expensive, as it must scan the device tree 951 * structure from the start to nodeoffset. 952 * 953 * returns: 954 * 0, on success 955 * buf contains the absolute path of the node at 956 * nodeoffset, as a NUL-terminated string. 957 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 958 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) 959 * characters and will not fit in the given buffer. 960 * -FDT_ERR_BADMAGIC, 961 * -FDT_ERR_BADVERSION, 962 * -FDT_ERR_BADSTATE, 963 * -FDT_ERR_BADSTRUCTURE, standard meanings 964 */ 965 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); 966 967 /** 968 * fdt_supernode_atdepth_offset - find a specific ancestor of a node 969 * @fdt: pointer to the device tree blob 970 * @nodeoffset: offset of the node whose parent to find 971 * @supernodedepth: depth of the ancestor to find 972 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL 973 * 974 * fdt_supernode_atdepth_offset() finds an ancestor of the given node 975 * at a specific depth from the root (where the root itself has depth 976 * 0, its immediate subnodes depth 1 and so forth). So 977 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); 978 * will always return 0, the offset of the root node. If the node at 979 * nodeoffset has depth D, then: 980 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); 981 * will return nodeoffset itself. 982 * 983 * NOTE: This function is expensive, as it must scan the device tree 984 * structure from the start to nodeoffset. 985 * 986 * returns: 987 * structure block offset of the node at node offset's ancestor 988 * of depth supernodedepth (>=0), on success 989 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 990 * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of 991 * nodeoffset 992 * -FDT_ERR_BADMAGIC, 993 * -FDT_ERR_BADVERSION, 994 * -FDT_ERR_BADSTATE, 995 * -FDT_ERR_BADSTRUCTURE, standard meanings 996 */ 997 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, 998 int supernodedepth, int *nodedepth); 999 1000 /** 1001 * fdt_node_depth - find the depth of a given node 1002 * @fdt: pointer to the device tree blob 1003 * @nodeoffset: offset of the node whose parent to find 1004 * 1005 * fdt_node_depth() finds the depth of a given node. The root node 1006 * has depth 0, its immediate subnodes depth 1 and so forth. 1007 * 1008 * NOTE: This function is expensive, as it must scan the device tree 1009 * structure from the start to nodeoffset. 1010 * 1011 * returns: 1012 * depth of the node at nodeoffset (>=0), on success 1013 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1014 * -FDT_ERR_BADMAGIC, 1015 * -FDT_ERR_BADVERSION, 1016 * -FDT_ERR_BADSTATE, 1017 * -FDT_ERR_BADSTRUCTURE, standard meanings 1018 */ 1019 int fdt_node_depth(const void *fdt, int nodeoffset); 1020 1021 /** 1022 * fdt_parent_offset - find the parent of a given node 1023 * @fdt: pointer to the device tree blob 1024 * @nodeoffset: offset of the node whose parent to find 1025 * 1026 * fdt_parent_offset() locates the parent node of a given node (that 1027 * is, it finds the offset of the node which contains the node at 1028 * nodeoffset as a subnode). 1029 * 1030 * NOTE: This function is expensive, as it must scan the device tree 1031 * structure from the start to nodeoffset, *twice*. 1032 * 1033 * returns: 1034 * structure block offset of the parent of the node at nodeoffset 1035 * (>=0), on success 1036 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1037 * -FDT_ERR_BADMAGIC, 1038 * -FDT_ERR_BADVERSION, 1039 * -FDT_ERR_BADSTATE, 1040 * -FDT_ERR_BADSTRUCTURE, standard meanings 1041 */ 1042 int fdt_parent_offset(const void *fdt, int nodeoffset); 1043 1044 /** 1045 * fdt_node_offset_by_prop_value - find nodes with a given property value 1046 * @fdt: pointer to the device tree blob 1047 * @startoffset: only find nodes after this offset 1048 * @propname: property name to check 1049 * @propval: property value to search for 1050 * @proplen: length of the value in propval 1051 * 1052 * fdt_node_offset_by_prop_value() returns the offset of the first 1053 * node after startoffset, which has a property named propname whose 1054 * value is of length proplen and has value equal to propval; or if 1055 * startoffset is -1, the very first such node in the tree. 1056 * 1057 * To iterate through all nodes matching the criterion, the following 1058 * idiom can be used: 1059 * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, 1060 * propval, proplen); 1061 * while (offset != -FDT_ERR_NOTFOUND) { 1062 * // other code here 1063 * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, 1064 * propval, proplen); 1065 * } 1066 * 1067 * Note the -1 in the first call to the function, if 0 is used here 1068 * instead, the function will never locate the root node, even if it 1069 * matches the criterion. 1070 * 1071 * returns: 1072 * structure block offset of the located node (>= 0, >startoffset), 1073 * on success 1074 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 1075 * tree after startoffset 1076 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1077 * -FDT_ERR_BADMAGIC, 1078 * -FDT_ERR_BADVERSION, 1079 * -FDT_ERR_BADSTATE, 1080 * -FDT_ERR_BADSTRUCTURE, standard meanings 1081 */ 1082 int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, 1083 const char *propname, 1084 const void *propval, int proplen); 1085 1086 /** 1087 * fdt_node_offset_by_phandle - find the node with a given phandle 1088 * @fdt: pointer to the device tree blob 1089 * @phandle: phandle value 1090 * 1091 * fdt_node_offset_by_phandle() returns the offset of the node 1092 * which has the given phandle value. If there is more than one node 1093 * in the tree with the given phandle (an invalid tree), results are 1094 * undefined. 1095 * 1096 * returns: 1097 * structure block offset of the located node (>= 0), on success 1098 * -FDT_ERR_NOTFOUND, no node with that phandle exists 1099 * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) 1100 * -FDT_ERR_BADMAGIC, 1101 * -FDT_ERR_BADVERSION, 1102 * -FDT_ERR_BADSTATE, 1103 * -FDT_ERR_BADSTRUCTURE, standard meanings 1104 */ 1105 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); 1106 1107 /** 1108 * fdt_node_check_compatible - check a node's compatible property 1109 * @fdt: pointer to the device tree blob 1110 * @nodeoffset: offset of a tree node 1111 * @compatible: string to match against 1112 * 1113 * fdt_node_check_compatible() returns 0 if the given node contains a 1114 * @compatible property with the given string as one of its elements, 1115 * it returns non-zero otherwise, or on error. 1116 * 1117 * returns: 1118 * 0, if the node has a 'compatible' property listing the given string 1119 * 1, if the node has a 'compatible' property, but it does not list 1120 * the given string 1121 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property 1122 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag 1123 * -FDT_ERR_BADMAGIC, 1124 * -FDT_ERR_BADVERSION, 1125 * -FDT_ERR_BADSTATE, 1126 * -FDT_ERR_BADSTRUCTURE, standard meanings 1127 */ 1128 int fdt_node_check_compatible(const void *fdt, int nodeoffset, 1129 const char *compatible); 1130 1131 /** 1132 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value 1133 * @fdt: pointer to the device tree blob 1134 * @startoffset: only find nodes after this offset 1135 * @compatible: 'compatible' string to match against 1136 * 1137 * fdt_node_offset_by_compatible() returns the offset of the first 1138 * node after startoffset, which has a 'compatible' property which 1139 * lists the given compatible string; or if startoffset is -1, the 1140 * very first such node in the tree. 1141 * 1142 * To iterate through all nodes matching the criterion, the following 1143 * idiom can be used: 1144 * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); 1145 * while (offset != -FDT_ERR_NOTFOUND) { 1146 * // other code here 1147 * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); 1148 * } 1149 * 1150 * Note the -1 in the first call to the function, if 0 is used here 1151 * instead, the function will never locate the root node, even if it 1152 * matches the criterion. 1153 * 1154 * returns: 1155 * structure block offset of the located node (>= 0, >startoffset), 1156 * on success 1157 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 1158 * tree after startoffset 1159 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1160 * -FDT_ERR_BADMAGIC, 1161 * -FDT_ERR_BADVERSION, 1162 * -FDT_ERR_BADSTATE, 1163 * -FDT_ERR_BADSTRUCTURE, standard meanings 1164 */ 1165 int fdt_node_offset_by_compatible(const void *fdt, int startoffset, 1166 const char *compatible); 1167 1168 /** 1169 * fdt_stringlist_contains - check a string list property for a string 1170 * @strlist: Property containing a list of strings to check 1171 * @listlen: Length of property 1172 * @str: String to search for 1173 * 1174 * This is a utility function provided for convenience. The list contains 1175 * one or more strings, each terminated by \0, as is found in a device tree 1176 * "compatible" property. 1177 * 1178 * Return: 1 if the string is found in the list, 0 not found, or invalid list 1179 */ 1180 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); 1181 1182 /** 1183 * fdt_stringlist_count - count the number of strings in a string list 1184 * @fdt: pointer to the device tree blob 1185 * @nodeoffset: offset of a tree node 1186 * @property: name of the property containing the string list 1187 * 1188 * Return: 1189 * the number of strings in the given property 1190 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1191 * -FDT_ERR_NOTFOUND if the property does not exist 1192 */ 1193 int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); 1194 1195 /** 1196 * fdt_stringlist_search - find a string in a string list and return its index 1197 * @fdt: pointer to the device tree blob 1198 * @nodeoffset: offset of a tree node 1199 * @property: name of the property containing the string list 1200 * @string: string to look up in the string list 1201 * 1202 * Note that it is possible for this function to succeed on property values 1203 * that are not NUL-terminated. That's because the function will stop after 1204 * finding the first occurrence of @string. This can for example happen with 1205 * small-valued cell properties, such as #address-cells, when searching for 1206 * the empty string. 1207 * 1208 * return: 1209 * the index of the string in the list of strings 1210 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1211 * -FDT_ERR_NOTFOUND if the property does not exist or does not contain 1212 * the given string 1213 */ 1214 int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, 1215 const char *string); 1216 1217 /** 1218 * fdt_stringlist_get() - obtain the string at a given index in a string list 1219 * @fdt: pointer to the device tree blob 1220 * @nodeoffset: offset of a tree node 1221 * @property: name of the property containing the string list 1222 * @index: index of the string to return 1223 * @lenp: return location for the string length or an error code on failure 1224 * 1225 * Note that this will successfully extract strings from properties with 1226 * non-NUL-terminated values. For example on small-valued cell properties 1227 * this function will return the empty string. 1228 * 1229 * If non-NULL, the length of the string (on success) or a negative error-code 1230 * (on failure) will be stored in the integer pointer to by lenp. 1231 * 1232 * Return: 1233 * A pointer to the string at the given index in the string list or NULL on 1234 * failure. On success the length of the string will be stored in the memory 1235 * location pointed to by the lenp parameter, if non-NULL. On failure one of 1236 * the following negative error codes will be returned in the lenp parameter 1237 * (if non-NULL): 1238 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1239 * -FDT_ERR_NOTFOUND if the property does not exist 1240 */ 1241 const char *fdt_stringlist_get(const void *fdt, int nodeoffset, 1242 const char *property, int index, 1243 int *lenp); 1244 1245 /**********************************************************************/ 1246 /* Read-only functions (addressing related) */ 1247 /**********************************************************************/ 1248 1249 /** 1250 * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells 1251 * 1252 * This is the maximum value for #address-cells, #size-cells and 1253 * similar properties that will be processed by libfdt. IEE1275 1254 * requires that OF implementations handle values up to 4. 1255 * Implementations may support larger values, but in practice higher 1256 * values aren't used. 1257 */ 1258 #define FDT_MAX_NCELLS 4 1259 1260 /** 1261 * fdt_address_cells - retrieve address size for a bus represented in the tree 1262 * @fdt: pointer to the device tree blob 1263 * @nodeoffset: offset of the node to find the address size for 1264 * 1265 * When the node has a valid #address-cells property, returns its value. 1266 * 1267 * returns: 1268 * 0 <= n < FDT_MAX_NCELLS, on success 1269 * 2, if the node has no #address-cells property 1270 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1271 * #address-cells property 1272 * -FDT_ERR_BADMAGIC, 1273 * -FDT_ERR_BADVERSION, 1274 * -FDT_ERR_BADSTATE, 1275 * -FDT_ERR_BADSTRUCTURE, 1276 * -FDT_ERR_TRUNCATED, standard meanings 1277 */ 1278 int fdt_address_cells(const void *fdt, int nodeoffset); 1279 1280 /** 1281 * fdt_size_cells - retrieve address range size for a bus represented in the 1282 * tree 1283 * @fdt: pointer to the device tree blob 1284 * @nodeoffset: offset of the node to find the address range size for 1285 * 1286 * When the node has a valid #size-cells property, returns its value. 1287 * 1288 * returns: 1289 * 0 <= n < FDT_MAX_NCELLS, on success 1290 * 1, if the node has no #size-cells property 1291 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1292 * #size-cells property 1293 * -FDT_ERR_BADMAGIC, 1294 * -FDT_ERR_BADVERSION, 1295 * -FDT_ERR_BADSTATE, 1296 * -FDT_ERR_BADSTRUCTURE, 1297 * -FDT_ERR_TRUNCATED, standard meanings 1298 */ 1299 int fdt_size_cells(const void *fdt, int nodeoffset); 1300 1301 1302 /**********************************************************************/ 1303 /* Write-in-place functions */ 1304 /**********************************************************************/ 1305 1306 /** 1307 * fdt_setprop_inplace_namelen_partial - change a property's value, 1308 * but not its size 1309 * @fdt: pointer to the device tree blob 1310 * @nodeoffset: offset of the node whose property to change 1311 * @name: name of the property to change 1312 * @namelen: number of characters of name to consider 1313 * @idx: index of the property to change in the array 1314 * @val: pointer to data to replace the property value with 1315 * @len: length of the property value 1316 * 1317 * Identical to fdt_setprop_inplace(), but modifies the given property 1318 * starting from the given index, and using only the first characters 1319 * of the name. It is useful when you want to manipulate only one value of 1320 * an array and you have a string that doesn't end with \0. 1321 * 1322 * Return: 0 on success, negative libfdt error value otherwise 1323 */ 1324 #ifndef SWIG /* Not available in Python */ 1325 int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, 1326 const char *name, int namelen, 1327 uint32_t idx, const void *val, 1328 int len); 1329 #endif 1330 1331 /** 1332 * fdt_setprop_inplace - change a property's value, but not its size 1333 * @fdt: pointer to the device tree blob 1334 * @nodeoffset: offset of the node whose property to change 1335 * @name: name of the property to change 1336 * @val: pointer to data to replace the property value with 1337 * @len: length of the property value 1338 * 1339 * fdt_setprop_inplace() replaces the value of a given property with 1340 * the data in val, of length len. This function cannot change the 1341 * size of a property, and so will only work if len is equal to the 1342 * current length of the property. 1343 * 1344 * This function will alter only the bytes in the blob which contain 1345 * the given property value, and will not alter or move any other part 1346 * of the tree. 1347 * 1348 * returns: 1349 * 0, on success 1350 * -FDT_ERR_NOSPACE, if len is not equal to the property's current length 1351 * -FDT_ERR_NOTFOUND, node does not have the named property 1352 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1353 * -FDT_ERR_BADMAGIC, 1354 * -FDT_ERR_BADVERSION, 1355 * -FDT_ERR_BADSTATE, 1356 * -FDT_ERR_BADSTRUCTURE, 1357 * -FDT_ERR_TRUNCATED, standard meanings 1358 */ 1359 #ifndef SWIG /* Not available in Python */ 1360 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, 1361 const void *val, int len); 1362 #endif 1363 1364 /** 1365 * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property 1366 * @fdt: pointer to the device tree blob 1367 * @nodeoffset: offset of the node whose property to change 1368 * @name: name of the property to change 1369 * @val: 32-bit integer value to replace the property with 1370 * 1371 * fdt_setprop_inplace_u32() replaces the value of a given property 1372 * with the 32-bit integer value in val, converting val to big-endian 1373 * if necessary. This function cannot change the size of a property, 1374 * and so will only work if the property already exists and has length 1375 * 4. 1376 * 1377 * This function will alter only the bytes in the blob which contain 1378 * the given property value, and will not alter or move any other part 1379 * of the tree. 1380 * 1381 * returns: 1382 * 0, on success 1383 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 1384 * -FDT_ERR_NOTFOUND, node does not have the named property 1385 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1386 * -FDT_ERR_BADMAGIC, 1387 * -FDT_ERR_BADVERSION, 1388 * -FDT_ERR_BADSTATE, 1389 * -FDT_ERR_BADSTRUCTURE, 1390 * -FDT_ERR_TRUNCATED, standard meanings 1391 */ 1392 static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, 1393 const char *name, uint32_t val) 1394 { 1395 fdt32_t tmp = cpu_to_fdt32(val); 1396 return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1397 } 1398 1399 /** 1400 * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property 1401 * @fdt: pointer to the device tree blob 1402 * @nodeoffset: offset of the node whose property to change 1403 * @name: name of the property to change 1404 * @val: 64-bit integer value to replace the property with 1405 * 1406 * fdt_setprop_inplace_u64() replaces the value of a given property 1407 * with the 64-bit integer value in val, converting val to big-endian 1408 * if necessary. This function cannot change the size of a property, 1409 * and so will only work if the property already exists and has length 1410 * 8. 1411 * 1412 * This function will alter only the bytes in the blob which contain 1413 * the given property value, and will not alter or move any other part 1414 * of the tree. 1415 * 1416 * returns: 1417 * 0, on success 1418 * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 1419 * -FDT_ERR_NOTFOUND, node does not have the named property 1420 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1421 * -FDT_ERR_BADMAGIC, 1422 * -FDT_ERR_BADVERSION, 1423 * -FDT_ERR_BADSTATE, 1424 * -FDT_ERR_BADSTRUCTURE, 1425 * -FDT_ERR_TRUNCATED, standard meanings 1426 */ 1427 static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, 1428 const char *name, uint64_t val) 1429 { 1430 fdt64_t tmp = cpu_to_fdt64(val); 1431 return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1432 } 1433 1434 /** 1435 * fdt_setprop_inplace_cell - change the value of a single-cell property 1436 * @fdt: pointer to the device tree blob 1437 * @nodeoffset: offset of the node containing the property 1438 * @name: name of the property to change the value of 1439 * @val: new value of the 32-bit cell 1440 * 1441 * This is an alternative name for fdt_setprop_inplace_u32() 1442 * Return: 0 on success, negative libfdt error number otherwise. 1443 */ 1444 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, 1445 const char *name, uint32_t val) 1446 { 1447 return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); 1448 } 1449 1450 /** 1451 * fdt_nop_property - replace a property with nop tags 1452 * @fdt: pointer to the device tree blob 1453 * @nodeoffset: offset of the node whose property to nop 1454 * @name: name of the property to nop 1455 * 1456 * fdt_nop_property() will replace a given property's representation 1457 * in the blob with FDT_NOP tags, effectively removing it from the 1458 * tree. 1459 * 1460 * This function will alter only the bytes in the blob which contain 1461 * the property, and will not alter or move any other part of the 1462 * tree. 1463 * 1464 * returns: 1465 * 0, on success 1466 * -FDT_ERR_NOTFOUND, node does not have the named property 1467 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1468 * -FDT_ERR_BADMAGIC, 1469 * -FDT_ERR_BADVERSION, 1470 * -FDT_ERR_BADSTATE, 1471 * -FDT_ERR_BADSTRUCTURE, 1472 * -FDT_ERR_TRUNCATED, standard meanings 1473 */ 1474 int fdt_nop_property(void *fdt, int nodeoffset, const char *name); 1475 1476 /** 1477 * fdt_nop_node - replace a node (subtree) with nop tags 1478 * @fdt: pointer to the device tree blob 1479 * @nodeoffset: offset of the node to nop 1480 * 1481 * fdt_nop_node() will replace a given node's representation in the 1482 * blob, including all its subnodes, if any, with FDT_NOP tags, 1483 * effectively removing it from the tree. 1484 * 1485 * This function will alter only the bytes in the blob which contain 1486 * the node and its properties and subnodes, and will not alter or 1487 * move any other part of the tree. 1488 * 1489 * returns: 1490 * 0, on success 1491 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1492 * -FDT_ERR_BADMAGIC, 1493 * -FDT_ERR_BADVERSION, 1494 * -FDT_ERR_BADSTATE, 1495 * -FDT_ERR_BADSTRUCTURE, 1496 * -FDT_ERR_TRUNCATED, standard meanings 1497 */ 1498 int fdt_nop_node(void *fdt, int nodeoffset); 1499 1500 /**********************************************************************/ 1501 /* Sequential write functions */ 1502 /**********************************************************************/ 1503 1504 /* fdt_create_with_flags flags */ 1505 #define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 1506 /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property 1507 * names in the fdt. This can result in faster creation times, but 1508 * a larger fdt. */ 1509 1510 #define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) 1511 1512 /** 1513 * fdt_create_with_flags - begin creation of a new fdt 1514 * @buf: pointer to memory allocated where fdt will be created 1515 * @bufsize: size of the memory space at fdt 1516 * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. 1517 * 1518 * fdt_create_with_flags() begins the process of creating a new fdt with 1519 * the sequential write interface. 1520 * 1521 * fdt creation process must end with fdt_finish() to produce a valid fdt. 1522 * 1523 * returns: 1524 * 0, on success 1525 * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt 1526 * -FDT_ERR_BADFLAGS, flags is not valid 1527 */ 1528 int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); 1529 1530 /** 1531 * fdt_create - begin creation of a new fdt 1532 * @buf: pointer to memory allocated where fdt will be created 1533 * @bufsize: size of the memory space at fdt 1534 * 1535 * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. 1536 * 1537 * returns: 1538 * 0, on success 1539 * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt 1540 */ 1541 int fdt_create(void *buf, int bufsize); 1542 1543 int fdt_resize(void *fdt, void *buf, int bufsize); 1544 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); 1545 int fdt_finish_reservemap(void *fdt); 1546 int fdt_begin_node(void *fdt, const char *name); 1547 int fdt_property(void *fdt, const char *name, const void *val, int len); 1548 static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) 1549 { 1550 fdt32_t tmp = cpu_to_fdt32(val); 1551 return fdt_property(fdt, name, &tmp, sizeof(tmp)); 1552 } 1553 static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) 1554 { 1555 fdt64_t tmp = cpu_to_fdt64(val); 1556 return fdt_property(fdt, name, &tmp, sizeof(tmp)); 1557 } 1558 1559 #ifndef SWIG /* Not available in Python */ 1560 static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) 1561 { 1562 return fdt_property_u32(fdt, name, val); 1563 } 1564 #endif 1565 1566 /** 1567 * fdt_property_placeholder - add a new property and return a ptr to its value 1568 * 1569 * @fdt: pointer to the device tree blob 1570 * @name: name of property to add 1571 * @len: length of property value in bytes 1572 * @valp: returns a pointer to where the value should be placed 1573 * 1574 * returns: 1575 * 0, on success 1576 * -FDT_ERR_BADMAGIC, 1577 * -FDT_ERR_NOSPACE, standard meanings 1578 */ 1579 int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); 1580 1581 #define fdt_property_string(fdt, name, str) \ 1582 fdt_property(fdt, name, str, strlen(str)+1) 1583 int fdt_end_node(void *fdt); 1584 int fdt_finish(void *fdt); 1585 1586 /**********************************************************************/ 1587 /* Read-write functions */ 1588 /**********************************************************************/ 1589 1590 int fdt_create_empty_tree(void *buf, int bufsize); 1591 int fdt_open_into(const void *fdt, void *buf, int bufsize); 1592 int fdt_pack(void *fdt); 1593 1594 /** 1595 * fdt_add_mem_rsv - add one memory reserve map entry 1596 * @fdt: pointer to the device tree blob 1597 * @address: 64-bit start address of the reserve map entry 1598 * @size: 64-bit size of the reserved region 1599 * 1600 * Adds a reserve map entry to the given blob reserving a region at 1601 * address address of length size. 1602 * 1603 * This function will insert data into the reserve map and will 1604 * therefore change the indexes of some entries in the table. 1605 * 1606 * returns: 1607 * 0, on success 1608 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1609 * contain the new reservation entry 1610 * -FDT_ERR_BADMAGIC, 1611 * -FDT_ERR_BADVERSION, 1612 * -FDT_ERR_BADSTATE, 1613 * -FDT_ERR_BADSTRUCTURE, 1614 * -FDT_ERR_BADLAYOUT, 1615 * -FDT_ERR_TRUNCATED, standard meanings 1616 */ 1617 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); 1618 1619 /** 1620 * fdt_del_mem_rsv - remove a memory reserve map entry 1621 * @fdt: pointer to the device tree blob 1622 * @n: entry to remove 1623 * 1624 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from 1625 * the blob. 1626 * 1627 * This function will delete data from the reservation table and will 1628 * therefore change the indexes of some entries in the table. 1629 * 1630 * returns: 1631 * 0, on success 1632 * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there 1633 * are less than n+1 reserve map entries) 1634 * -FDT_ERR_BADMAGIC, 1635 * -FDT_ERR_BADVERSION, 1636 * -FDT_ERR_BADSTATE, 1637 * -FDT_ERR_BADSTRUCTURE, 1638 * -FDT_ERR_BADLAYOUT, 1639 * -FDT_ERR_TRUNCATED, standard meanings 1640 */ 1641 int fdt_del_mem_rsv(void *fdt, int n); 1642 1643 /** 1644 * fdt_set_name - change the name of a given node 1645 * @fdt: pointer to the device tree blob 1646 * @nodeoffset: structure block offset of a node 1647 * @name: name to give the node 1648 * 1649 * fdt_set_name() replaces the name (including unit address, if any) 1650 * of the given node with the given string. NOTE: this function can't 1651 * efficiently check if the new name is unique amongst the given 1652 * node's siblings; results are undefined if this function is invoked 1653 * with a name equal to one of the given node's siblings. 1654 * 1655 * This function may insert or delete data from the blob, and will 1656 * therefore change the offsets of some existing nodes. 1657 * 1658 * returns: 1659 * 0, on success 1660 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob 1661 * to contain the new name 1662 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1663 * -FDT_ERR_BADMAGIC, 1664 * -FDT_ERR_BADVERSION, 1665 * -FDT_ERR_BADSTATE, standard meanings 1666 */ 1667 int fdt_set_name(void *fdt, int nodeoffset, const char *name); 1668 1669 /** 1670 * fdt_setprop_namelen - create or change a property 1671 * @fdt: pointer to the device tree blob 1672 * @nodeoffset: offset of the node whose property to change 1673 * @name: name of the property to change 1674 * @namelen: length of the name 1675 * @val: pointer to data to set the property value to 1676 * @len: length of the property value 1677 * 1678 * fdt_setprop_namelen() sets the value of the named property in the given 1679 * node to the given value and length, creating the property if it 1680 * does not already exist. 1681 * 1682 * This function may insert or delete data from the blob, and will 1683 * therefore change the offsets of some existing nodes. 1684 * 1685 * returns: 1686 * 0, on success 1687 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1688 * contain the new property value 1689 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1690 * -FDT_ERR_BADLAYOUT, 1691 * -FDT_ERR_BADMAGIC, 1692 * -FDT_ERR_BADVERSION, 1693 * -FDT_ERR_BADSTATE, 1694 * -FDT_ERR_BADSTRUCTURE, 1695 * -FDT_ERR_BADLAYOUT, 1696 * -FDT_ERR_TRUNCATED, standard meanings 1697 */ 1698 int fdt_setprop_namelen(void *fdt, int nodeoffset, const char *name, 1699 int namelen, const void *val, int len); 1700 1701 /** 1702 * fdt_setprop - create or change a property 1703 * @fdt: pointer to the device tree blob 1704 * @nodeoffset: offset of the node whose property to change 1705 * @name: name of the property to change 1706 * @val: pointer to data to set the property value to 1707 * @len: length of the property value 1708 * 1709 * fdt_setprop() sets the value of the named property in the given 1710 * node to the given value and length, creating the property if it 1711 * does not already exist. 1712 * 1713 * This function may insert or delete data from the blob, and will 1714 * therefore change the offsets of some existing nodes. 1715 * 1716 * returns: 1717 * 0, on success 1718 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1719 * contain the new property value 1720 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1721 * -FDT_ERR_BADLAYOUT, 1722 * -FDT_ERR_BADMAGIC, 1723 * -FDT_ERR_BADVERSION, 1724 * -FDT_ERR_BADSTATE, 1725 * -FDT_ERR_BADSTRUCTURE, 1726 * -FDT_ERR_BADLAYOUT, 1727 * -FDT_ERR_TRUNCATED, standard meanings 1728 */ 1729 static inline int fdt_setprop(void *fdt, int nodeoffset, const char *name, 1730 const void *val, int len) 1731 { 1732 return fdt_setprop_namelen(fdt, nodeoffset, name, strlen(name), val, 1733 len); 1734 } 1735 1736 /** 1737 * fdt_setprop_placeholder_namelen - allocate space for a property 1738 * @fdt: pointer to the device tree blob 1739 * @nodeoffset: offset of the node whose property to change 1740 * @name: name of the property to change 1741 * @namelen: length of the name 1742 * @len: length of the property value 1743 * @prop_data: return pointer to property data 1744 * 1745 * fdt_setprop_placeholder_namelen() allocates the named property in the given node. 1746 * If the property exists it is resized. In either case a pointer to the 1747 * property data is returned. 1748 * 1749 * This function may insert or delete data from the blob, and will 1750 * therefore change the offsets of some existing nodes. 1751 * 1752 * returns: 1753 * 0, on success 1754 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1755 * contain the new property value 1756 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1757 * -FDT_ERR_BADLAYOUT, 1758 * -FDT_ERR_BADMAGIC, 1759 * -FDT_ERR_BADVERSION, 1760 * -FDT_ERR_BADSTATE, 1761 * -FDT_ERR_BADSTRUCTURE, 1762 * -FDT_ERR_BADLAYOUT, 1763 * -FDT_ERR_TRUNCATED, standard meanings 1764 */ 1765 int fdt_setprop_placeholder_namelen(void *fdt, int nodeoffset, const char *name, 1766 int namelen, int len, void **prop_data); 1767 1768 /** 1769 * fdt_setprop_placeholder - allocate space for a property 1770 * @fdt: pointer to the device tree blob 1771 * @nodeoffset: offset of the node whose property to change 1772 * @name: name of the property to change 1773 * @len: length of the property value 1774 * @prop_data: return pointer to property data 1775 * 1776 * fdt_setprop_placeholder() allocates the named property in the given node. 1777 * If the property exists it is resized. In either case a pointer to the 1778 * property data is returned. 1779 * 1780 * This function may insert or delete data from the blob, and will 1781 * therefore change the offsets of some existing nodes. 1782 * 1783 * returns: 1784 * 0, on success 1785 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1786 * contain the new property value 1787 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1788 * -FDT_ERR_BADLAYOUT, 1789 * -FDT_ERR_BADMAGIC, 1790 * -FDT_ERR_BADVERSION, 1791 * -FDT_ERR_BADSTATE, 1792 * -FDT_ERR_BADSTRUCTURE, 1793 * -FDT_ERR_BADLAYOUT, 1794 * -FDT_ERR_TRUNCATED, standard meanings 1795 */ 1796 static inline int fdt_setprop_placeholder(void *fdt, int nodeoffset, 1797 const char *name, int len, 1798 void **prop_data) 1799 { 1800 return fdt_setprop_placeholder_namelen(fdt, nodeoffset, name, 1801 strlen(name), len, prop_data); 1802 } 1803 1804 /** 1805 * fdt_setprop_u32 - set a property to a 32-bit integer 1806 * @fdt: pointer to the device tree blob 1807 * @nodeoffset: offset of the node whose property to change 1808 * @name: name of the property to change 1809 * @val: 32-bit integer value for the property (native endian) 1810 * 1811 * fdt_setprop_u32() sets the value of the named property in the given 1812 * node to the given 32-bit integer value (converting to big-endian if 1813 * necessary), or creates a new property with that value if it does 1814 * not already exist. 1815 * 1816 * This function may insert or delete data from the blob, and will 1817 * therefore change the offsets of some existing nodes. 1818 * 1819 * returns: 1820 * 0, on success 1821 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1822 * contain the new property value 1823 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1824 * -FDT_ERR_BADLAYOUT, 1825 * -FDT_ERR_BADMAGIC, 1826 * -FDT_ERR_BADVERSION, 1827 * -FDT_ERR_BADSTATE, 1828 * -FDT_ERR_BADSTRUCTURE, 1829 * -FDT_ERR_BADLAYOUT, 1830 * -FDT_ERR_TRUNCATED, standard meanings 1831 */ 1832 static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, 1833 uint32_t val) 1834 { 1835 fdt32_t tmp = cpu_to_fdt32(val); 1836 return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1837 } 1838 1839 /** 1840 * fdt_setprop_u64 - set a property to a 64-bit integer 1841 * @fdt: pointer to the device tree blob 1842 * @nodeoffset: offset of the node whose property to change 1843 * @name: name of the property to change 1844 * @val: 64-bit integer value for the property (native endian) 1845 * 1846 * fdt_setprop_u64() sets the value of the named property in the given 1847 * node to the given 64-bit integer value (converting to big-endian if 1848 * necessary), or creates a new property with that value if it does 1849 * not already exist. 1850 * 1851 * This function may insert or delete data from the blob, and will 1852 * therefore change the offsets of some existing nodes. 1853 * 1854 * returns: 1855 * 0, on success 1856 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1857 * contain the new property value 1858 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1859 * -FDT_ERR_BADLAYOUT, 1860 * -FDT_ERR_BADMAGIC, 1861 * -FDT_ERR_BADVERSION, 1862 * -FDT_ERR_BADSTATE, 1863 * -FDT_ERR_BADSTRUCTURE, 1864 * -FDT_ERR_BADLAYOUT, 1865 * -FDT_ERR_TRUNCATED, standard meanings 1866 */ 1867 static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, 1868 uint64_t val) 1869 { 1870 fdt64_t tmp = cpu_to_fdt64(val); 1871 return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1872 } 1873 1874 /** 1875 * fdt_setprop_cell - set a property to a single cell value 1876 * @fdt: pointer to the device tree blob 1877 * @nodeoffset: offset of the node whose property to change 1878 * @name: name of the property to change 1879 * @val: 32-bit integer value for the property (native endian) 1880 * 1881 * This is an alternative name for fdt_setprop_u32() 1882 * 1883 * Return: 0 on success, negative libfdt error value otherwise. 1884 */ 1885 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, 1886 uint32_t val) 1887 { 1888 return fdt_setprop_u32(fdt, nodeoffset, name, val); 1889 } 1890 1891 /** 1892 * fdt_setprop_string - set a property to a string value 1893 * @fdt: pointer to the device tree blob 1894 * @nodeoffset: offset of the node whose property to change 1895 * @name: name of the property to change 1896 * @str: string value for the property 1897 * 1898 * fdt_setprop_string() sets the value of the named property in the 1899 * given node to the given string value (using the length of the 1900 * string to determine the new length of the property), or creates a 1901 * new property with that value if it does not already exist. 1902 * 1903 * This function may insert or delete data from the blob, and will 1904 * therefore change the offsets of some existing nodes. 1905 * 1906 * returns: 1907 * 0, on success 1908 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1909 * contain the new property value 1910 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1911 * -FDT_ERR_BADLAYOUT, 1912 * -FDT_ERR_BADMAGIC, 1913 * -FDT_ERR_BADVERSION, 1914 * -FDT_ERR_BADSTATE, 1915 * -FDT_ERR_BADSTRUCTURE, 1916 * -FDT_ERR_BADLAYOUT, 1917 * -FDT_ERR_TRUNCATED, standard meanings 1918 */ 1919 #define fdt_setprop_string(fdt, nodeoffset, name, str) \ 1920 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 1921 1922 /** 1923 * fdt_setprop_namelen_string - set a property to a string value 1924 * @fdt: pointer to the device tree blob 1925 * @nodeoffset: offset of the node whose property to change 1926 * @name: name of the property to change 1927 * @namelen: number of characters of name to consider 1928 * @str: string value for the property 1929 * 1930 * fdt_setprop_namelen_string() sets the value of the named property in the 1931 * given node to the given string value (using the length of the 1932 * string to determine the new length of the property), or creates a 1933 * new property with that value if it does not already exist. 1934 * 1935 * This function may insert or delete data from the blob, and will 1936 * therefore change the offsets of some existing nodes. 1937 * 1938 * returns: 1939 * 0, on success 1940 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1941 * contain the new property value 1942 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1943 * -FDT_ERR_BADLAYOUT, 1944 * -FDT_ERR_BADMAGIC, 1945 * -FDT_ERR_BADVERSION, 1946 * -FDT_ERR_BADSTATE, 1947 * -FDT_ERR_BADSTRUCTURE, 1948 * -FDT_ERR_BADLAYOUT, 1949 * -FDT_ERR_TRUNCATED, standard meanings 1950 */ 1951 #define fdt_setprop_namelen_string(fdt, nodeoffset, name, namelen, str) \ 1952 fdt_setprop_namelen((fdt), (nodeoffset), (name), (namelen), (str), \ 1953 strlen(str) + 1) 1954 1955 /** 1956 * fdt_setprop_empty - set a property to an empty value 1957 * @fdt: pointer to the device tree blob 1958 * @nodeoffset: offset of the node whose property to change 1959 * @name: name of the property to change 1960 * 1961 * fdt_setprop_empty() sets the value of the named property in the 1962 * given node to an empty (zero length) value, or creates a new empty 1963 * property if it does not already exist. 1964 * 1965 * This function may insert or delete data from the blob, and will 1966 * therefore change the offsets of some existing nodes. 1967 * 1968 * returns: 1969 * 0, on success 1970 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1971 * contain the new property value 1972 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1973 * -FDT_ERR_BADLAYOUT, 1974 * -FDT_ERR_BADMAGIC, 1975 * -FDT_ERR_BADVERSION, 1976 * -FDT_ERR_BADSTATE, 1977 * -FDT_ERR_BADSTRUCTURE, 1978 * -FDT_ERR_BADLAYOUT, 1979 * -FDT_ERR_TRUNCATED, standard meanings 1980 */ 1981 #define fdt_setprop_empty(fdt, nodeoffset, name) \ 1982 fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) 1983 1984 /** 1985 * fdt_appendprop - append to or create a property 1986 * @fdt: pointer to the device tree blob 1987 * @nodeoffset: offset of the node whose property to change 1988 * @name: name of the property to append to 1989 * @val: pointer to data to append to the property value 1990 * @len: length of the data to append to the property value 1991 * 1992 * fdt_appendprop() appends the value to the named property in the 1993 * given node, creating the property if it does not already exist. 1994 * 1995 * This function may insert data into the blob, and will therefore 1996 * change the offsets of some existing nodes. 1997 * 1998 * returns: 1999 * 0, on success 2000 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2001 * contain the new property value 2002 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2003 * -FDT_ERR_BADLAYOUT, 2004 * -FDT_ERR_BADMAGIC, 2005 * -FDT_ERR_BADVERSION, 2006 * -FDT_ERR_BADSTATE, 2007 * -FDT_ERR_BADSTRUCTURE, 2008 * -FDT_ERR_BADLAYOUT, 2009 * -FDT_ERR_TRUNCATED, standard meanings 2010 */ 2011 int fdt_appendprop(void *fdt, int nodeoffset, const char *name, 2012 const void *val, int len); 2013 2014 /** 2015 * fdt_appendprop_u32 - append a 32-bit integer value to a property 2016 * @fdt: pointer to the device tree blob 2017 * @nodeoffset: offset of the node whose property to change 2018 * @name: name of the property to change 2019 * @val: 32-bit integer value to append to the property (native endian) 2020 * 2021 * fdt_appendprop_u32() appends the given 32-bit integer value 2022 * (converting to big-endian if necessary) to the value of the named 2023 * property in the given node, or creates a new property with that 2024 * value if it does not already exist. 2025 * 2026 * This function may insert data into the blob, and will therefore 2027 * change the offsets of some existing nodes. 2028 * 2029 * returns: 2030 * 0, on success 2031 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2032 * contain the new property value 2033 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2034 * -FDT_ERR_BADLAYOUT, 2035 * -FDT_ERR_BADMAGIC, 2036 * -FDT_ERR_BADVERSION, 2037 * -FDT_ERR_BADSTATE, 2038 * -FDT_ERR_BADSTRUCTURE, 2039 * -FDT_ERR_BADLAYOUT, 2040 * -FDT_ERR_TRUNCATED, standard meanings 2041 */ 2042 static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, 2043 const char *name, uint32_t val) 2044 { 2045 fdt32_t tmp = cpu_to_fdt32(val); 2046 return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 2047 } 2048 2049 /** 2050 * fdt_appendprop_u64 - append a 64-bit integer value to a property 2051 * @fdt: pointer to the device tree blob 2052 * @nodeoffset: offset of the node whose property to change 2053 * @name: name of the property to change 2054 * @val: 64-bit integer value to append to the property (native endian) 2055 * 2056 * fdt_appendprop_u64() appends the given 64-bit integer value 2057 * (converting to big-endian if necessary) to the value of the named 2058 * property in the given node, or creates a new property with that 2059 * value if it does not already exist. 2060 * 2061 * This function may insert data into the blob, and will therefore 2062 * change the offsets of some existing nodes. 2063 * 2064 * returns: 2065 * 0, on success 2066 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2067 * contain the new property value 2068 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2069 * -FDT_ERR_BADLAYOUT, 2070 * -FDT_ERR_BADMAGIC, 2071 * -FDT_ERR_BADVERSION, 2072 * -FDT_ERR_BADSTATE, 2073 * -FDT_ERR_BADSTRUCTURE, 2074 * -FDT_ERR_BADLAYOUT, 2075 * -FDT_ERR_TRUNCATED, standard meanings 2076 */ 2077 static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, 2078 const char *name, uint64_t val) 2079 { 2080 fdt64_t tmp = cpu_to_fdt64(val); 2081 return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 2082 } 2083 2084 /** 2085 * fdt_appendprop_cell - append a single cell value to a property 2086 * @fdt: pointer to the device tree blob 2087 * @nodeoffset: offset of the node whose property to change 2088 * @name: name of the property to change 2089 * @val: 32-bit integer value to append to the property (native endian) 2090 * 2091 * This is an alternative name for fdt_appendprop_u32() 2092 * 2093 * Return: 0 on success, negative libfdt error value otherwise. 2094 */ 2095 static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, 2096 const char *name, uint32_t val) 2097 { 2098 return fdt_appendprop_u32(fdt, nodeoffset, name, val); 2099 } 2100 2101 /** 2102 * fdt_appendprop_string - append a string to a property 2103 * @fdt: pointer to the device tree blob 2104 * @nodeoffset: offset of the node whose property to change 2105 * @name: name of the property to change 2106 * @str: string value to append to the property 2107 * 2108 * fdt_appendprop_string() appends the given string to the value of 2109 * the named property in the given node, or creates a new property 2110 * with that value if it does not already exist. 2111 * 2112 * This function may insert data into the blob, and will therefore 2113 * change the offsets of some existing nodes. 2114 * 2115 * returns: 2116 * 0, on success 2117 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2118 * contain the new property value 2119 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2120 * -FDT_ERR_BADLAYOUT, 2121 * -FDT_ERR_BADMAGIC, 2122 * -FDT_ERR_BADVERSION, 2123 * -FDT_ERR_BADSTATE, 2124 * -FDT_ERR_BADSTRUCTURE, 2125 * -FDT_ERR_BADLAYOUT, 2126 * -FDT_ERR_TRUNCATED, standard meanings 2127 */ 2128 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \ 2129 fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 2130 2131 /** 2132 * fdt_appendprop_addrrange - append a address range property 2133 * @fdt: pointer to the device tree blob 2134 * @parent: offset of the parent node 2135 * @nodeoffset: offset of the node to add a property at 2136 * @name: name of property 2137 * @addr: start address of a given range 2138 * @size: size of a given range 2139 * 2140 * fdt_appendprop_addrrange() appends an address range value (start 2141 * address and size) to the value of the named property in the given 2142 * node, or creates a new property with that value if it does not 2143 * already exist. 2144 * 2145 * Cell sizes are determined by parent's #address-cells and #size-cells. 2146 * 2147 * This function may insert data into the blob, and will therefore 2148 * change the offsets of some existing nodes. 2149 * 2150 * returns: 2151 * 0, on success 2152 * -FDT_ERR_BADLAYOUT, 2153 * -FDT_ERR_BADMAGIC, 2154 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 2155 * #address-cells property 2156 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2157 * -FDT_ERR_BADSTATE, 2158 * -FDT_ERR_BADSTRUCTURE, 2159 * -FDT_ERR_BADVERSION, 2160 * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size 2161 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2162 * contain a new property 2163 * -FDT_ERR_TRUNCATED, standard meanings 2164 */ 2165 int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, 2166 const char *name, uint64_t addr, uint64_t size); 2167 2168 /** 2169 * fdt_delprop - delete a property 2170 * @fdt: pointer to the device tree blob 2171 * @nodeoffset: offset of the node whose property to nop 2172 * @name: name of the property to nop 2173 * 2174 * fdt_delprop() will delete the given property. 2175 * 2176 * This function will delete data from the blob, and will therefore 2177 * change the offsets of some existing nodes. 2178 * 2179 * returns: 2180 * 0, on success 2181 * -FDT_ERR_NOTFOUND, node does not have the named property 2182 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2183 * -FDT_ERR_BADLAYOUT, 2184 * -FDT_ERR_BADMAGIC, 2185 * -FDT_ERR_BADVERSION, 2186 * -FDT_ERR_BADSTATE, 2187 * -FDT_ERR_BADSTRUCTURE, 2188 * -FDT_ERR_TRUNCATED, standard meanings 2189 */ 2190 int fdt_delprop(void *fdt, int nodeoffset, const char *name); 2191 2192 /** 2193 * fdt_add_subnode_namelen - creates a new node based on substring 2194 * @fdt: pointer to the device tree blob 2195 * @parentoffset: structure block offset of a node 2196 * @name: name of the subnode to create 2197 * @namelen: number of characters of name to consider 2198 * 2199 * Identical to fdt_add_subnode(), but use only the first @namelen 2200 * characters of @name as the name of the new node. This is useful for 2201 * creating subnodes based on a portion of a larger string, such as a 2202 * full path. 2203 * 2204 * Return: structure block offset of the created subnode (>=0), 2205 * negative libfdt error value otherwise 2206 */ 2207 #ifndef SWIG /* Not available in Python */ 2208 int fdt_add_subnode_namelen(void *fdt, int parentoffset, 2209 const char *name, int namelen); 2210 #endif 2211 2212 /** 2213 * fdt_add_subnode - creates a new node 2214 * @fdt: pointer to the device tree blob 2215 * @parentoffset: structure block offset of a node 2216 * @name: name of the subnode to locate 2217 * 2218 * fdt_add_subnode() creates a new node as a subnode of the node at 2219 * structure block offset parentoffset, with the given name (which 2220 * should include the unit address, if any). 2221 * 2222 * This function will insert data into the blob, and will therefore 2223 * change the offsets of some existing nodes. 2224 * 2225 * returns: 2226 * structure block offset of the created subnode (>=0), on success 2227 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist 2228 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE 2229 * tag 2230 * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of 2231 * the given name 2232 * -FDT_ERR_NOSPACE, if there is insufficient free space in the 2233 * blob to contain the new node 2234 * -FDT_ERR_NOSPACE 2235 * -FDT_ERR_BADLAYOUT 2236 * -FDT_ERR_BADMAGIC, 2237 * -FDT_ERR_BADVERSION, 2238 * -FDT_ERR_BADSTATE, 2239 * -FDT_ERR_BADSTRUCTURE, 2240 * -FDT_ERR_TRUNCATED, standard meanings. 2241 */ 2242 int fdt_add_subnode(void *fdt, int parentoffset, const char *name); 2243 2244 /** 2245 * fdt_del_node - delete a node (subtree) 2246 * @fdt: pointer to the device tree blob 2247 * @nodeoffset: offset of the node to nop 2248 * 2249 * fdt_del_node() will remove the given node, including all its 2250 * subnodes if any, from the blob. 2251 * 2252 * This function will delete data from the blob, and will therefore 2253 * change the offsets of some existing nodes. 2254 * 2255 * returns: 2256 * 0, on success 2257 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2258 * -FDT_ERR_BADLAYOUT, 2259 * -FDT_ERR_BADMAGIC, 2260 * -FDT_ERR_BADVERSION, 2261 * -FDT_ERR_BADSTATE, 2262 * -FDT_ERR_BADSTRUCTURE, 2263 * -FDT_ERR_TRUNCATED, standard meanings 2264 */ 2265 int fdt_del_node(void *fdt, int nodeoffset); 2266 2267 /** 2268 * fdt_overlay_apply - Applies a DT overlay on a base DT 2269 * @fdt: pointer to the base device tree blob 2270 * @fdto: pointer to the device tree overlay blob 2271 * 2272 * fdt_overlay_apply() will apply the given device tree overlay on the 2273 * given base device tree. 2274 * 2275 * Expect the base device tree to be modified, even if the function 2276 * returns an error. 2277 * 2278 * returns: 2279 * 0, on success 2280 * -FDT_ERR_NOSPACE, there's not enough space in the base device tree 2281 * -FDT_ERR_NOTFOUND, the overlay points to some nonexistent nodes or 2282 * properties in the base DT 2283 * -FDT_ERR_BADPHANDLE, 2284 * -FDT_ERR_BADOVERLAY, 2285 * -FDT_ERR_NOPHANDLES, 2286 * -FDT_ERR_INTERNAL, 2287 * -FDT_ERR_BADLAYOUT, 2288 * -FDT_ERR_BADMAGIC, 2289 * -FDT_ERR_BADOFFSET, 2290 * -FDT_ERR_BADPATH, 2291 * -FDT_ERR_BADVERSION, 2292 * -FDT_ERR_BADSTRUCTURE, 2293 * -FDT_ERR_BADSTATE, 2294 * -FDT_ERR_TRUNCATED, standard meanings 2295 */ 2296 int fdt_overlay_apply(void *fdt, void *fdto); 2297 2298 /** 2299 * fdt_overlay_target_offset - retrieves the offset of a fragment's target 2300 * @fdt: Base device tree blob 2301 * @fdto: Device tree overlay blob 2302 * @fragment_offset: node offset of the fragment in the overlay 2303 * @pathp: pointer which receives the path of the target (or NULL) 2304 * 2305 * fdt_overlay_target_offset() retrieves the target offset in the base 2306 * device tree of a fragment, no matter how the actual targeting is 2307 * done (through a phandle or a path) 2308 * 2309 * returns: 2310 * the targeted node offset in the base device tree 2311 * Negative error code on error 2312 */ 2313 int fdt_overlay_target_offset(const void *fdt, const void *fdto, 2314 int fragment_offset, char const **pathp); 2315 2316 /**********************************************************************/ 2317 /* Debugging / informational functions */ 2318 /**********************************************************************/ 2319 2320 const char *fdt_strerror(int errval); 2321 2322 #ifdef __cplusplus 2323 } 2324 #endif 2325 2326 #endif /* LIBFDT_H */ 2327