1 1.1 skrll // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) 2 1.1 skrll /* 3 1.1 skrll * pylibfdt - Flat Device Tree manipulation in Python 4 1.1 skrll * Copyright (C) 2017 Google, Inc. 5 1.1 skrll * Written by Simon Glass <sjg (at) chromium.org> 6 1.1 skrll */ 7 1.1 skrll 8 1.1 skrll %module libfdt 9 1.1 skrll 10 1.1 skrll %include <stdint.i> 11 1.1 skrll 12 1.1 skrll %{ 13 1.1 skrll #define SWIG_FILE_WITH_INIT 14 1.1 skrll #include "libfdt.h" 15 1.1 skrll 16 1.1 skrll /* 17 1.1 skrll * We rename this function here to avoid problems with swig, since we also have 18 1.1 skrll * a struct called fdt_property. That struct causes swig to create a class in 19 1.1 skrll * libfdt.py called fdt_property(), which confuses things. 20 1.1 skrll */ 21 1.1 skrll static int fdt_property_stub(void *fdt, const char *name, const char *val, 22 1.1 skrll int len) 23 1.1 skrll { 24 1.1 skrll return fdt_property(fdt, name, val, len); 25 1.1 skrll } 26 1.1 skrll 27 1.1 skrll %} 28 1.1 skrll 29 1.1 skrll %pythoncode %{ 30 1.1 skrll 31 1.1 skrll import struct 32 1.1 skrll 33 1.1 skrll # Error codes, corresponding to FDT_ERR_... in libfdt.h 34 1.1 skrll (NOTFOUND, 35 1.1 skrll EXISTS, 36 1.1 skrll NOSPACE, 37 1.1 skrll BADOFFSET, 38 1.1 skrll BADPATH, 39 1.1 skrll BADPHANDLE, 40 1.1 skrll BADSTATE, 41 1.1 skrll TRUNCATED, 42 1.1 skrll BADMAGIC, 43 1.1 skrll BADVERSION, 44 1.1 skrll BADSTRUCTURE, 45 1.1 skrll BADLAYOUT, 46 1.1 skrll INTERNAL, 47 1.1 skrll BADNCELLS, 48 1.1 skrll BADVALUE, 49 1.1 skrll BADOVERLAY, 50 1.1 skrll NOPHANDLES) = QUIET_ALL = range(1, 18) 51 1.1 skrll # QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions 52 1.1 skrll # altogether. All # functions passed this value will return an error instead 53 1.1 skrll # of raising an exception. 54 1.1 skrll 55 1.1 skrll # Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors, 56 1.1 skrll # instead of raising an exception. 57 1.1 skrll QUIET_NOTFOUND = (NOTFOUND,) 58 1.1 skrll QUIET_NOSPACE = (NOSPACE,) 59 1.1 skrll 60 1.1 skrll 61 1.1 skrll class FdtException(Exception): 62 1.1 skrll """An exception caused by an error such as one of the codes above""" 63 1.1 skrll def __init__(self, err): 64 1.1 skrll self.err = err 65 1.1 skrll 66 1.1 skrll def __str__(self): 67 1.1 skrll return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err)) 68 1.1 skrll 69 1.1 skrll def strerror(fdt_err): 70 1.1 skrll """Get the string for an error number 71 1.1 skrll 72 1.1 skrll Args: 73 1.1 skrll fdt_err: Error number (-ve) 74 1.1 skrll 75 1.1 skrll Returns: 76 1.1 skrll String containing the associated error 77 1.1 skrll """ 78 1.1 skrll return fdt_strerror(fdt_err) 79 1.1 skrll 80 1.1 skrll def check_err(val, quiet=()): 81 1.1 skrll """Raise an error if the return value is -ve 82 1.1 skrll 83 1.1 skrll This is used to check for errors returned by libfdt C functions. 84 1.1 skrll 85 1.1 skrll Args: 86 1.1 skrll val: Return value from a libfdt function 87 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 88 1.1 skrll 89 1.1 skrll Returns: 90 1.1 skrll val if val >= 0 91 1.1 skrll 92 1.1 skrll Raises 93 1.1 skrll FdtException if val < 0 94 1.1 skrll """ 95 1.1 skrll if isinstance(val, int) and val < 0: 96 1.1 skrll if -val not in quiet: 97 1.1 skrll raise FdtException(val) 98 1.1 skrll return val 99 1.1 skrll 100 1.1 skrll def check_err_null(val, quiet=()): 101 1.1 skrll """Raise an error if the return value is NULL 102 1.1 skrll 103 1.1 skrll This is used to check for a NULL return value from certain libfdt C 104 1.1 skrll functions 105 1.1 skrll 106 1.1 skrll Args: 107 1.1 skrll val: Return value from a libfdt function 108 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 109 1.1 skrll 110 1.1 skrll Returns: 111 1.1 skrll val if val is a list, None if not 112 1.1 skrll 113 1.1 skrll Raises 114 1.1 skrll FdtException if val indicates an error was reported and the error 115 1.1 skrll is not in @quiet. 116 1.1 skrll """ 117 1.1 skrll # Normally a list is returned which contains the data and its length. 118 1.1 skrll # If we get just an integer error code, it means the function failed. 119 1.1 skrll if not isinstance(val, list): 120 1.1 skrll if -val not in quiet: 121 1.1 skrll raise FdtException(val) 122 1.1 skrll return val 123 1.1 skrll 124 1.1 skrll class FdtRo(object): 125 1.1 skrll """Class for a read-only device-tree 126 1.1 skrll 127 1.1 skrll This is a base class used by FdtRw (read-write access) and FdtSw 128 1.1 skrll (sequential-write access). It implements read-only access to the 129 1.1 skrll device tree. 130 1.1 skrll 131 1.1 skrll Here are the three classes and when you should use them: 132 1.1 skrll 133 1.1 skrll FdtRo - read-only access to an existing FDT 134 1.1 skrll FdtRw - read-write access to an existing FDT (most common case) 135 1.1 skrll FdtSw - for creating a new FDT, as well as allowing read-only access 136 1.1 skrll """ 137 1.1 skrll def __init__(self, data): 138 1.1 skrll self._fdt = bytearray(data) 139 1.1 skrll check_err(fdt_check_header(self._fdt)); 140 1.1 skrll 141 1.1 skrll def as_bytearray(self): 142 1.1 skrll """Get the device tree contents as a bytearray 143 1.1 skrll 144 1.1 skrll This can be passed directly to libfdt functions that access a 145 1.1 skrll const void * for the device tree. 146 1.1 skrll 147 1.1 skrll Returns: 148 1.1 skrll bytearray containing the device tree 149 1.1 skrll """ 150 1.1 skrll return bytearray(self._fdt) 151 1.1 skrll 152 1.1 skrll def next_node(self, nodeoffset, depth, quiet=()): 153 1.1 skrll """Find the next subnode 154 1.1 skrll 155 1.1 skrll Args: 156 1.1 skrll nodeoffset: Node offset of previous node 157 1.1 skrll depth: The depth of the node at nodeoffset. This is used to 158 1.1 skrll calculate the depth of the returned node 159 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 160 1.1 skrll 161 1.1 skrll Returns: 162 1.1 skrll Typle: 163 1.1 skrll Offset of the next node, if any, else a -ve error 164 1.1 skrll Depth of the returned node, if any, else undefined 165 1.1 skrll 166 1.1 skrll Raises: 167 1.1 skrll FdtException if no more nodes found or other error occurs 168 1.1 skrll """ 169 1.1 skrll return check_err(fdt_next_node(self._fdt, nodeoffset, depth), quiet) 170 1.1 skrll 171 1.1 skrll def first_subnode(self, nodeoffset, quiet=()): 172 1.1 skrll """Find the first subnode of a parent node 173 1.1 skrll 174 1.1 skrll Args: 175 1.1 skrll nodeoffset: Node offset of parent node 176 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 177 1.1 skrll 178 1.1 skrll Returns: 179 1.1 skrll The offset of the first subnode, if any 180 1.1 skrll 181 1.1 skrll Raises: 182 1.1 skrll FdtException if no subnodes found or other error occurs 183 1.1 skrll """ 184 1.1 skrll return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet) 185 1.1 skrll 186 1.1 skrll def next_subnode(self, nodeoffset, quiet=()): 187 1.1 skrll """Find the next subnode 188 1.1 skrll 189 1.1 skrll Args: 190 1.1 skrll nodeoffset: Node offset of previous subnode 191 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 192 1.1 skrll 193 1.1 skrll Returns: 194 1.1 skrll The offset of the next subnode, if any 195 1.1 skrll 196 1.1 skrll Raises: 197 1.1 skrll FdtException if no more subnodes found or other error occurs 198 1.1 skrll """ 199 1.1 skrll return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet) 200 1.1 skrll 201 1.1 skrll def magic(self): 202 1.1 skrll """Return the magic word from the header 203 1.1 skrll 204 1.1 skrll Returns: 205 1.1 skrll Magic word 206 1.1 skrll """ 207 1.1 skrll return fdt_magic(self._fdt) 208 1.1 skrll 209 1.1 skrll def totalsize(self): 210 1.1 skrll """Return the total size of the device tree 211 1.1 skrll 212 1.1 skrll Returns: 213 1.1 skrll Total tree size in bytes 214 1.1 skrll """ 215 1.1 skrll return fdt_totalsize(self._fdt) 216 1.1 skrll 217 1.1 skrll def off_dt_struct(self): 218 1.1 skrll """Return the start of the device-tree struct area 219 1.1 skrll 220 1.1 skrll Returns: 221 1.1 skrll Start offset of struct area 222 1.1 skrll """ 223 1.1 skrll return fdt_off_dt_struct(self._fdt) 224 1.1 skrll 225 1.1 skrll def off_dt_strings(self): 226 1.1 skrll """Return the start of the device-tree string area 227 1.1 skrll 228 1.1 skrll Returns: 229 1.1 skrll Start offset of string area 230 1.1 skrll """ 231 1.1 skrll return fdt_off_dt_strings(self._fdt) 232 1.1 skrll 233 1.1 skrll def off_mem_rsvmap(self): 234 1.1 skrll """Return the start of the memory reserve map 235 1.1 skrll 236 1.1 skrll Returns: 237 1.1 skrll Start offset of memory reserve map 238 1.1 skrll """ 239 1.1 skrll return fdt_off_mem_rsvmap(self._fdt) 240 1.1 skrll 241 1.1 skrll def version(self): 242 1.1 skrll """Return the version of the device tree 243 1.1 skrll 244 1.1 skrll Returns: 245 1.1 skrll Version number of the device tree 246 1.1 skrll """ 247 1.1 skrll return fdt_version(self._fdt) 248 1.1 skrll 249 1.1 skrll def last_comp_version(self): 250 1.1 skrll """Return the last compatible version of the device tree 251 1.1 skrll 252 1.1 skrll Returns: 253 1.1 skrll Last compatible version number of the device tree 254 1.1 skrll """ 255 1.1 skrll return fdt_last_comp_version(self._fdt) 256 1.1 skrll 257 1.1 skrll def boot_cpuid_phys(self): 258 1.1 skrll """Return the physical boot CPU ID 259 1.1 skrll 260 1.1 skrll Returns: 261 1.1 skrll Physical boot CPU ID 262 1.1 skrll """ 263 1.1 skrll return fdt_boot_cpuid_phys(self._fdt) 264 1.1 skrll 265 1.1 skrll def size_dt_strings(self): 266 1.1 skrll """Return the start of the device-tree string area 267 1.1 skrll 268 1.1 skrll Returns: 269 1.1 skrll Start offset of string area 270 1.1 skrll """ 271 1.1 skrll return fdt_size_dt_strings(self._fdt) 272 1.1 skrll 273 1.1 skrll def size_dt_struct(self): 274 1.1 skrll """Return the start of the device-tree struct area 275 1.1 skrll 276 1.1 skrll Returns: 277 1.1 skrll Start offset of struct area 278 1.1 skrll """ 279 1.1 skrll return fdt_size_dt_struct(self._fdt) 280 1.1 skrll 281 1.1 skrll def num_mem_rsv(self, quiet=()): 282 1.1 skrll """Return the number of memory reserve-map records 283 1.1 skrll 284 1.1 skrll Returns: 285 1.1 skrll Number of memory reserve-map records 286 1.1 skrll """ 287 1.1 skrll return check_err(fdt_num_mem_rsv(self._fdt), quiet) 288 1.1 skrll 289 1.1 skrll def get_mem_rsv(self, index, quiet=()): 290 1.1 skrll """Return the indexed memory reserve-map record 291 1.1 skrll 292 1.1 skrll Args: 293 1.1 skrll index: Record to return (0=first) 294 1.1 skrll 295 1.1 skrll Returns: 296 1.1 skrll Number of memory reserve-map records 297 1.1 skrll """ 298 1.1 skrll return check_err(fdt_get_mem_rsv(self._fdt, index), quiet) 299 1.1 skrll 300 1.1 skrll def subnode_offset(self, parentoffset, name, quiet=()): 301 1.1 skrll """Get the offset of a named subnode 302 1.1 skrll 303 1.1 skrll Args: 304 1.1 skrll parentoffset: Offset of the parent node to check 305 1.1 skrll name: Name of the required subnode, e.g. 'subnode@1' 306 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 307 1.1 skrll 308 1.1 skrll Returns: 309 1.1 skrll The node offset of the found node, if any 310 1.1 skrll 311 1.1 skrll Raises 312 1.1 skrll FdtException if there is no node with that name, or other error 313 1.1 skrll """ 314 1.1 skrll return check_err(fdt_subnode_offset(self._fdt, parentoffset, name), 315 1.1 skrll quiet) 316 1.1 skrll 317 1.1 skrll def path_offset(self, path, quiet=()): 318 1.1 skrll """Get the offset for a given path 319 1.1 skrll 320 1.1 skrll Args: 321 1.1 skrll path: Path to the required node, e.g. '/node@3/subnode@1' 322 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 323 1.1 skrll 324 1.1 skrll Returns: 325 1.1 skrll Node offset 326 1.1 skrll 327 1.1 skrll Raises 328 1.1 skrll FdtException if the path is not valid or not found 329 1.1 skrll """ 330 1.1 skrll return check_err(fdt_path_offset(self._fdt, path), quiet) 331 1.1 skrll 332 1.1 skrll def get_name(self, nodeoffset): 333 1.1 skrll """Get the name of a node 334 1.1 skrll 335 1.1 skrll Args: 336 1.1 skrll nodeoffset: Offset of node to check 337 1.1 skrll 338 1.1 skrll Returns: 339 1.1 skrll Node name 340 1.1 skrll 341 1.1 skrll Raises: 342 1.1 skrll FdtException on error (e.g. nodeoffset is invalid) 343 1.1 skrll """ 344 1.1 skrll return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0] 345 1.1 skrll 346 1.1 skrll def first_property_offset(self, nodeoffset, quiet=()): 347 1.1 skrll """Get the offset of the first property in a node offset 348 1.1 skrll 349 1.1 skrll Args: 350 1.1 skrll nodeoffset: Offset to the node to check 351 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 352 1.1 skrll 353 1.1 skrll Returns: 354 1.1 skrll Offset of the first property 355 1.1 skrll 356 1.1 skrll Raises 357 1.1 skrll FdtException if the associated node has no properties, or some 358 1.1 skrll other error occurred 359 1.1 skrll """ 360 1.1 skrll return check_err(fdt_first_property_offset(self._fdt, nodeoffset), 361 1.1 skrll quiet) 362 1.1 skrll 363 1.1 skrll def next_property_offset(self, prop_offset, quiet=()): 364 1.1 skrll """Get the next property in a node 365 1.1 skrll 366 1.1 skrll Args: 367 1.1 skrll prop_offset: Offset of the previous property 368 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 369 1.1 skrll 370 1.1 skrll Returns: 371 1.1 skrll Offset of the next property 372 1.1 skrll 373 1.1 skrll Raises: 374 1.1 skrll FdtException if the associated node has no more properties, or 375 1.1 skrll some other error occurred 376 1.1 skrll """ 377 1.1 skrll return check_err(fdt_next_property_offset(self._fdt, prop_offset), 378 1.1 skrll quiet) 379 1.1 skrll 380 1.1 skrll def get_property_by_offset(self, prop_offset, quiet=()): 381 1.1 skrll """Obtains a property that can be examined 382 1.1 skrll 383 1.1 skrll Args: 384 1.1 skrll prop_offset: Offset of property (e.g. from first_property_offset()) 385 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 386 1.1 skrll 387 1.1 skrll Returns: 388 1.1 skrll Property object, or None if not found 389 1.1 skrll 390 1.1 skrll Raises: 391 1.1 skrll FdtException on error (e.g. invalid prop_offset or device 392 1.1 skrll tree format) 393 1.1 skrll """ 394 1.1 skrll pdata = check_err_null( 395 1.1 skrll fdt_get_property_by_offset(self._fdt, prop_offset), quiet) 396 1.1 skrll if isinstance(pdata, (int)): 397 1.1 skrll return pdata 398 1.1 skrll return Property(pdata[0], pdata[1]) 399 1.1 skrll 400 1.1 skrll def getprop(self, nodeoffset, prop_name, quiet=()): 401 1.1 skrll """Get a property from a node 402 1.1 skrll 403 1.1 skrll Args: 404 1.1 skrll nodeoffset: Node offset containing property to get 405 1.1 skrll prop_name: Name of property to get 406 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 407 1.1 skrll 408 1.1 skrll Returns: 409 1.1 skrll Value of property as a Property object (which can be used as a 410 1.1 skrll bytearray/string), or -ve error number. On failure, returns an 411 1.1 skrll integer error 412 1.1 skrll 413 1.1 skrll Raises: 414 1.1 skrll FdtError if any error occurs (e.g. the property is not found) 415 1.1 skrll """ 416 1.1 skrll pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 417 1.1 skrll quiet) 418 1.1 skrll if isinstance(pdata, (int)): 419 1.1 skrll return pdata 420 1.1 skrll return Property(prop_name, bytearray(pdata[0])) 421 1.1 skrll 422 1.1 skrll def get_phandle(self, nodeoffset): 423 1.1 skrll """Get the phandle of a node 424 1.1 skrll 425 1.1 skrll Args: 426 1.1 skrll nodeoffset: Node offset to check 427 1.1 skrll 428 1.1 skrll Returns: 429 1.1 skrll phandle of node, or 0 if the node has no phandle or another error 430 1.1 skrll occurs 431 1.1 skrll """ 432 1.1 skrll return fdt_get_phandle(self._fdt, nodeoffset) 433 1.1 skrll 434 1.1 skrll def get_alias(self, name): 435 1.1 skrll """Get the full path referenced by a given alias 436 1.1 skrll 437 1.1 skrll Args: 438 1.1 skrll name: name of the alias to lookup 439 1.1 skrll 440 1.1 skrll Returns: 441 1.1 skrll Full path to the node for the alias named 'name', if it exists 442 1.1 skrll None, if the given alias or the /aliases node does not exist 443 1.1 skrll """ 444 1.1 skrll return fdt_get_alias(self._fdt, name) 445 1.1 skrll 446 1.1 skrll def parent_offset(self, nodeoffset, quiet=()): 447 1.1 skrll """Get the offset of a node's parent 448 1.1 skrll 449 1.1 skrll Args: 450 1.1 skrll nodeoffset: Node offset to check 451 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 452 1.1 skrll 453 1.1 skrll Returns: 454 1.1 skrll The offset of the parent node, if any 455 1.1 skrll 456 1.1 skrll Raises: 457 1.1 skrll FdtException if no parent found or other error occurs 458 1.1 skrll """ 459 1.1 skrll return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet) 460 1.1 skrll 461 1.1 skrll def node_offset_by_phandle(self, phandle, quiet=()): 462 1.1 skrll """Get the offset of a node with the given phandle 463 1.1 skrll 464 1.1 skrll Args: 465 1.1 skrll phandle: Phandle to search for 466 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 467 1.1 skrll 468 1.1 skrll Returns: 469 1.1 skrll The offset of node with that phandle, if any 470 1.1 skrll 471 1.1 skrll Raises: 472 1.1 skrll FdtException if no node found or other error occurs 473 1.1 skrll """ 474 1.1 skrll return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet) 475 1.1 skrll 476 1.1 skrll 477 1.1 skrll class Fdt(FdtRo): 478 1.1 skrll """Device tree class, supporting all operations 479 1.1 skrll 480 1.1 skrll The Fdt object is created is created from a device tree binary file, 481 1.1 skrll e.g. with something like: 482 1.1 skrll 483 1.1 skrll fdt = Fdt(open("filename.dtb").read()) 484 1.1 skrll 485 1.1 skrll Operations can then be performed using the methods in this class. Each 486 1.1 skrll method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...). 487 1.1 skrll 488 1.1 skrll All methods raise an FdtException if an error occurs. To avoid this 489 1.1 skrll behaviour a 'quiet' parameter is provided for some functions. This 490 1.1 skrll defaults to empty, but you can pass a list of errors that you expect. 491 1.1 skrll If one of these errors occurs, the function will return an error number 492 1.1 skrll (e.g. -NOTFOUND). 493 1.1 skrll """ 494 1.1 skrll def __init__(self, data): 495 1.1 skrll FdtRo.__init__(self, data) 496 1.1 skrll 497 1.1 skrll @staticmethod 498 1.1 skrll def create_empty_tree(size, quiet=()): 499 1.1 skrll """Create an empty device tree ready for use 500 1.1 skrll 501 1.1 skrll Args: 502 1.1 skrll size: Size of device tree in bytes 503 1.1 skrll 504 1.1 skrll Returns: 505 1.1 skrll Fdt object containing the device tree 506 1.1 skrll """ 507 1.1 skrll data = bytearray(size) 508 1.1 skrll err = check_err(fdt_create_empty_tree(data, size), quiet) 509 1.1 skrll if err: 510 1.1 skrll return err 511 1.1 skrll return Fdt(data) 512 1.1 skrll 513 1.1 skrll def resize(self, size, quiet=()): 514 1.1 skrll """Move the device tree into a larger or smaller space 515 1.1 skrll 516 1.1 skrll This creates a new device tree of size @size and moves the existing 517 1.1 skrll device tree contents over to that. It can be used to create more space 518 1.1 skrll in a device tree. Note that the Fdt object remains the same, but it 519 1.1 skrll now has a new bytearray holding the contents. 520 1.1 skrll 521 1.1 skrll Args: 522 1.1 skrll size: Required new size of device tree in bytes 523 1.1 skrll """ 524 1.1 skrll fdt = bytearray(size) 525 1.1 skrll err = check_err(fdt_open_into(self._fdt, fdt, size), quiet) 526 1.1 skrll if err: 527 1.1 skrll return err 528 1.1 skrll self._fdt = fdt 529 1.1 skrll 530 1.1 skrll def pack(self, quiet=()): 531 1.1 skrll """Pack the device tree to remove unused space 532 1.1 skrll 533 1.1 skrll This adjusts the tree in place. 534 1.1 skrll 535 1.1 skrll Args: 536 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 537 1.1 skrll 538 1.1 skrll Returns: 539 1.1 skrll Error code, or 0 if OK 540 1.1 skrll 541 1.1 skrll Raises: 542 1.1 skrll FdtException if any error occurs 543 1.1 skrll """ 544 1.1 skrll err = check_err(fdt_pack(self._fdt), quiet) 545 1.1 skrll if err: 546 1.1 skrll return err 547 1.1 skrll del self._fdt[self.totalsize():] 548 1.1 skrll return err 549 1.1 skrll 550 1.1 skrll def set_name(self, nodeoffset, name, quiet=()): 551 1.1 skrll """Set the name of a node 552 1.1 skrll 553 1.1 skrll Args: 554 1.1 skrll nodeoffset: Node offset of node to update 555 1.1 skrll name: New node name (string without \0) 556 1.1 skrll 557 1.1 skrll Returns: 558 1.1 skrll Error code, or 0 if OK 559 1.1 skrll 560 1.1 skrll Raises: 561 1.1 skrll FdtException if no parent found or other error occurs 562 1.1 skrll """ 563 1.1 skrll if chr(0) in name: 564 1.1 skrll raise ValueError('Property contains embedded nul characters') 565 1.1 skrll return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet) 566 1.1 skrll 567 1.1 skrll def setprop(self, nodeoffset, prop_name, val, quiet=()): 568 1.1 skrll """Set the value of a property 569 1.1 skrll 570 1.1 skrll Args: 571 1.1 skrll nodeoffset: Node offset containing the property to create/update 572 1.1 skrll prop_name: Name of property 573 1.1 skrll val: Value to write (string or bytearray) 574 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 575 1.1 skrll 576 1.1 skrll Returns: 577 1.1 skrll Error code, or 0 if OK 578 1.1 skrll 579 1.1 skrll Raises: 580 1.1 skrll FdtException if no parent found or other error occurs 581 1.1 skrll """ 582 1.1 skrll return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, 583 1.1 skrll len(val)), quiet) 584 1.1 skrll 585 1.1 skrll def setprop_u32(self, nodeoffset, prop_name, val, quiet=()): 586 1.1 skrll """Set the value of a property 587 1.1 skrll 588 1.1 skrll Args: 589 1.1 skrll nodeoffset: Node offset containing the property to create/update 590 1.1 skrll prop_name: Name of property 591 1.1 skrll val: Value to write (integer) 592 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 593 1.1 skrll 594 1.1 skrll Returns: 595 1.1 skrll Error code, or 0 if OK 596 1.1 skrll 597 1.1 skrll Raises: 598 1.1 skrll FdtException if no parent found or other error occurs 599 1.1 skrll """ 600 1.1 skrll return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val), 601 1.1 skrll quiet) 602 1.1 skrll 603 1.1 skrll def setprop_u64(self, nodeoffset, prop_name, val, quiet=()): 604 1.1 skrll """Set the value of a property 605 1.1 skrll 606 1.1 skrll Args: 607 1.1 skrll nodeoffset: Node offset containing the property to create/update 608 1.1 skrll prop_name: Name of property 609 1.1 skrll val: Value to write (integer) 610 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 611 1.1 skrll 612 1.1 skrll Returns: 613 1.1 skrll Error code, or 0 if OK 614 1.1 skrll 615 1.1 skrll Raises: 616 1.1 skrll FdtException if no parent found or other error occurs 617 1.1 skrll """ 618 1.1 skrll return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), 619 1.1 skrll quiet) 620 1.1 skrll 621 1.1 skrll def setprop_str(self, nodeoffset, prop_name, val, quiet=()): 622 1.1 skrll """Set the string value of a property 623 1.1 skrll 624 1.1 skrll The property is set to the string, with a nul terminator added 625 1.1 skrll 626 1.1 skrll Args: 627 1.1 skrll nodeoffset: Node offset containing the property to create/update 628 1.1 skrll prop_name: Name of property 629 1.1 skrll val: Value to write (string without nul terminator). Unicode is 630 1.1 skrll supposed by encoding to UTF-8 631 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 632 1.1 skrll 633 1.1 skrll Returns: 634 1.1 skrll Error code, or 0 if OK 635 1.1 skrll 636 1.1 skrll Raises: 637 1.1 skrll FdtException if no parent found or other error occurs 638 1.1 skrll """ 639 1.1 skrll val = val.encode('utf-8') + b'\0' 640 1.1 skrll return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, 641 1.1 skrll val, len(val)), quiet) 642 1.1 skrll 643 1.1 skrll def delprop(self, nodeoffset, prop_name, quiet=()): 644 1.1 skrll """Delete a property from a node 645 1.1 skrll 646 1.1 skrll Args: 647 1.1 skrll nodeoffset: Node offset containing property to delete 648 1.1 skrll prop_name: Name of property to delete 649 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 650 1.1 skrll 651 1.1 skrll Returns: 652 1.1 skrll Error code, or 0 if OK 653 1.1 skrll 654 1.1 skrll Raises: 655 1.1 skrll FdtError if the property does not exist, or another error occurs 656 1.1 skrll """ 657 1.1 skrll return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name), quiet) 658 1.1 skrll 659 1.1 skrll def add_subnode(self, parentoffset, name, quiet=()): 660 1.1 skrll """Add a new subnode to a node 661 1.1 skrll 662 1.1 skrll Args: 663 1.1 skrll parentoffset: Parent offset to add the subnode to 664 1.1 skrll name: Name of node to add 665 1.1 skrll 666 1.1 skrll Returns: 667 1.1 skrll offset of the node created, or negative error code on failure 668 1.1 skrll 669 1.1 skrll Raises: 670 1.1 skrll FdtError if there is not enough space, or another error occurs 671 1.1 skrll """ 672 1.1 skrll return check_err(fdt_add_subnode(self._fdt, parentoffset, name), quiet) 673 1.1 skrll 674 1.1 skrll def del_node(self, nodeoffset, quiet=()): 675 1.1 skrll """Delete a node 676 1.1 skrll 677 1.1 skrll Args: 678 1.1 skrll nodeoffset: Offset of node to delete 679 1.1 skrll 680 1.1 skrll Returns: 681 1.1 skrll Error code, or 0 if OK 682 1.1 skrll 683 1.1 skrll Raises: 684 1.1 skrll FdtError if an error occurs 685 1.1 skrll """ 686 1.1 skrll return check_err(fdt_del_node(self._fdt, nodeoffset), quiet) 687 1.1 skrll 688 1.1 skrll 689 1.1 skrll class Property(bytearray): 690 1.1 skrll """Holds a device tree property name and value. 691 1.1 skrll 692 1.1 skrll This holds a copy of a property taken from the device tree. It does not 693 1.1 skrll reference the device tree, so if anything changes in the device tree, 694 1.1 skrll a Property object will remain valid. 695 1.1 skrll 696 1.1 skrll Properties: 697 1.1 skrll name: Property name 698 1.1 skrll value: Property value as a bytearray 699 1.1 skrll """ 700 1.1 skrll def __init__(self, name, value): 701 1.1 skrll bytearray.__init__(self, value) 702 1.1 skrll self.name = name 703 1.1 skrll 704 1.1 skrll def as_cell(self, fmt): 705 1.1 skrll return struct.unpack('>' + fmt, self)[0] 706 1.1 skrll 707 1.1 skrll def as_uint32(self): 708 1.1 skrll return self.as_cell('L') 709 1.1 skrll 710 1.1 skrll def as_int32(self): 711 1.1 skrll return self.as_cell('l') 712 1.1 skrll 713 1.1 skrll def as_uint64(self): 714 1.1 skrll return self.as_cell('Q') 715 1.1 skrll 716 1.1 skrll def as_int64(self): 717 1.1 skrll return self.as_cell('q') 718 1.1 skrll 719 1.1 skrll def as_str(self): 720 1.1 skrll """Unicode is supported by decoding from UTF-8""" 721 1.1 skrll if self[-1] != 0: 722 1.1 skrll raise ValueError('Property lacks nul termination') 723 1.1 skrll if 0 in self[:-1]: 724 1.1 skrll raise ValueError('Property contains embedded nul characters') 725 1.1 skrll return self[:-1].decode('utf-8') 726 1.1 skrll 727 1.1 skrll 728 1.1 skrll class FdtSw(FdtRo): 729 1.1 skrll """Software interface to create a device tree from scratch 730 1.1 skrll 731 1.1 skrll The methods in this class work by adding to an existing 'partial' device 732 1.1 skrll tree buffer of a fixed size created by instantiating this class. When the 733 1.1 skrll tree is complete, call as_fdt() to obtain a device tree ready to be used. 734 1.1 skrll 735 1.1 skrll Similarly with nodes, a new node is started with begin_node() and finished 736 1.1 skrll with end_node(). 737 1.1 skrll 738 1.1 skrll The context manager functions can be used to make this a bit easier: 739 1.1 skrll 740 1.1 skrll # First create the device tree with a node and property: 741 1.1 skrll sw = FdtSw() 742 1.1 skrll sw.finish_reservemap() 743 1.1 skrll with sw.add_node(''): 744 1.1 skrll with sw.add_node('node'): 745 1.1 skrll sw.property_u32('reg', 2) 746 1.1 skrll fdt = sw.as_fdt() 747 1.1 skrll 748 1.1 skrll # Now we can use it as a real device tree 749 1.1 skrll fdt.setprop_u32(0, 'reg', 3) 750 1.1 skrll 751 1.1 skrll The size hint provides a starting size for the space to be used by the 752 1.1 skrll device tree. This will be increased automatically as needed as new items 753 1.1 skrll are added to the tree. 754 1.1 skrll """ 755 1.1 skrll INC_SIZE = 1024 # Expand size by this much when out of space 756 1.1 skrll 757 1.1 skrll def __init__(self, size_hint=None): 758 1.1 skrll """Create a new FdtSw object 759 1.1 skrll 760 1.1 skrll Args: 761 1.1 skrll size_hint: A hint as to the initial size to use 762 1.1 skrll 763 1.1 skrll Raises: 764 1.1 skrll ValueError if size_hint is negative 765 1.1 skrll 766 1.1 skrll Returns: 767 1.1 skrll FdtSw object on success, else integer error code (if not raising) 768 1.1 skrll """ 769 1.1 skrll if not size_hint: 770 1.1 skrll size_hint = self.INC_SIZE 771 1.1 skrll fdtsw = bytearray(size_hint) 772 1.1 skrll err = check_err(fdt_create(fdtsw, size_hint)) 773 1.1 skrll if err: 774 1.1 skrll return err 775 1.1 skrll self._fdt = fdtsw 776 1.1 skrll 777 1.1 skrll def as_fdt(self): 778 1.1 skrll """Convert a FdtSw into an Fdt so it can be accessed as normal 779 1.1 skrll 780 1.1 skrll Creates a new Fdt object from the work-in-progress device tree. This 781 1.1 skrll does not call fdt_finish() on the current object, so it is possible to 782 1.1 skrll add more nodes/properties and call as_fdt() again to get an updated 783 1.1 skrll tree. 784 1.1 skrll 785 1.1 skrll Returns: 786 1.1 skrll Fdt object allowing access to the newly created device tree 787 1.1 skrll """ 788 1.1 skrll fdtsw = bytearray(self._fdt) 789 1.1 skrll check_err(fdt_finish(fdtsw)) 790 1.1 skrll return Fdt(fdtsw) 791 1.1 skrll 792 1.1 skrll def check_space(self, val): 793 1.1 skrll """Check if we need to add more space to the FDT 794 1.1 skrll 795 1.1 skrll This should be called with the error code from an operation. If this is 796 1.1 skrll -NOSPACE then the FDT will be expanded to have more space, and True will 797 1.1 skrll be returned, indicating that the operation needs to be tried again. 798 1.1 skrll 799 1.1 skrll Args: 800 1.1 skrll val: Return value from the operation that was attempted 801 1.1 skrll 802 1.1 skrll Returns: 803 1.1 skrll True if the operation must be retried, else False 804 1.1 skrll """ 805 1.1 skrll if check_err(val, QUIET_NOSPACE) < 0: 806 1.1 skrll self.resize(len(self._fdt) + self.INC_SIZE) 807 1.1 skrll return True 808 1.1 skrll return False 809 1.1 skrll 810 1.1 skrll def resize(self, size): 811 1.1 skrll """Resize the buffer to accommodate a larger tree 812 1.1 skrll 813 1.1 skrll Args: 814 1.1 skrll size: New size of tree 815 1.1 skrll 816 1.1 skrll Raises: 817 1.1 skrll FdtException on any error 818 1.1 skrll """ 819 1.1 skrll fdt = bytearray(size) 820 1.1 skrll err = check_err(fdt_resize(self._fdt, fdt, size)) 821 1.1 skrll self._fdt = fdt 822 1.1 skrll 823 1.1 skrll def add_reservemap_entry(self, addr, size): 824 1.1 skrll """Add a new memory reserve map entry 825 1.1 skrll 826 1.1 skrll Once finished adding, you must call finish_reservemap(). 827 1.1 skrll 828 1.1 skrll Args: 829 1.1 skrll addr: 64-bit start address 830 1.1 skrll size: 64-bit size 831 1.1 skrll 832 1.1 skrll Raises: 833 1.1 skrll FdtException on any error 834 1.1 skrll """ 835 1.1 skrll while self.check_space(fdt_add_reservemap_entry(self._fdt, addr, 836 1.1 skrll size)): 837 1.1 skrll pass 838 1.1 skrll 839 1.1 skrll def finish_reservemap(self): 840 1.1 skrll """Indicate that there are no more reserve map entries to add 841 1.1 skrll 842 1.1 skrll Raises: 843 1.1 skrll FdtException on any error 844 1.1 skrll """ 845 1.1 skrll while self.check_space(fdt_finish_reservemap(self._fdt)): 846 1.1 skrll pass 847 1.1 skrll 848 1.1 skrll def begin_node(self, name): 849 1.1 skrll """Begin a new node 850 1.1 skrll 851 1.1 skrll Use this before adding properties to the node. Then call end_node() to 852 1.1 skrll finish it. You can also use the context manager as shown in the FdtSw 853 1.1 skrll class comment. 854 1.1 skrll 855 1.1 skrll Args: 856 1.1 skrll name: Name of node to begin 857 1.1 skrll 858 1.1 skrll Raises: 859 1.1 skrll FdtException on any error 860 1.1 skrll """ 861 1.1 skrll while self.check_space(fdt_begin_node(self._fdt, name)): 862 1.1 skrll pass 863 1.1 skrll 864 1.1 skrll def property_string(self, name, string): 865 1.1 skrll """Add a property with a string value 866 1.1 skrll 867 1.1 skrll The string will be nul-terminated when written to the device tree 868 1.1 skrll 869 1.1 skrll Args: 870 1.1 skrll name: Name of property to add 871 1.1 skrll string: String value of property 872 1.1 skrll 873 1.1 skrll Raises: 874 1.1 skrll FdtException on any error 875 1.1 skrll """ 876 1.1 skrll while self.check_space(fdt_property_string(self._fdt, name, string)): 877 1.1 skrll pass 878 1.1 skrll 879 1.1 skrll def property_u32(self, name, val): 880 1.1 skrll """Add a property with a 32-bit value 881 1.1 skrll 882 1.1 skrll Write a single-cell value to the device tree 883 1.1 skrll 884 1.1 skrll Args: 885 1.1 skrll name: Name of property to add 886 1.1 skrll val: Value of property 887 1.1 skrll 888 1.1 skrll Raises: 889 1.1 skrll FdtException on any error 890 1.1 skrll """ 891 1.1 skrll while self.check_space(fdt_property_u32(self._fdt, name, val)): 892 1.1 skrll pass 893 1.1 skrll 894 1.1 skrll def property_u64(self, name, val): 895 1.1 skrll """Add a property with a 64-bit value 896 1.1 skrll 897 1.1 skrll Write a double-cell value to the device tree in big-endian format 898 1.1 skrll 899 1.1 skrll Args: 900 1.1 skrll name: Name of property to add 901 1.1 skrll val: Value of property 902 1.1 skrll 903 1.1 skrll Raises: 904 1.1 skrll FdtException on any error 905 1.1 skrll """ 906 1.1 skrll while self.check_space(fdt_property_u64(self._fdt, name, val)): 907 1.1 skrll pass 908 1.1 skrll 909 1.1 skrll def property_cell(self, name, val): 910 1.1 skrll """Add a property with a single-cell value 911 1.1 skrll 912 1.1 skrll Write a single-cell value to the device tree 913 1.1 skrll 914 1.1 skrll Args: 915 1.1 skrll name: Name of property to add 916 1.1 skrll val: Value of property 917 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 918 1.1 skrll 919 1.1 skrll Raises: 920 1.1 skrll FdtException on any error 921 1.1 skrll """ 922 1.1 skrll while self.check_space(fdt_property_cell(self._fdt, name, val)): 923 1.1 skrll pass 924 1.1 skrll 925 1.1 skrll def property(self, name, val): 926 1.1 skrll """Add a property 927 1.1 skrll 928 1.1 skrll Write a new property with the given value to the device tree. The value 929 1.1 skrll is taken as is and is not nul-terminated 930 1.1 skrll 931 1.1 skrll Args: 932 1.1 skrll name: Name of property to add 933 1.1 skrll val: Value of property 934 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 935 1.1 skrll 936 1.1 skrll Raises: 937 1.1 skrll FdtException on any error 938 1.1 skrll """ 939 1.1 skrll while self.check_space(fdt_property_stub(self._fdt, name, val, 940 1.1 skrll len(val))): 941 1.1 skrll pass 942 1.1 skrll 943 1.1 skrll def end_node(self): 944 1.1 skrll """End a node 945 1.1 skrll 946 1.1 skrll Use this after adding properties to a node to close it off. You can also 947 1.1 skrll use the context manager as shown in the FdtSw class comment. 948 1.1 skrll 949 1.1 skrll Args: 950 1.1 skrll quiet: Errors to ignore (empty to raise on all errors) 951 1.1 skrll 952 1.1 skrll Raises: 953 1.1 skrll FdtException on any error 954 1.1 skrll """ 955 1.1 skrll while self.check_space(fdt_end_node(self._fdt)): 956 1.1 skrll pass 957 1.1 skrll 958 1.1 skrll def add_node(self, name): 959 1.1 skrll """Create a new context for adding a node 960 1.1 skrll 961 1.1 skrll When used in a 'with' clause this starts a new node and finishes it 962 1.1 skrll afterward. 963 1.1 skrll 964 1.1 skrll Args: 965 1.1 skrll name: Name of node to add 966 1.1 skrll """ 967 1.1 skrll return NodeAdder(self, name) 968 1.1 skrll 969 1.1 skrll 970 1.1 skrll class NodeAdder(): 971 1.1 skrll """Class to provide a node context 972 1.1 skrll 973 1.1 skrll This allows you to add nodes in a more natural way: 974 1.1 skrll 975 1.1 skrll with fdtsw.add_node('name'): 976 1.1 skrll fdtsw.property_string('test', 'value') 977 1.1 skrll 978 1.1 skrll The node is automatically completed with a call to end_node() when the 979 1.1 skrll context exits. 980 1.1 skrll """ 981 1.1 skrll def __init__(self, fdtsw, name): 982 1.1 skrll self._fdt = fdtsw 983 1.1 skrll self._name = name 984 1.1 skrll 985 1.1 skrll def __enter__(self): 986 1.1 skrll self._fdt.begin_node(self._name) 987 1.1 skrll 988 1.1 skrll def __exit__(self, type, value, traceback): 989 1.1 skrll self._fdt.end_node() 990 1.1 skrll %} 991 1.1 skrll 992 1.1 skrll %rename(fdt_property) fdt_property_func; 993 1.1 skrll 994 1.1 skrll /* 995 1.1 skrll * fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h 996 1.1 skrll * so use the same type here. 997 1.1 skrll */ 998 1.1 skrll typedef uint32_t fdt32_t; 999 1.1 skrll 1000 1.1 skrll %include "fdt.h" 1001 1.1 skrll 1002 1.1 skrll %include "typemaps.i" 1003 1.1 skrll 1004 1.1 skrll /* Most functions don't change the device tree, so use a const void * */ 1005 1.1 skrll %typemap(in) (const void *)(const void *fdt) { 1006 1.1 skrll if (!PyByteArray_Check($input)) { 1007 1.1 skrll SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 1008 1.1 skrll "', argument " "$argnum"" of type '" "$type""'"); 1009 1.1 skrll } 1010 1.1 skrll $1 = (void *)PyByteArray_AsString($input); 1011 1.1 skrll fdt = $1; 1012 1.1 skrll fdt = fdt; /* avoid unused variable warning */ 1013 1.1 skrll } 1014 1.1 skrll 1015 1.1 skrll /* Some functions do change the device tree, so use void * */ 1016 1.1 skrll %typemap(in) (void *)(const void *fdt) { 1017 1.1 skrll if (!PyByteArray_Check($input)) { 1018 1.1 skrll SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 1019 1.1 skrll "', argument " "$argnum"" of type '" "$type""'"); 1020 1.1 skrll } 1021 1.1 skrll $1 = PyByteArray_AsString($input); 1022 1.1 skrll fdt = $1; 1023 1.1 skrll fdt = fdt; /* avoid unused variable warning */ 1024 1.1 skrll } 1025 1.1 skrll 1026 1.1 skrll /* typemap used for fdt_get_property_by_offset() */ 1027 1.1 skrll %typemap(out) (struct fdt_property *) { 1028 1.1 skrll PyObject *buff; 1029 1.1 skrll 1030 1.1 skrll if ($1) { 1031 1.1 skrll resultobj = PyString_FromString( 1032 1.1 skrll fdt_string(fdt1, fdt32_to_cpu($1->nameoff))); 1033 1.1 skrll buff = PyByteArray_FromStringAndSize( 1034 1.1 skrll (const char *)($1 + 1), fdt32_to_cpu($1->len)); 1035 1.1 skrll resultobj = SWIG_Python_AppendOutput(resultobj, buff); 1036 1.1 skrll } 1037 1.1 skrll } 1038 1.1 skrll 1039 1.1 skrll %apply int *OUTPUT { int *lenp }; 1040 1.1 skrll 1041 1.1 skrll /* typemap used for fdt_getprop() */ 1042 1.1 skrll %typemap(out) (const void *) { 1043 1.1 skrll if (!$1) 1044 1.1 skrll $result = Py_None; 1045 1.1 skrll else 1046 1.1 skrll %#if PY_VERSION_HEX >= 0x03000000 1047 1.1 skrll $result = Py_BuildValue("y#", $1, *arg4); 1048 1.1 skrll %#else 1049 1.1 skrll $result = Py_BuildValue("s#", $1, *arg4); 1050 1.1 skrll %#endif 1051 1.1 skrll } 1052 1.1 skrll 1053 1.1 skrll /* typemap used for fdt_setprop() */ 1054 1.1 skrll %typemap(in) (const void *val) { 1055 1.1 skrll %#if PY_VERSION_HEX >= 0x03000000 1056 1.1 skrll if (!PyBytes_Check($input)) { 1057 1.1 skrll SWIG_exception_fail(SWIG_TypeError, "bytes expected in method '" "$symname" 1058 1.1 skrll "', argument " "$argnum"" of type '" "$type""'"); 1059 1.1 skrll } 1060 1.1 skrll $1 = PyBytes_AsString($input); 1061 1.1 skrll %#else 1062 1.1 skrll $1 = PyString_AsString($input); /* char *str */ 1063 1.1 skrll %#endif 1064 1.1 skrll } 1065 1.1 skrll 1066 1.1 skrll /* typemaps used for fdt_next_node() */ 1067 1.1 skrll %typemap(in, numinputs=1) int *depth (int depth) { 1068 1.1 skrll depth = (int) PyInt_AsLong($input); 1069 1.1 skrll $1 = &depth; 1070 1.1 skrll } 1071 1.1 skrll 1072 1.1 skrll %typemap(argout) int *depth { 1073 1.1 skrll PyObject *val = Py_BuildValue("i", *arg$argnum); 1074 1.1 skrll resultobj = SWIG_Python_AppendOutput(resultobj, val); 1075 1.1 skrll } 1076 1.1 skrll 1077 1.1 skrll %apply int *depth { int *depth }; 1078 1.1 skrll 1079 1.1 skrll /* typemaps for fdt_get_mem_rsv */ 1080 1.1 skrll %typemap(in, numinputs=0) uint64_t * (uint64_t temp) { 1081 1.1 skrll $1 = &temp; 1082 1.1 skrll } 1083 1.1 skrll 1084 1.1 skrll %typemap(argout) uint64_t * { 1085 1.1 skrll PyObject *val = PyLong_FromUnsignedLongLong(*arg$argnum); 1086 1.1 skrll if (!result) { 1087 1.1 skrll if (PyTuple_GET_SIZE(resultobj) == 0) 1088 1.1 skrll resultobj = val; 1089 1.1 skrll else 1090 1.1 skrll resultobj = SWIG_Python_AppendOutput(resultobj, val); 1091 1.1 skrll } 1092 1.1 skrll } 1093 1.1 skrll 1094 1.1 skrll /* We have both struct fdt_property and a function fdt_property() */ 1095 1.1 skrll %warnfilter(302) fdt_property; 1096 1.1 skrll 1097 1.1 skrll /* These are macros in the header so have to be redefined here */ 1098 1.1 skrll uint32_t fdt_magic(const void *fdt); 1099 1.1 skrll uint32_t fdt_totalsize(const void *fdt); 1100 1.1 skrll uint32_t fdt_off_dt_struct(const void *fdt); 1101 1.1 skrll uint32_t fdt_off_dt_strings(const void *fdt); 1102 1.1 skrll uint32_t fdt_off_mem_rsvmap(const void *fdt); 1103 1.1 skrll uint32_t fdt_version(const void *fdt); 1104 1.1 skrll uint32_t fdt_last_comp_version(const void *fdt); 1105 1.1 skrll uint32_t fdt_boot_cpuid_phys(const void *fdt); 1106 1.1 skrll uint32_t fdt_size_dt_strings(const void *fdt); 1107 1.1 skrll uint32_t fdt_size_dt_struct(const void *fdt); 1108 1.1 skrll 1109 1.1 skrll int fdt_property_string(void *fdt, const char *name, const char *val); 1110 1.1 skrll int fdt_property_cell(void *fdt, const char *name, uint32_t val); 1111 1.1 skrll 1112 1.1 skrll /* 1113 1.1 skrll * This function has a stub since the name fdt_property is used for both a 1114 1.1 skrll * function and a struct, which confuses SWIG. 1115 1.1 skrll */ 1116 1.1 skrll int fdt_property_stub(void *fdt, const char *name, const char *val, int len); 1117 1.1 skrll 1118 1.1 skrll %include <libfdt.h> 1119