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: devicetree 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 #endif 716 717 /** 718 * fdt_get_property - find a given property in a given node 719 * @fdt: pointer to the device tree blob 720 * @nodeoffset: offset of the node whose property to find 721 * @name: name of the property to find 722 * @lenp: pointer to an integer variable (will be overwritten) or NULL 723 * 724 * fdt_get_property() retrieves a pointer to the fdt_property 725 * structure within the device tree blob corresponding to the property 726 * named 'name' of the node at offset nodeoffset. If lenp is 727 * non-NULL, the length of the property value is also returned, in the 728 * integer pointed to by lenp. 729 * 730 * returns: 731 * pointer to the structure representing the property 732 * if lenp is non-NULL, *lenp contains the length of the property 733 * value (>=0) 734 * NULL, on error 735 * if lenp is non-NULL, *lenp contains an error code (<0): 736 * -FDT_ERR_NOTFOUND, node does not have named property 737 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE 738 * tag 739 * -FDT_ERR_BADMAGIC, 740 * -FDT_ERR_BADVERSION, 741 * -FDT_ERR_BADSTATE, 742 * -FDT_ERR_BADSTRUCTURE, 743 * -FDT_ERR_TRUNCATED, standard meanings 744 */ 745 const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, 746 const char *name, int *lenp); 747 static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, 748 const char *name, 749 int *lenp) 750 { 751 return (struct fdt_property *)(uintptr_t) 752 fdt_get_property(fdt, nodeoffset, name, lenp); 753 } 754 755 /** 756 * fdt_getprop_by_offset - retrieve the value of a property at a given offset 757 * @fdt: pointer to the device tree blob 758 * @offset: offset of the property to read 759 * @namep: pointer to a string variable (will be overwritten) or NULL 760 * @lenp: pointer to an integer variable (will be overwritten) or NULL 761 * 762 * fdt_getprop_by_offset() retrieves a pointer to the value of the 763 * property at structure block offset 'offset' (this will be a pointer 764 * to within the device blob itself, not a copy of the value). If 765 * lenp is non-NULL, the length of the property value is also 766 * returned, in the integer pointed to by lenp. If namep is non-NULL, 767 * the property's namne will also be returned in the char * pointed to 768 * by namep (this will be a pointer to within the device tree's string 769 * block, not a new copy of the name). 770 * 771 * returns: 772 * pointer to the property's value 773 * if lenp is non-NULL, *lenp contains the length of the property 774 * value (>=0) 775 * if namep is non-NULL *namep contiains a pointer to the property 776 * name. 777 * NULL, on error 778 * if lenp is non-NULL, *lenp contains an error code (<0): 779 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag 780 * -FDT_ERR_BADMAGIC, 781 * -FDT_ERR_BADVERSION, 782 * -FDT_ERR_BADSTATE, 783 * -FDT_ERR_BADSTRUCTURE, 784 * -FDT_ERR_TRUNCATED, standard meanings 785 */ 786 #ifndef SWIG /* This function is not useful in Python */ 787 const void *fdt_getprop_by_offset(const void *fdt, int offset, 788 const char **namep, int *lenp); 789 #endif 790 791 /** 792 * fdt_getprop_namelen - get property value based on substring 793 * @fdt: pointer to the device tree blob 794 * @nodeoffset: offset of the node whose property to find 795 * @name: name of the property to find 796 * @namelen: number of characters of name to consider 797 * @lenp: pointer to an integer variable (will be overwritten) or NULL 798 * 799 * Identical to fdt_getprop(), but only examine the first namelen 800 * characters of name for matching the property name. 801 * 802 * Return: pointer to the property's value or NULL on error 803 */ 804 #ifndef SWIG /* Not available in Python */ 805 const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, 806 const char *name, int namelen, int *lenp); 807 static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, 808 const char *name, int namelen, 809 int *lenp) 810 { 811 return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, 812 namelen, lenp); 813 } 814 #endif 815 816 /** 817 * fdt_getprop - retrieve the value of a given property 818 * @fdt: pointer to the device tree blob 819 * @nodeoffset: offset of the node whose property to find 820 * @name: name of the property to find 821 * @lenp: pointer to an integer variable (will be overwritten) or NULL 822 * 823 * fdt_getprop() retrieves a pointer to the value of the property 824 * named @name of the node at offset @nodeoffset (this will be a 825 * pointer to within the device blob itself, not a copy of the value). 826 * If @lenp is non-NULL, the length of the property value is also 827 * returned, in the integer pointed to by @lenp. 828 * 829 * returns: 830 * pointer to the property's value 831 * if lenp is non-NULL, *lenp contains the length of the property 832 * value (>=0) 833 * NULL, on error 834 * if lenp is non-NULL, *lenp contains an error code (<0): 835 * -FDT_ERR_NOTFOUND, node does not have named property 836 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE 837 * tag 838 * -FDT_ERR_BADMAGIC, 839 * -FDT_ERR_BADVERSION, 840 * -FDT_ERR_BADSTATE, 841 * -FDT_ERR_BADSTRUCTURE, 842 * -FDT_ERR_TRUNCATED, standard meanings 843 */ 844 const void *fdt_getprop(const void *fdt, int nodeoffset, 845 const char *name, int *lenp); 846 static inline void *fdt_getprop_w(void *fdt, int nodeoffset, 847 const char *name, int *lenp) 848 { 849 return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); 850 } 851 852 /** 853 * fdt_get_phandle - retrieve the phandle of a given node 854 * @fdt: pointer to the device tree blob 855 * @nodeoffset: structure block offset of the node 856 * 857 * fdt_get_phandle() retrieves the phandle of the device tree node at 858 * structure block offset nodeoffset. 859 * 860 * returns: 861 * the phandle of the node at nodeoffset, on success (!= 0, != -1) 862 * 0, if the node has no phandle, or another error occurs 863 */ 864 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); 865 866 /** 867 * fdt_get_alias_namelen - get alias based on substring 868 * @fdt: pointer to the device tree blob 869 * @name: name of the alias th look up 870 * @namelen: number of characters of name to consider 871 * 872 * Identical to fdt_get_alias(), but only examine the first @namelen 873 * characters of @name for matching the alias name. 874 * 875 * Return: a pointer to the expansion of the alias named @name, if it exists, 876 * NULL otherwise 877 */ 878 #ifndef SWIG /* Not available in Python */ 879 const char *fdt_get_alias_namelen(const void *fdt, 880 const char *name, int namelen); 881 #endif 882 883 /** 884 * fdt_get_alias - retrieve the path referenced by a given alias 885 * @fdt: pointer to the device tree blob 886 * @name: name of the alias th look up 887 * 888 * fdt_get_alias() retrieves the value of a given alias. That is, the 889 * value of the property named @name in the node /aliases. 890 * 891 * returns: 892 * a pointer to the expansion of the alias named 'name', if it exists 893 * NULL, if the given alias or the /aliases node does not exist 894 */ 895 const char *fdt_get_alias(const void *fdt, const char *name); 896 897 /** 898 * fdt_get_symbol_namelen - get symbol based on substring 899 * @fdt: pointer to the device tree blob 900 * @name: name of the symbol to look up 901 * @namelen: number of characters of name to consider 902 * 903 * Identical to fdt_get_symbol(), but only examine the first @namelen 904 * characters of @name for matching the symbol name. 905 * 906 * Return: a pointer to the expansion of the symbol named @name, if it exists, 907 * NULL otherwise 908 */ 909 #ifndef SWIG /* Not available in Python */ 910 const char *fdt_get_symbol_namelen(const void *fdt, 911 const char *name, int namelen); 912 #endif 913 914 /** 915 * fdt_get_symbol - retrieve the path referenced by a given symbol 916 * @fdt: pointer to the device tree blob 917 * @name: name of the symbol to look up 918 * 919 * fdt_get_symbol() retrieves the value of a given symbol. That is, 920 * the value of the property named @name in the node 921 * /__symbols__. Such a node exists only for a device tree blob that 922 * has been compiled with the -@ dtc option. Each property corresponds 923 * to a label appearing in the device tree source, with the name of 924 * the property being the label and the value being the full path of 925 * the node it is attached to. 926 * 927 * returns: 928 * a pointer to the expansion of the symbol named 'name', if it exists 929 * NULL, if the given symbol or the /__symbols__ node does not exist 930 */ 931 const char *fdt_get_symbol(const void *fdt, const char *name); 932 933 /** 934 * fdt_get_path - determine the full path of a node 935 * @fdt: pointer to the device tree blob 936 * @nodeoffset: offset of the node whose path to find 937 * @buf: character buffer to contain the returned path (will be overwritten) 938 * @buflen: size of the character buffer at buf 939 * 940 * fdt_get_path() computes the full path of the node at offset 941 * nodeoffset, and records that path in the buffer at buf. 942 * 943 * NOTE: This function is expensive, as it must scan the device tree 944 * structure from the start to nodeoffset. 945 * 946 * returns: 947 * 0, on success 948 * buf contains the absolute path of the node at 949 * nodeoffset, as a NUL-terminated string. 950 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 951 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) 952 * characters and will not fit in the given buffer. 953 * -FDT_ERR_BADMAGIC, 954 * -FDT_ERR_BADVERSION, 955 * -FDT_ERR_BADSTATE, 956 * -FDT_ERR_BADSTRUCTURE, standard meanings 957 */ 958 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); 959 960 /** 961 * fdt_supernode_atdepth_offset - find a specific ancestor of a node 962 * @fdt: pointer to the device tree blob 963 * @nodeoffset: offset of the node whose parent to find 964 * @supernodedepth: depth of the ancestor to find 965 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL 966 * 967 * fdt_supernode_atdepth_offset() finds an ancestor of the given node 968 * at a specific depth from the root (where the root itself has depth 969 * 0, its immediate subnodes depth 1 and so forth). So 970 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); 971 * will always return 0, the offset of the root node. If the node at 972 * nodeoffset has depth D, then: 973 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); 974 * will return nodeoffset itself. 975 * 976 * NOTE: This function is expensive, as it must scan the device tree 977 * structure from the start to nodeoffset. 978 * 979 * returns: 980 * structure block offset of the node at node offset's ancestor 981 * of depth supernodedepth (>=0), on success 982 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 983 * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of 984 * nodeoffset 985 * -FDT_ERR_BADMAGIC, 986 * -FDT_ERR_BADVERSION, 987 * -FDT_ERR_BADSTATE, 988 * -FDT_ERR_BADSTRUCTURE, standard meanings 989 */ 990 int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, 991 int supernodedepth, int *nodedepth); 992 993 /** 994 * fdt_node_depth - find the depth of a given node 995 * @fdt: pointer to the device tree blob 996 * @nodeoffset: offset of the node whose parent to find 997 * 998 * fdt_node_depth() finds the depth of a given node. The root node 999 * has depth 0, its immediate subnodes depth 1 and so forth. 1000 * 1001 * NOTE: This function is expensive, as it must scan the device tree 1002 * structure from the start to nodeoffset. 1003 * 1004 * returns: 1005 * depth of the node at nodeoffset (>=0), on success 1006 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1007 * -FDT_ERR_BADMAGIC, 1008 * -FDT_ERR_BADVERSION, 1009 * -FDT_ERR_BADSTATE, 1010 * -FDT_ERR_BADSTRUCTURE, standard meanings 1011 */ 1012 int fdt_node_depth(const void *fdt, int nodeoffset); 1013 1014 /** 1015 * fdt_parent_offset - find the parent of a given node 1016 * @fdt: pointer to the device tree blob 1017 * @nodeoffset: offset of the node whose parent to find 1018 * 1019 * fdt_parent_offset() locates the parent node of a given node (that 1020 * is, it finds the offset of the node which contains the node at 1021 * nodeoffset as a subnode). 1022 * 1023 * NOTE: This function is expensive, as it must scan the device tree 1024 * structure from the start to nodeoffset, *twice*. 1025 * 1026 * returns: 1027 * structure block offset of the parent of the node at nodeoffset 1028 * (>=0), on success 1029 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1030 * -FDT_ERR_BADMAGIC, 1031 * -FDT_ERR_BADVERSION, 1032 * -FDT_ERR_BADSTATE, 1033 * -FDT_ERR_BADSTRUCTURE, standard meanings 1034 */ 1035 int fdt_parent_offset(const void *fdt, int nodeoffset); 1036 1037 /** 1038 * fdt_node_offset_by_prop_value - find nodes with a given property value 1039 * @fdt: pointer to the device tree blob 1040 * @startoffset: only find nodes after this offset 1041 * @propname: property name to check 1042 * @propval: property value to search for 1043 * @proplen: length of the value in propval 1044 * 1045 * fdt_node_offset_by_prop_value() returns the offset of the first 1046 * node after startoffset, which has a property named propname whose 1047 * value is of length proplen and has value equal to propval; or if 1048 * startoffset is -1, the very first such node in the tree. 1049 * 1050 * To iterate through all nodes matching the criterion, the following 1051 * idiom can be used: 1052 * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, 1053 * propval, proplen); 1054 * while (offset != -FDT_ERR_NOTFOUND) { 1055 * // other code here 1056 * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, 1057 * propval, proplen); 1058 * } 1059 * 1060 * Note the -1 in the first call to the function, if 0 is used here 1061 * instead, the function will never locate the root node, even if it 1062 * matches the criterion. 1063 * 1064 * returns: 1065 * structure block offset of the located node (>= 0, >startoffset), 1066 * on success 1067 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 1068 * tree after startoffset 1069 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1070 * -FDT_ERR_BADMAGIC, 1071 * -FDT_ERR_BADVERSION, 1072 * -FDT_ERR_BADSTATE, 1073 * -FDT_ERR_BADSTRUCTURE, standard meanings 1074 */ 1075 int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, 1076 const char *propname, 1077 const void *propval, int proplen); 1078 1079 /** 1080 * fdt_node_offset_by_phandle - find the node with a given phandle 1081 * @fdt: pointer to the device tree blob 1082 * @phandle: phandle value 1083 * 1084 * fdt_node_offset_by_phandle() returns the offset of the node 1085 * which has the given phandle value. If there is more than one node 1086 * in the tree with the given phandle (an invalid tree), results are 1087 * undefined. 1088 * 1089 * returns: 1090 * structure block offset of the located node (>= 0), on success 1091 * -FDT_ERR_NOTFOUND, no node with that phandle exists 1092 * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) 1093 * -FDT_ERR_BADMAGIC, 1094 * -FDT_ERR_BADVERSION, 1095 * -FDT_ERR_BADSTATE, 1096 * -FDT_ERR_BADSTRUCTURE, standard meanings 1097 */ 1098 int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); 1099 1100 /** 1101 * fdt_node_check_compatible - check a node's compatible property 1102 * @fdt: pointer to the device tree blob 1103 * @nodeoffset: offset of a tree node 1104 * @compatible: string to match against 1105 * 1106 * fdt_node_check_compatible() returns 0 if the given node contains a 1107 * @compatible property with the given string as one of its elements, 1108 * it returns non-zero otherwise, or on error. 1109 * 1110 * returns: 1111 * 0, if the node has a 'compatible' property listing the given string 1112 * 1, if the node has a 'compatible' property, but it does not list 1113 * the given string 1114 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property 1115 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag 1116 * -FDT_ERR_BADMAGIC, 1117 * -FDT_ERR_BADVERSION, 1118 * -FDT_ERR_BADSTATE, 1119 * -FDT_ERR_BADSTRUCTURE, standard meanings 1120 */ 1121 int fdt_node_check_compatible(const void *fdt, int nodeoffset, 1122 const char *compatible); 1123 1124 /** 1125 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value 1126 * @fdt: pointer to the device tree blob 1127 * @startoffset: only find nodes after this offset 1128 * @compatible: 'compatible' string to match against 1129 * 1130 * fdt_node_offset_by_compatible() returns the offset of the first 1131 * node after startoffset, which has a 'compatible' property which 1132 * lists the given compatible string; or if startoffset is -1, the 1133 * very first such node in the tree. 1134 * 1135 * To iterate through all nodes matching the criterion, the following 1136 * idiom can be used: 1137 * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); 1138 * while (offset != -FDT_ERR_NOTFOUND) { 1139 * // other code here 1140 * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); 1141 * } 1142 * 1143 * Note the -1 in the first call to the function, if 0 is used here 1144 * instead, the function will never locate the root node, even if it 1145 * matches the criterion. 1146 * 1147 * returns: 1148 * structure block offset of the located node (>= 0, >startoffset), 1149 * on success 1150 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the 1151 * tree after startoffset 1152 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 1153 * -FDT_ERR_BADMAGIC, 1154 * -FDT_ERR_BADVERSION, 1155 * -FDT_ERR_BADSTATE, 1156 * -FDT_ERR_BADSTRUCTURE, standard meanings 1157 */ 1158 int fdt_node_offset_by_compatible(const void *fdt, int startoffset, 1159 const char *compatible); 1160 1161 /** 1162 * fdt_stringlist_contains - check a string list property for a string 1163 * @strlist: Property containing a list of strings to check 1164 * @listlen: Length of property 1165 * @str: String to search for 1166 * 1167 * This is a utility function provided for convenience. The list contains 1168 * one or more strings, each terminated by \0, as is found in a device tree 1169 * "compatible" property. 1170 * 1171 * Return: 1 if the string is found in the list, 0 not found, or invalid list 1172 */ 1173 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); 1174 1175 /** 1176 * fdt_stringlist_count - count the number of strings in a string list 1177 * @fdt: pointer to the device tree blob 1178 * @nodeoffset: offset of a tree node 1179 * @property: name of the property containing the string list 1180 * 1181 * Return: 1182 * the number of strings in the given property 1183 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1184 * -FDT_ERR_NOTFOUND if the property does not exist 1185 */ 1186 int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); 1187 1188 /** 1189 * fdt_stringlist_search - find a string in a string list and return its index 1190 * @fdt: pointer to the device tree blob 1191 * @nodeoffset: offset of a tree node 1192 * @property: name of the property containing the string list 1193 * @string: string to look up in the string list 1194 * 1195 * Note that it is possible for this function to succeed on property values 1196 * that are not NUL-terminated. That's because the function will stop after 1197 * finding the first occurrence of @string. This can for example happen with 1198 * small-valued cell properties, such as #address-cells, when searching for 1199 * the empty string. 1200 * 1201 * return: 1202 * the index of the string in the list of strings 1203 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1204 * -FDT_ERR_NOTFOUND if the property does not exist or does not contain 1205 * the given string 1206 */ 1207 int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, 1208 const char *string); 1209 1210 /** 1211 * fdt_stringlist_get() - obtain the string at a given index in a string list 1212 * @fdt: pointer to the device tree blob 1213 * @nodeoffset: offset of a tree node 1214 * @property: name of the property containing the string list 1215 * @index: index of the string to return 1216 * @lenp: return location for the string length or an error code on failure 1217 * 1218 * Note that this will successfully extract strings from properties with 1219 * non-NUL-terminated values. For example on small-valued cell properties 1220 * this function will return the empty string. 1221 * 1222 * If non-NULL, the length of the string (on success) or a negative error-code 1223 * (on failure) will be stored in the integer pointer to by lenp. 1224 * 1225 * Return: 1226 * A pointer to the string at the given index in the string list or NULL on 1227 * failure. On success the length of the string will be stored in the memory 1228 * location pointed to by the lenp parameter, if non-NULL. On failure one of 1229 * the following negative error codes will be returned in the lenp parameter 1230 * (if non-NULL): 1231 * -FDT_ERR_BADVALUE if the property value is not NUL-terminated 1232 * -FDT_ERR_NOTFOUND if the property does not exist 1233 */ 1234 const char *fdt_stringlist_get(const void *fdt, int nodeoffset, 1235 const char *property, int index, 1236 int *lenp); 1237 1238 /**********************************************************************/ 1239 /* Read-only functions (addressing related) */ 1240 /**********************************************************************/ 1241 1242 /** 1243 * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells 1244 * 1245 * This is the maximum value for #address-cells, #size-cells and 1246 * similar properties that will be processed by libfdt. IEE1275 1247 * requires that OF implementations handle values up to 4. 1248 * Implementations may support larger values, but in practice higher 1249 * values aren't used. 1250 */ 1251 #define FDT_MAX_NCELLS 4 1252 1253 /** 1254 * fdt_address_cells - retrieve address size for a bus represented in the tree 1255 * @fdt: pointer to the device tree blob 1256 * @nodeoffset: offset of the node to find the address size for 1257 * 1258 * When the node has a valid #address-cells property, returns its value. 1259 * 1260 * returns: 1261 * 0 <= n < FDT_MAX_NCELLS, on success 1262 * 2, if the node has no #address-cells property 1263 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1264 * #address-cells property 1265 * -FDT_ERR_BADMAGIC, 1266 * -FDT_ERR_BADVERSION, 1267 * -FDT_ERR_BADSTATE, 1268 * -FDT_ERR_BADSTRUCTURE, 1269 * -FDT_ERR_TRUNCATED, standard meanings 1270 */ 1271 int fdt_address_cells(const void *fdt, int nodeoffset); 1272 1273 /** 1274 * fdt_size_cells - retrieve address range size for a bus represented in the 1275 * tree 1276 * @fdt: pointer to the device tree blob 1277 * @nodeoffset: offset of the node to find the address range size for 1278 * 1279 * When the node has a valid #size-cells property, returns its value. 1280 * 1281 * returns: 1282 * 0 <= n < FDT_MAX_NCELLS, on success 1283 * 1, if the node has no #size-cells property 1284 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 1285 * #size-cells property 1286 * -FDT_ERR_BADMAGIC, 1287 * -FDT_ERR_BADVERSION, 1288 * -FDT_ERR_BADSTATE, 1289 * -FDT_ERR_BADSTRUCTURE, 1290 * -FDT_ERR_TRUNCATED, standard meanings 1291 */ 1292 int fdt_size_cells(const void *fdt, int nodeoffset); 1293 1294 1295 /**********************************************************************/ 1296 /* Write-in-place functions */ 1297 /**********************************************************************/ 1298 1299 /** 1300 * fdt_setprop_inplace_namelen_partial - change a property's value, 1301 * but not its size 1302 * @fdt: pointer to the device tree blob 1303 * @nodeoffset: offset of the node whose property to change 1304 * @name: name of the property to change 1305 * @namelen: number of characters of name to consider 1306 * @idx: index of the property to change in the array 1307 * @val: pointer to data to replace the property value with 1308 * @len: length of the property value 1309 * 1310 * Identical to fdt_setprop_inplace(), but modifies the given property 1311 * starting from the given index, and using only the first characters 1312 * of the name. It is useful when you want to manipulate only one value of 1313 * an array and you have a string that doesn't end with \0. 1314 * 1315 * Return: 0 on success, negative libfdt error value otherwise 1316 */ 1317 #ifndef SWIG /* Not available in Python */ 1318 int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, 1319 const char *name, int namelen, 1320 uint32_t idx, const void *val, 1321 int len); 1322 #endif 1323 1324 /** 1325 * fdt_setprop_inplace - change a property's value, but not its size 1326 * @fdt: pointer to the device tree blob 1327 * @nodeoffset: offset of the node whose property to change 1328 * @name: name of the property to change 1329 * @val: pointer to data to replace the property value with 1330 * @len: length of the property value 1331 * 1332 * fdt_setprop_inplace() replaces the value of a given property with 1333 * the data in val, of length len. This function cannot change the 1334 * size of a property, and so will only work if len is equal to the 1335 * current length of the property. 1336 * 1337 * This function will alter only the bytes in the blob which contain 1338 * the given property value, and will not alter or move any other part 1339 * of the tree. 1340 * 1341 * returns: 1342 * 0, on success 1343 * -FDT_ERR_NOSPACE, if len is not equal to the property's current length 1344 * -FDT_ERR_NOTFOUND, node does not have the named property 1345 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1346 * -FDT_ERR_BADMAGIC, 1347 * -FDT_ERR_BADVERSION, 1348 * -FDT_ERR_BADSTATE, 1349 * -FDT_ERR_BADSTRUCTURE, 1350 * -FDT_ERR_TRUNCATED, standard meanings 1351 */ 1352 #ifndef SWIG /* Not available in Python */ 1353 int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, 1354 const void *val, int len); 1355 #endif 1356 1357 /** 1358 * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property 1359 * @fdt: pointer to the device tree blob 1360 * @nodeoffset: offset of the node whose property to change 1361 * @name: name of the property to change 1362 * @val: 32-bit integer value to replace the property with 1363 * 1364 * fdt_setprop_inplace_u32() replaces the value of a given property 1365 * with the 32-bit integer value in val, converting val to big-endian 1366 * if necessary. This function cannot change the size of a property, 1367 * and so will only work if the property already exists and has length 1368 * 4. 1369 * 1370 * This function will alter only the bytes in the blob which contain 1371 * the given property value, and will not alter or move any other part 1372 * of the tree. 1373 * 1374 * returns: 1375 * 0, on success 1376 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 1377 * -FDT_ERR_NOTFOUND, node does not have the named property 1378 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1379 * -FDT_ERR_BADMAGIC, 1380 * -FDT_ERR_BADVERSION, 1381 * -FDT_ERR_BADSTATE, 1382 * -FDT_ERR_BADSTRUCTURE, 1383 * -FDT_ERR_TRUNCATED, standard meanings 1384 */ 1385 static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, 1386 const char *name, uint32_t val) 1387 { 1388 fdt32_t tmp = cpu_to_fdt32(val); 1389 return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1390 } 1391 1392 /** 1393 * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property 1394 * @fdt: pointer to the device tree blob 1395 * @nodeoffset: offset of the node whose property to change 1396 * @name: name of the property to change 1397 * @val: 64-bit integer value to replace the property with 1398 * 1399 * fdt_setprop_inplace_u64() replaces the value of a given property 1400 * with the 64-bit integer value in val, converting val to big-endian 1401 * if necessary. This function cannot change the size of a property, 1402 * and so will only work if the property already exists and has length 1403 * 8. 1404 * 1405 * This function will alter only the bytes in the blob which contain 1406 * the given property value, and will not alter or move any other part 1407 * of the tree. 1408 * 1409 * returns: 1410 * 0, on success 1411 * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 1412 * -FDT_ERR_NOTFOUND, node does not have the named property 1413 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1414 * -FDT_ERR_BADMAGIC, 1415 * -FDT_ERR_BADVERSION, 1416 * -FDT_ERR_BADSTATE, 1417 * -FDT_ERR_BADSTRUCTURE, 1418 * -FDT_ERR_TRUNCATED, standard meanings 1419 */ 1420 static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, 1421 const char *name, uint64_t val) 1422 { 1423 fdt64_t tmp = cpu_to_fdt64(val); 1424 return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1425 } 1426 1427 /** 1428 * fdt_setprop_inplace_cell - change the value of a single-cell property 1429 * @fdt: pointer to the device tree blob 1430 * @nodeoffset: offset of the node containing the property 1431 * @name: name of the property to change the value of 1432 * @val: new value of the 32-bit cell 1433 * 1434 * This is an alternative name for fdt_setprop_inplace_u32() 1435 * Return: 0 on success, negative libfdt error number otherwise. 1436 */ 1437 static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, 1438 const char *name, uint32_t val) 1439 { 1440 return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); 1441 } 1442 1443 /** 1444 * fdt_nop_property - replace a property with nop tags 1445 * @fdt: pointer to the device tree blob 1446 * @nodeoffset: offset of the node whose property to nop 1447 * @name: name of the property to nop 1448 * 1449 * fdt_nop_property() will replace a given property's representation 1450 * in the blob with FDT_NOP tags, effectively removing it from the 1451 * tree. 1452 * 1453 * This function will alter only the bytes in the blob which contain 1454 * the property, and will not alter or move any other part of the 1455 * tree. 1456 * 1457 * returns: 1458 * 0, on success 1459 * -FDT_ERR_NOTFOUND, node does not have the named property 1460 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1461 * -FDT_ERR_BADMAGIC, 1462 * -FDT_ERR_BADVERSION, 1463 * -FDT_ERR_BADSTATE, 1464 * -FDT_ERR_BADSTRUCTURE, 1465 * -FDT_ERR_TRUNCATED, standard meanings 1466 */ 1467 int fdt_nop_property(void *fdt, int nodeoffset, const char *name); 1468 1469 /** 1470 * fdt_nop_node - replace a node (subtree) with nop tags 1471 * @fdt: pointer to the device tree blob 1472 * @nodeoffset: offset of the node to nop 1473 * 1474 * fdt_nop_node() will replace a given node's representation in the 1475 * blob, including all its subnodes, if any, with FDT_NOP tags, 1476 * effectively removing it from the tree. 1477 * 1478 * This function will alter only the bytes in the blob which contain 1479 * the node and its properties and subnodes, and will not alter or 1480 * move any other part of the tree. 1481 * 1482 * returns: 1483 * 0, on success 1484 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1485 * -FDT_ERR_BADMAGIC, 1486 * -FDT_ERR_BADVERSION, 1487 * -FDT_ERR_BADSTATE, 1488 * -FDT_ERR_BADSTRUCTURE, 1489 * -FDT_ERR_TRUNCATED, standard meanings 1490 */ 1491 int fdt_nop_node(void *fdt, int nodeoffset); 1492 1493 /**********************************************************************/ 1494 /* Sequential write functions */ 1495 /**********************************************************************/ 1496 1497 /* fdt_create_with_flags flags */ 1498 #define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 1499 /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property 1500 * names in the fdt. This can result in faster creation times, but 1501 * a larger fdt. */ 1502 1503 #define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) 1504 1505 /** 1506 * fdt_create_with_flags - begin creation of a new fdt 1507 * @buf: pointer to memory allocated where fdt will be created 1508 * @bufsize: size of the memory space at fdt 1509 * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. 1510 * 1511 * fdt_create_with_flags() begins the process of creating a new fdt with 1512 * the sequential write interface. 1513 * 1514 * fdt creation process must end with fdt_finish() to produce a valid fdt. 1515 * 1516 * returns: 1517 * 0, on success 1518 * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt 1519 * -FDT_ERR_BADFLAGS, flags is not valid 1520 */ 1521 int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); 1522 1523 /** 1524 * fdt_create - begin creation of a new fdt 1525 * @buf: pointer to memory allocated where fdt will be created 1526 * @bufsize: size of the memory space at fdt 1527 * 1528 * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. 1529 * 1530 * returns: 1531 * 0, on success 1532 * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt 1533 */ 1534 int fdt_create(void *buf, int bufsize); 1535 1536 int fdt_resize(void *fdt, void *buf, int bufsize); 1537 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); 1538 int fdt_finish_reservemap(void *fdt); 1539 int fdt_begin_node(void *fdt, const char *name); 1540 int fdt_property(void *fdt, const char *name, const void *val, int len); 1541 static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) 1542 { 1543 fdt32_t tmp = cpu_to_fdt32(val); 1544 return fdt_property(fdt, name, &tmp, sizeof(tmp)); 1545 } 1546 static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) 1547 { 1548 fdt64_t tmp = cpu_to_fdt64(val); 1549 return fdt_property(fdt, name, &tmp, sizeof(tmp)); 1550 } 1551 1552 #ifndef SWIG /* Not available in Python */ 1553 static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) 1554 { 1555 return fdt_property_u32(fdt, name, val); 1556 } 1557 #endif 1558 1559 /** 1560 * fdt_property_placeholder - add a new property and return a ptr to its value 1561 * 1562 * @fdt: pointer to the device tree blob 1563 * @name: name of property to add 1564 * @len: length of property value in bytes 1565 * @valp: returns a pointer to where where the value should be placed 1566 * 1567 * returns: 1568 * 0, on success 1569 * -FDT_ERR_BADMAGIC, 1570 * -FDT_ERR_NOSPACE, standard meanings 1571 */ 1572 int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); 1573 1574 #define fdt_property_string(fdt, name, str) \ 1575 fdt_property(fdt, name, str, strlen(str)+1) 1576 int fdt_end_node(void *fdt); 1577 int fdt_finish(void *fdt); 1578 1579 /**********************************************************************/ 1580 /* Read-write functions */ 1581 /**********************************************************************/ 1582 1583 int fdt_create_empty_tree(void *buf, int bufsize); 1584 int fdt_open_into(const void *fdt, void *buf, int bufsize); 1585 int fdt_pack(void *fdt); 1586 1587 /** 1588 * fdt_add_mem_rsv - add one memory reserve map entry 1589 * @fdt: pointer to the device tree blob 1590 * @address: 64-bit start address of the reserve map entry 1591 * @size: 64-bit size of the reserved region 1592 * 1593 * Adds a reserve map entry to the given blob reserving a region at 1594 * address address of length size. 1595 * 1596 * This function will insert data into the reserve map and will 1597 * therefore change the indexes of some entries in the table. 1598 * 1599 * returns: 1600 * 0, on success 1601 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1602 * contain the new reservation entry 1603 * -FDT_ERR_BADMAGIC, 1604 * -FDT_ERR_BADVERSION, 1605 * -FDT_ERR_BADSTATE, 1606 * -FDT_ERR_BADSTRUCTURE, 1607 * -FDT_ERR_BADLAYOUT, 1608 * -FDT_ERR_TRUNCATED, standard meanings 1609 */ 1610 int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); 1611 1612 /** 1613 * fdt_del_mem_rsv - remove a memory reserve map entry 1614 * @fdt: pointer to the device tree blob 1615 * @n: entry to remove 1616 * 1617 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from 1618 * the blob. 1619 * 1620 * This function will delete data from the reservation table and will 1621 * therefore change the indexes of some entries in the table. 1622 * 1623 * returns: 1624 * 0, on success 1625 * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there 1626 * are less than n+1 reserve map entries) 1627 * -FDT_ERR_BADMAGIC, 1628 * -FDT_ERR_BADVERSION, 1629 * -FDT_ERR_BADSTATE, 1630 * -FDT_ERR_BADSTRUCTURE, 1631 * -FDT_ERR_BADLAYOUT, 1632 * -FDT_ERR_TRUNCATED, standard meanings 1633 */ 1634 int fdt_del_mem_rsv(void *fdt, int n); 1635 1636 /** 1637 * fdt_set_name - change the name of a given node 1638 * @fdt: pointer to the device tree blob 1639 * @nodeoffset: structure block offset of a node 1640 * @name: name to give the node 1641 * 1642 * fdt_set_name() replaces the name (including unit address, if any) 1643 * of the given node with the given string. NOTE: this function can't 1644 * efficiently check if the new name is unique amongst the given 1645 * node's siblings; results are undefined if this function is invoked 1646 * with a name equal to one of the given node's siblings. 1647 * 1648 * This function may insert or delete data from the blob, and will 1649 * therefore change the offsets of some existing nodes. 1650 * 1651 * returns: 1652 * 0, on success 1653 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob 1654 * to contain the new name 1655 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1656 * -FDT_ERR_BADMAGIC, 1657 * -FDT_ERR_BADVERSION, 1658 * -FDT_ERR_BADSTATE, standard meanings 1659 */ 1660 int fdt_set_name(void *fdt, int nodeoffset, const char *name); 1661 1662 /** 1663 * fdt_setprop - create or change a property 1664 * @fdt: pointer to the device tree blob 1665 * @nodeoffset: offset of the node whose property to change 1666 * @name: name of the property to change 1667 * @val: pointer to data to set the property value to 1668 * @len: length of the property value 1669 * 1670 * fdt_setprop() sets the value of the named property in the given 1671 * node to the given value and length, creating the property if it 1672 * does not already exist. 1673 * 1674 * This function may insert or delete data from the blob, and will 1675 * therefore change the offsets of some existing nodes. 1676 * 1677 * returns: 1678 * 0, on success 1679 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1680 * contain the new property value 1681 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1682 * -FDT_ERR_BADLAYOUT, 1683 * -FDT_ERR_BADMAGIC, 1684 * -FDT_ERR_BADVERSION, 1685 * -FDT_ERR_BADSTATE, 1686 * -FDT_ERR_BADSTRUCTURE, 1687 * -FDT_ERR_BADLAYOUT, 1688 * -FDT_ERR_TRUNCATED, standard meanings 1689 */ 1690 int fdt_setprop(void *fdt, int nodeoffset, const char *name, 1691 const void *val, int len); 1692 1693 /** 1694 * fdt_setprop_placeholder - allocate space for a property 1695 * @fdt: pointer to the device tree blob 1696 * @nodeoffset: offset of the node whose property to change 1697 * @name: name of the property to change 1698 * @len: length of the property value 1699 * @prop_data: return pointer to property data 1700 * 1701 * fdt_setprop_placeholer() allocates the named property in the given node. 1702 * If the property exists it is resized. In either case a pointer to the 1703 * property data is returned. 1704 * 1705 * This function may insert or delete data from the blob, and will 1706 * therefore change the offsets of some existing nodes. 1707 * 1708 * returns: 1709 * 0, on success 1710 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1711 * contain the new property value 1712 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1713 * -FDT_ERR_BADLAYOUT, 1714 * -FDT_ERR_BADMAGIC, 1715 * -FDT_ERR_BADVERSION, 1716 * -FDT_ERR_BADSTATE, 1717 * -FDT_ERR_BADSTRUCTURE, 1718 * -FDT_ERR_BADLAYOUT, 1719 * -FDT_ERR_TRUNCATED, standard meanings 1720 */ 1721 int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, 1722 int len, void **prop_data); 1723 1724 /** 1725 * fdt_setprop_u32 - set a property to a 32-bit integer 1726 * @fdt: pointer to the device tree blob 1727 * @nodeoffset: offset of the node whose property to change 1728 * @name: name of the property to change 1729 * @val: 32-bit integer value for the property (native endian) 1730 * 1731 * fdt_setprop_u32() sets the value of the named property in the given 1732 * node to the given 32-bit integer value (converting to big-endian if 1733 * necessary), or creates a new property with that value if it does 1734 * not already exist. 1735 * 1736 * This function may insert or delete data from the blob, and will 1737 * therefore change the offsets of some existing nodes. 1738 * 1739 * returns: 1740 * 0, on success 1741 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1742 * contain the new property value 1743 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1744 * -FDT_ERR_BADLAYOUT, 1745 * -FDT_ERR_BADMAGIC, 1746 * -FDT_ERR_BADVERSION, 1747 * -FDT_ERR_BADSTATE, 1748 * -FDT_ERR_BADSTRUCTURE, 1749 * -FDT_ERR_BADLAYOUT, 1750 * -FDT_ERR_TRUNCATED, standard meanings 1751 */ 1752 static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, 1753 uint32_t val) 1754 { 1755 fdt32_t tmp = cpu_to_fdt32(val); 1756 return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1757 } 1758 1759 /** 1760 * fdt_setprop_u64 - set a property to a 64-bit integer 1761 * @fdt: pointer to the device tree blob 1762 * @nodeoffset: offset of the node whose property to change 1763 * @name: name of the property to change 1764 * @val: 64-bit integer value for the property (native endian) 1765 * 1766 * fdt_setprop_u64() sets the value of the named property in the given 1767 * node to the given 64-bit integer value (converting to big-endian if 1768 * necessary), or creates a new property with that value if it does 1769 * not already exist. 1770 * 1771 * This function may insert or delete data from the blob, and will 1772 * therefore change the offsets of some existing nodes. 1773 * 1774 * returns: 1775 * 0, on success 1776 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1777 * contain the new property value 1778 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1779 * -FDT_ERR_BADLAYOUT, 1780 * -FDT_ERR_BADMAGIC, 1781 * -FDT_ERR_BADVERSION, 1782 * -FDT_ERR_BADSTATE, 1783 * -FDT_ERR_BADSTRUCTURE, 1784 * -FDT_ERR_BADLAYOUT, 1785 * -FDT_ERR_TRUNCATED, standard meanings 1786 */ 1787 static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, 1788 uint64_t val) 1789 { 1790 fdt64_t tmp = cpu_to_fdt64(val); 1791 return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1792 } 1793 1794 /** 1795 * fdt_setprop_cell - set a property to a single cell value 1796 * @fdt: pointer to the device tree blob 1797 * @nodeoffset: offset of the node whose property to change 1798 * @name: name of the property to change 1799 * @val: 32-bit integer value for the property (native endian) 1800 * 1801 * This is an alternative name for fdt_setprop_u32() 1802 * 1803 * Return: 0 on success, negative libfdt error value otherwise. 1804 */ 1805 static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, 1806 uint32_t val) 1807 { 1808 return fdt_setprop_u32(fdt, nodeoffset, name, val); 1809 } 1810 1811 /** 1812 * fdt_setprop_string - set a property to a string value 1813 * @fdt: pointer to the device tree blob 1814 * @nodeoffset: offset of the node whose property to change 1815 * @name: name of the property to change 1816 * @str: string value for the property 1817 * 1818 * fdt_setprop_string() sets the value of the named property in the 1819 * given node to the given string value (using the length of the 1820 * string to determine the new length of the property), or creates a 1821 * new property with that value if it does not already exist. 1822 * 1823 * This function may insert or delete data from the blob, and will 1824 * therefore change the offsets of some existing nodes. 1825 * 1826 * returns: 1827 * 0, on success 1828 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1829 * contain the new property value 1830 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1831 * -FDT_ERR_BADLAYOUT, 1832 * -FDT_ERR_BADMAGIC, 1833 * -FDT_ERR_BADVERSION, 1834 * -FDT_ERR_BADSTATE, 1835 * -FDT_ERR_BADSTRUCTURE, 1836 * -FDT_ERR_BADLAYOUT, 1837 * -FDT_ERR_TRUNCATED, standard meanings 1838 */ 1839 #define fdt_setprop_string(fdt, nodeoffset, name, str) \ 1840 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 1841 1842 1843 /** 1844 * fdt_setprop_empty - set a property to an empty value 1845 * @fdt: pointer to the device tree blob 1846 * @nodeoffset: offset of the node whose property to change 1847 * @name: name of the property to change 1848 * 1849 * fdt_setprop_empty() sets the value of the named property in the 1850 * given node to an empty (zero length) value, or creates a new empty 1851 * property if it does not already exist. 1852 * 1853 * This function may insert or delete data from the blob, and will 1854 * therefore change the offsets of some existing nodes. 1855 * 1856 * returns: 1857 * 0, on success 1858 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1859 * contain the new property value 1860 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1861 * -FDT_ERR_BADLAYOUT, 1862 * -FDT_ERR_BADMAGIC, 1863 * -FDT_ERR_BADVERSION, 1864 * -FDT_ERR_BADSTATE, 1865 * -FDT_ERR_BADSTRUCTURE, 1866 * -FDT_ERR_BADLAYOUT, 1867 * -FDT_ERR_TRUNCATED, standard meanings 1868 */ 1869 #define fdt_setprop_empty(fdt, nodeoffset, name) \ 1870 fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) 1871 1872 /** 1873 * fdt_appendprop - append to or create a property 1874 * @fdt: pointer to the device tree blob 1875 * @nodeoffset: offset of the node whose property to change 1876 * @name: name of the property to append to 1877 * @val: pointer to data to append to the property value 1878 * @len: length of the data to append to the property value 1879 * 1880 * fdt_appendprop() appends the value to the named property in the 1881 * given node, creating the property if it does not already exist. 1882 * 1883 * This function may insert data into the blob, and will therefore 1884 * change the offsets of some existing nodes. 1885 * 1886 * returns: 1887 * 0, on success 1888 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1889 * contain the new property value 1890 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1891 * -FDT_ERR_BADLAYOUT, 1892 * -FDT_ERR_BADMAGIC, 1893 * -FDT_ERR_BADVERSION, 1894 * -FDT_ERR_BADSTATE, 1895 * -FDT_ERR_BADSTRUCTURE, 1896 * -FDT_ERR_BADLAYOUT, 1897 * -FDT_ERR_TRUNCATED, standard meanings 1898 */ 1899 int fdt_appendprop(void *fdt, int nodeoffset, const char *name, 1900 const void *val, int len); 1901 1902 /** 1903 * fdt_appendprop_u32 - append a 32-bit integer value to a property 1904 * @fdt: pointer to the device tree blob 1905 * @nodeoffset: offset of the node whose property to change 1906 * @name: name of the property to change 1907 * @val: 32-bit integer value to append to the property (native endian) 1908 * 1909 * fdt_appendprop_u32() appends the given 32-bit integer value 1910 * (converting to big-endian if necessary) to the value of the named 1911 * property in the given node, or creates a new property with that 1912 * value if it does not already exist. 1913 * 1914 * This function may insert data into the blob, and will therefore 1915 * change the offsets of some existing nodes. 1916 * 1917 * returns: 1918 * 0, on success 1919 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1920 * contain the new property value 1921 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1922 * -FDT_ERR_BADLAYOUT, 1923 * -FDT_ERR_BADMAGIC, 1924 * -FDT_ERR_BADVERSION, 1925 * -FDT_ERR_BADSTATE, 1926 * -FDT_ERR_BADSTRUCTURE, 1927 * -FDT_ERR_BADLAYOUT, 1928 * -FDT_ERR_TRUNCATED, standard meanings 1929 */ 1930 static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, 1931 const char *name, uint32_t val) 1932 { 1933 fdt32_t tmp = cpu_to_fdt32(val); 1934 return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1935 } 1936 1937 /** 1938 * fdt_appendprop_u64 - append a 64-bit integer value to a property 1939 * @fdt: pointer to the device tree blob 1940 * @nodeoffset: offset of the node whose property to change 1941 * @name: name of the property to change 1942 * @val: 64-bit integer value to append to the property (native endian) 1943 * 1944 * fdt_appendprop_u64() appends the given 64-bit integer value 1945 * (converting to big-endian if necessary) to the value of the named 1946 * property in the given node, or creates a new property with that 1947 * value if it does not already exist. 1948 * 1949 * This function may insert data into the blob, and will therefore 1950 * change the offsets of some existing nodes. 1951 * 1952 * returns: 1953 * 0, on success 1954 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 1955 * contain the new property value 1956 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 1957 * -FDT_ERR_BADLAYOUT, 1958 * -FDT_ERR_BADMAGIC, 1959 * -FDT_ERR_BADVERSION, 1960 * -FDT_ERR_BADSTATE, 1961 * -FDT_ERR_BADSTRUCTURE, 1962 * -FDT_ERR_BADLAYOUT, 1963 * -FDT_ERR_TRUNCATED, standard meanings 1964 */ 1965 static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, 1966 const char *name, uint64_t val) 1967 { 1968 fdt64_t tmp = cpu_to_fdt64(val); 1969 return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); 1970 } 1971 1972 /** 1973 * fdt_appendprop_cell - append a single cell value to a property 1974 * @fdt: pointer to the device tree blob 1975 * @nodeoffset: offset of the node whose property to change 1976 * @name: name of the property to change 1977 * @val: 32-bit integer value to append to the property (native endian) 1978 * 1979 * This is an alternative name for fdt_appendprop_u32() 1980 * 1981 * Return: 0 on success, negative libfdt error value otherwise. 1982 */ 1983 static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, 1984 const char *name, uint32_t val) 1985 { 1986 return fdt_appendprop_u32(fdt, nodeoffset, name, val); 1987 } 1988 1989 /** 1990 * fdt_appendprop_string - append a string to a property 1991 * @fdt: pointer to the device tree blob 1992 * @nodeoffset: offset of the node whose property to change 1993 * @name: name of the property to change 1994 * @str: string value to append to the property 1995 * 1996 * fdt_appendprop_string() appends the given string to the value of 1997 * the named property in the given node, or creates a new property 1998 * with that value if it does not already exist. 1999 * 2000 * This function may insert data into the blob, and will therefore 2001 * change the offsets of some existing nodes. 2002 * 2003 * returns: 2004 * 0, on success 2005 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2006 * contain the new property value 2007 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2008 * -FDT_ERR_BADLAYOUT, 2009 * -FDT_ERR_BADMAGIC, 2010 * -FDT_ERR_BADVERSION, 2011 * -FDT_ERR_BADSTATE, 2012 * -FDT_ERR_BADSTRUCTURE, 2013 * -FDT_ERR_BADLAYOUT, 2014 * -FDT_ERR_TRUNCATED, standard meanings 2015 */ 2016 #define fdt_appendprop_string(fdt, nodeoffset, name, str) \ 2017 fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 2018 2019 /** 2020 * fdt_appendprop_addrrange - append a address range property 2021 * @fdt: pointer to the device tree blob 2022 * @parent: offset of the parent node 2023 * @nodeoffset: offset of the node to add a property at 2024 * @name: name of property 2025 * @addr: start address of a given range 2026 * @size: size of a given range 2027 * 2028 * fdt_appendprop_addrrange() appends an address range value (start 2029 * address and size) to the value of the named property in the given 2030 * node, or creates a new property with that value if it does not 2031 * already exist. 2032 * 2033 * Cell sizes are determined by parent's #address-cells and #size-cells. 2034 * 2035 * This function may insert data into the blob, and will therefore 2036 * change the offsets of some existing nodes. 2037 * 2038 * returns: 2039 * 0, on success 2040 * -FDT_ERR_BADLAYOUT, 2041 * -FDT_ERR_BADMAGIC, 2042 * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid 2043 * #address-cells property 2044 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2045 * -FDT_ERR_BADSTATE, 2046 * -FDT_ERR_BADSTRUCTURE, 2047 * -FDT_ERR_BADVERSION, 2048 * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size 2049 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to 2050 * contain a new property 2051 * -FDT_ERR_TRUNCATED, standard meanings 2052 */ 2053 int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, 2054 const char *name, uint64_t addr, uint64_t size); 2055 2056 /** 2057 * fdt_delprop - delete a property 2058 * @fdt: pointer to the device tree blob 2059 * @nodeoffset: offset of the node whose property to nop 2060 * @name: name of the property to nop 2061 * 2062 * fdt_del_property() will delete the given property. 2063 * 2064 * This function will delete data from the blob, and will therefore 2065 * change the offsets of some existing nodes. 2066 * 2067 * returns: 2068 * 0, on success 2069 * -FDT_ERR_NOTFOUND, node does not have the named property 2070 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2071 * -FDT_ERR_BADLAYOUT, 2072 * -FDT_ERR_BADMAGIC, 2073 * -FDT_ERR_BADVERSION, 2074 * -FDT_ERR_BADSTATE, 2075 * -FDT_ERR_BADSTRUCTURE, 2076 * -FDT_ERR_TRUNCATED, standard meanings 2077 */ 2078 int fdt_delprop(void *fdt, int nodeoffset, const char *name); 2079 2080 /** 2081 * fdt_add_subnode_namelen - creates a new node based on substring 2082 * @fdt: pointer to the device tree blob 2083 * @parentoffset: structure block offset of a node 2084 * @name: name of the subnode to create 2085 * @namelen: number of characters of name to consider 2086 * 2087 * Identical to fdt_add_subnode(), but use only the first @namelen 2088 * characters of @name as the name of the new node. This is useful for 2089 * creating subnodes based on a portion of a larger string, such as a 2090 * full path. 2091 * 2092 * Return: structure block offset of the created subnode (>=0), 2093 * negative libfdt error value otherwise 2094 */ 2095 #ifndef SWIG /* Not available in Python */ 2096 int fdt_add_subnode_namelen(void *fdt, int parentoffset, 2097 const char *name, int namelen); 2098 #endif 2099 2100 /** 2101 * fdt_add_subnode - creates a new node 2102 * @fdt: pointer to the device tree blob 2103 * @parentoffset: structure block offset of a node 2104 * @name: name of the subnode to locate 2105 * 2106 * fdt_add_subnode() creates a new node as a subnode of the node at 2107 * structure block offset parentoffset, with the given name (which 2108 * should include the unit address, if any). 2109 * 2110 * This function will insert data into the blob, and will therefore 2111 * change the offsets of some existing nodes. 2112 * 2113 * returns: 2114 * structure block offset of the created nodeequested subnode (>=0), on 2115 * success 2116 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist 2117 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE 2118 * tag 2119 * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of 2120 * the given name 2121 * -FDT_ERR_NOSPACE, if there is insufficient free space in the 2122 * blob to contain the new node 2123 * -FDT_ERR_NOSPACE 2124 * -FDT_ERR_BADLAYOUT 2125 * -FDT_ERR_BADMAGIC, 2126 * -FDT_ERR_BADVERSION, 2127 * -FDT_ERR_BADSTATE, 2128 * -FDT_ERR_BADSTRUCTURE, 2129 * -FDT_ERR_TRUNCATED, standard meanings. 2130 */ 2131 int fdt_add_subnode(void *fdt, int parentoffset, const char *name); 2132 2133 /** 2134 * fdt_del_node - delete a node (subtree) 2135 * @fdt: pointer to the device tree blob 2136 * @nodeoffset: offset of the node to nop 2137 * 2138 * fdt_del_node() will remove the given node, including all its 2139 * subnodes if any, from the blob. 2140 * 2141 * This function will delete data from the blob, and will therefore 2142 * change the offsets of some existing nodes. 2143 * 2144 * returns: 2145 * 0, on success 2146 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag 2147 * -FDT_ERR_BADLAYOUT, 2148 * -FDT_ERR_BADMAGIC, 2149 * -FDT_ERR_BADVERSION, 2150 * -FDT_ERR_BADSTATE, 2151 * -FDT_ERR_BADSTRUCTURE, 2152 * -FDT_ERR_TRUNCATED, standard meanings 2153 */ 2154 int fdt_del_node(void *fdt, int nodeoffset); 2155 2156 /** 2157 * fdt_overlay_apply - Applies a DT overlay on a base DT 2158 * @fdt: pointer to the base device tree blob 2159 * @fdto: pointer to the device tree overlay blob 2160 * 2161 * fdt_overlay_apply() will apply the given device tree overlay on the 2162 * given base device tree. 2163 * 2164 * Expect the base device tree to be modified, even if the function 2165 * returns an error. 2166 * 2167 * returns: 2168 * 0, on success 2169 * -FDT_ERR_NOSPACE, there's not enough space in the base device tree 2170 * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or 2171 * properties in the base DT 2172 * -FDT_ERR_BADPHANDLE, 2173 * -FDT_ERR_BADOVERLAY, 2174 * -FDT_ERR_NOPHANDLES, 2175 * -FDT_ERR_INTERNAL, 2176 * -FDT_ERR_BADLAYOUT, 2177 * -FDT_ERR_BADMAGIC, 2178 * -FDT_ERR_BADOFFSET, 2179 * -FDT_ERR_BADPATH, 2180 * -FDT_ERR_BADVERSION, 2181 * -FDT_ERR_BADSTRUCTURE, 2182 * -FDT_ERR_BADSTATE, 2183 * -FDT_ERR_TRUNCATED, standard meanings 2184 */ 2185 int fdt_overlay_apply(void *fdt, void *fdto); 2186 2187 /** 2188 * fdt_overlay_target_offset - retrieves the offset of a fragment's target 2189 * @fdt: Base device tree blob 2190 * @fdto: Device tree overlay blob 2191 * @fragment_offset: node offset of the fragment in the overlay 2192 * @pathp: pointer which receives the path of the target (or NULL) 2193 * 2194 * fdt_overlay_target_offset() retrieves the target offset in the base 2195 * device tree of a fragment, no matter how the actual targeting is 2196 * done (through a phandle or a path) 2197 * 2198 * returns: 2199 * the targeted node offset in the base device tree 2200 * Negative error code on error 2201 */ 2202 int fdt_overlay_target_offset(const void *fdt, const void *fdto, 2203 int fragment_offset, char const **pathp); 2204 2205 /**********************************************************************/ 2206 /* Debugging / informational functions */ 2207 /**********************************************************************/ 2208 2209 const char *fdt_strerror(int errval); 2210 2211 #ifdef __cplusplus 2212 } 2213 #endif 2214 2215 #endif /* LIBFDT_H */ 2216