14549e789STom Rini/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ 215b97f5cSMasahiro Yamada/* 315b97f5cSMasahiro Yamada * pylibfdt - Flat Device Tree manipulation in Python 415b97f5cSMasahiro Yamada * Copyright (C) 2017 Google, Inc. 515b97f5cSMasahiro Yamada * Written by Simon Glass <sjg@chromium.org> 615b97f5cSMasahiro Yamada */ 715b97f5cSMasahiro Yamada 815b97f5cSMasahiro Yamada%module libfdt 915b97f5cSMasahiro Yamada 1015b97f5cSMasahiro Yamada%include <stdint.i> 1115b97f5cSMasahiro Yamada 1215b97f5cSMasahiro Yamada%{ 1315b97f5cSMasahiro Yamada#define SWIG_FILE_WITH_INIT 1415b97f5cSMasahiro Yamada#include "libfdt.h" 15*3def0cf2SSimon Glass 16*3def0cf2SSimon Glass/* 17*3def0cf2SSimon Glass * We rename this function here to avoid problems with swig, since we also have 18*3def0cf2SSimon Glass * a struct called fdt_property. That struct causes swig to create a class in 19*3def0cf2SSimon Glass * libfdt.py called fdt_property(), which confuses things. 20*3def0cf2SSimon Glass */ 21*3def0cf2SSimon Glassstatic int _fdt_property(void *fdt, const char *name, const char *val, int len) 22*3def0cf2SSimon Glass{ 23*3def0cf2SSimon Glass return fdt_property(fdt, name, val, len); 24*3def0cf2SSimon Glass} 25*3def0cf2SSimon Glass 2615b97f5cSMasahiro Yamada%} 2715b97f5cSMasahiro Yamada 2815b97f5cSMasahiro Yamada%pythoncode %{ 2915b97f5cSMasahiro Yamada 3015b97f5cSMasahiro Yamadaimport struct 3115b97f5cSMasahiro Yamada 3215b97f5cSMasahiro Yamada# Error codes, corresponding to FDT_ERR_... in libfdt.h 3315b97f5cSMasahiro Yamada(NOTFOUND, 3415b97f5cSMasahiro Yamada EXISTS, 3515b97f5cSMasahiro Yamada NOSPACE, 3615b97f5cSMasahiro Yamada BADOFFSET, 3715b97f5cSMasahiro Yamada BADPATH, 3815b97f5cSMasahiro Yamada BADPHANDLE, 3915b97f5cSMasahiro Yamada BADSTATE, 4015b97f5cSMasahiro Yamada TRUNCATED, 4115b97f5cSMasahiro Yamada BADMAGIC, 4215b97f5cSMasahiro Yamada BADVERSION, 4315b97f5cSMasahiro Yamada BADSTRUCTURE, 4415b97f5cSMasahiro Yamada BADLAYOUT, 4515b97f5cSMasahiro Yamada INTERNAL, 4615b97f5cSMasahiro Yamada BADNCELLS, 4715b97f5cSMasahiro Yamada BADVALUE, 4815b97f5cSMasahiro Yamada BADOVERLAY, 4915b97f5cSMasahiro Yamada NOPHANDLES) = QUIET_ALL = range(1, 18) 5015b97f5cSMasahiro Yamada# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions 5115b97f5cSMasahiro Yamada# altogether. All # functions passed this value will return an error instead 5215b97f5cSMasahiro Yamada# of raising an exception. 5315b97f5cSMasahiro Yamada 5415b97f5cSMasahiro Yamada# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors, 5515b97f5cSMasahiro Yamada# instead of raising an exception. 5615b97f5cSMasahiro YamadaQUIET_NOTFOUND = (NOTFOUND,) 5715b97f5cSMasahiro Yamada 5815b97f5cSMasahiro Yamada 5915b97f5cSMasahiro Yamadaclass FdtException(Exception): 6015b97f5cSMasahiro Yamada """An exception caused by an error such as one of the codes above""" 6115b97f5cSMasahiro Yamada def __init__(self, err): 6215b97f5cSMasahiro Yamada self.err = err 6315b97f5cSMasahiro Yamada 6415b97f5cSMasahiro Yamada def __str__(self): 6515b97f5cSMasahiro Yamada return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err)) 6615b97f5cSMasahiro Yamada 6715b97f5cSMasahiro Yamadadef strerror(fdt_err): 6815b97f5cSMasahiro Yamada """Get the string for an error number 6915b97f5cSMasahiro Yamada 7015b97f5cSMasahiro Yamada Args: 7115b97f5cSMasahiro Yamada fdt_err: Error number (-ve) 7215b97f5cSMasahiro Yamada 7315b97f5cSMasahiro Yamada Returns: 7415b97f5cSMasahiro Yamada String containing the associated error 7515b97f5cSMasahiro Yamada """ 7615b97f5cSMasahiro Yamada return fdt_strerror(fdt_err) 7715b97f5cSMasahiro Yamada 7815b97f5cSMasahiro Yamadadef check_err(val, quiet=()): 7915b97f5cSMasahiro Yamada """Raise an error if the return value is -ve 8015b97f5cSMasahiro Yamada 8115b97f5cSMasahiro Yamada This is used to check for errors returned by libfdt C functions. 8215b97f5cSMasahiro Yamada 8315b97f5cSMasahiro Yamada Args: 8415b97f5cSMasahiro Yamada val: Return value from a libfdt function 8515b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 8615b97f5cSMasahiro Yamada 8715b97f5cSMasahiro Yamada Returns: 8815b97f5cSMasahiro Yamada val if val >= 0 8915b97f5cSMasahiro Yamada 9015b97f5cSMasahiro Yamada Raises 9115b97f5cSMasahiro Yamada FdtException if val < 0 9215b97f5cSMasahiro Yamada """ 9315b97f5cSMasahiro Yamada if val < 0: 9415b97f5cSMasahiro Yamada if -val not in quiet: 9515b97f5cSMasahiro Yamada raise FdtException(val) 9615b97f5cSMasahiro Yamada return val 9715b97f5cSMasahiro Yamada 9815b97f5cSMasahiro Yamadadef check_err_null(val, quiet=()): 9915b97f5cSMasahiro Yamada """Raise an error if the return value is NULL 10015b97f5cSMasahiro Yamada 10115b97f5cSMasahiro Yamada This is used to check for a NULL return value from certain libfdt C 10215b97f5cSMasahiro Yamada functions 10315b97f5cSMasahiro Yamada 10415b97f5cSMasahiro Yamada Args: 10515b97f5cSMasahiro Yamada val: Return value from a libfdt function 10615b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 10715b97f5cSMasahiro Yamada 10815b97f5cSMasahiro Yamada Returns: 10915b97f5cSMasahiro Yamada val if val is a list, None if not 11015b97f5cSMasahiro Yamada 11115b97f5cSMasahiro Yamada Raises 11215b97f5cSMasahiro Yamada FdtException if val indicates an error was reported and the error 11315b97f5cSMasahiro Yamada is not in @quiet. 11415b97f5cSMasahiro Yamada """ 11515b97f5cSMasahiro Yamada # Normally a list is returned which contains the data and its length. 11615b97f5cSMasahiro Yamada # If we get just an integer error code, it means the function failed. 11715b97f5cSMasahiro Yamada if not isinstance(val, list): 11815b97f5cSMasahiro Yamada if -val not in quiet: 11915b97f5cSMasahiro Yamada raise FdtException(val) 12015b97f5cSMasahiro Yamada return val 12115b97f5cSMasahiro Yamada 122*3def0cf2SSimon Glass 12315b97f5cSMasahiro Yamadaclass Fdt: 12415b97f5cSMasahiro Yamada """Device tree class, supporting all operations 12515b97f5cSMasahiro Yamada 12615b97f5cSMasahiro Yamada The Fdt object is created is created from a device tree binary file, 12715b97f5cSMasahiro Yamada e.g. with something like: 12815b97f5cSMasahiro Yamada 12915b97f5cSMasahiro Yamada fdt = Fdt(open("filename.dtb").read()) 13015b97f5cSMasahiro Yamada 13115b97f5cSMasahiro Yamada Operations can then be performed using the methods in this class. Each 13215b97f5cSMasahiro Yamada method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...). 13315b97f5cSMasahiro Yamada 13415b97f5cSMasahiro Yamada All methods raise an FdtException if an error occurs. To avoid this 13515b97f5cSMasahiro Yamada behaviour a 'quiet' parameter is provided for some functions. This 13615b97f5cSMasahiro Yamada defaults to empty, but you can pass a list of errors that you expect. 13715b97f5cSMasahiro Yamada If one of these errors occurs, the function will return an error number 13815b97f5cSMasahiro Yamada (e.g. -NOTFOUND). 13915b97f5cSMasahiro Yamada """ 14015b97f5cSMasahiro Yamada def __init__(self, data): 14115b97f5cSMasahiro Yamada self._fdt = bytearray(data) 14215b97f5cSMasahiro Yamada check_err(fdt_check_header(self._fdt)); 14315b97f5cSMasahiro Yamada 144*3def0cf2SSimon Glass def as_bytearray(self): 145*3def0cf2SSimon Glass """Get the device tree contents as a bytearray 146*3def0cf2SSimon Glass 147*3def0cf2SSimon Glass This can be passed directly to libfdt functions that access a 148*3def0cf2SSimon Glass const void * for the device tree. 149*3def0cf2SSimon Glass 150*3def0cf2SSimon Glass Returns: 151*3def0cf2SSimon Glass bytearray containing the device tree 152*3def0cf2SSimon Glass """ 153*3def0cf2SSimon Glass return bytearray(self._fdt) 154*3def0cf2SSimon Glass 155*3def0cf2SSimon Glass def next_node(self, nodeoffset, depth, quiet=()): 156*3def0cf2SSimon Glass """Find the next subnode 157*3def0cf2SSimon Glass 158*3def0cf2SSimon Glass Args: 159*3def0cf2SSimon Glass nodeoffset: Node offset of previous node 160*3def0cf2SSimon Glass depth: On input, the depth of the node at nodeoffset. On output, the 161*3def0cf2SSimon Glass depth of the returned node 162*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 163*3def0cf2SSimon Glass 164*3def0cf2SSimon Glass Returns: 165*3def0cf2SSimon Glass The offset of the next node, if any 166*3def0cf2SSimon Glass 167*3def0cf2SSimon Glass Raises: 168*3def0cf2SSimon Glass FdtException if no more nodes found or other error occurs 169*3def0cf2SSimon Glass """ 170*3def0cf2SSimon Glass return check_err(fdt_next_node(self._fdt, nodeoffset, depth), quiet) 171*3def0cf2SSimon Glass 172*3def0cf2SSimon Glass def first_subnode(self, nodeoffset, quiet=()): 173*3def0cf2SSimon Glass """Find the first subnode of a parent node 174*3def0cf2SSimon Glass 175*3def0cf2SSimon Glass Args: 176*3def0cf2SSimon Glass nodeoffset: Node offset of parent node 177*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 178*3def0cf2SSimon Glass 179*3def0cf2SSimon Glass Returns: 180*3def0cf2SSimon Glass The offset of the first subnode, if any 181*3def0cf2SSimon Glass 182*3def0cf2SSimon Glass Raises: 183*3def0cf2SSimon Glass FdtException if no subnodes found or other error occurs 184*3def0cf2SSimon Glass """ 185*3def0cf2SSimon Glass return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet) 186*3def0cf2SSimon Glass 187*3def0cf2SSimon Glass def next_subnode(self, nodeoffset, quiet=()): 188*3def0cf2SSimon Glass """Find the next subnode 189*3def0cf2SSimon Glass 190*3def0cf2SSimon Glass Args: 191*3def0cf2SSimon Glass nodeoffset: Node offset of previous subnode 192*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 193*3def0cf2SSimon Glass 194*3def0cf2SSimon Glass Returns: 195*3def0cf2SSimon Glass The offset of the next subnode, if any 196*3def0cf2SSimon Glass 197*3def0cf2SSimon Glass Raises: 198*3def0cf2SSimon Glass FdtException if no more subnodes found or other error occurs 199*3def0cf2SSimon Glass """ 200*3def0cf2SSimon Glass return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet) 201*3def0cf2SSimon Glass 202*3def0cf2SSimon Glass def magic(self): 203*3def0cf2SSimon Glass """Return the magic word from the header 204*3def0cf2SSimon Glass 205*3def0cf2SSimon Glass Returns: 206*3def0cf2SSimon Glass Magic word 207*3def0cf2SSimon Glass """ 208*3def0cf2SSimon Glass return fdt_magic(self._fdt) & 0xffffffff 209*3def0cf2SSimon Glass 210*3def0cf2SSimon Glass def totalsize(self): 211*3def0cf2SSimon Glass """Return the total size of the device tree 212*3def0cf2SSimon Glass 213*3def0cf2SSimon Glass Returns: 214*3def0cf2SSimon Glass Total tree size in bytes 215*3def0cf2SSimon Glass """ 216*3def0cf2SSimon Glass return check_err(fdt_totalsize(self._fdt)) 217*3def0cf2SSimon Glass 218*3def0cf2SSimon Glass def off_dt_struct(self): 219*3def0cf2SSimon Glass """Return the start of the device-tree struct area 220*3def0cf2SSimon Glass 221*3def0cf2SSimon Glass Returns: 222*3def0cf2SSimon Glass Start offset of struct area 223*3def0cf2SSimon Glass """ 224*3def0cf2SSimon Glass return check_err(fdt_off_dt_struct(self._fdt)) 225*3def0cf2SSimon Glass 226*3def0cf2SSimon Glass def off_dt_strings(self): 227*3def0cf2SSimon Glass """Return the start of the device-tree string area 228*3def0cf2SSimon Glass 229*3def0cf2SSimon Glass Returns: 230*3def0cf2SSimon Glass Start offset of string area 231*3def0cf2SSimon Glass """ 232*3def0cf2SSimon Glass return check_err(fdt_off_dt_strings(self._fdt)) 233*3def0cf2SSimon Glass 234*3def0cf2SSimon Glass def off_mem_rsvmap(self): 235*3def0cf2SSimon Glass """Return the start of the memory reserve map 236*3def0cf2SSimon Glass 237*3def0cf2SSimon Glass Returns: 238*3def0cf2SSimon Glass Start offset of memory reserve map 239*3def0cf2SSimon Glass """ 240*3def0cf2SSimon Glass return check_err(fdt_off_mem_rsvmap(self._fdt)) 241*3def0cf2SSimon Glass 242*3def0cf2SSimon Glass def version(self): 243*3def0cf2SSimon Glass """Return the version of the device tree 244*3def0cf2SSimon Glass 245*3def0cf2SSimon Glass Returns: 246*3def0cf2SSimon Glass Version number of the device tree 247*3def0cf2SSimon Glass """ 248*3def0cf2SSimon Glass return check_err(fdt_version(self._fdt)) 249*3def0cf2SSimon Glass 250*3def0cf2SSimon Glass def last_comp_version(self): 251*3def0cf2SSimon Glass """Return the last compatible version of the device tree 252*3def0cf2SSimon Glass 253*3def0cf2SSimon Glass Returns: 254*3def0cf2SSimon Glass Last compatible version number of the device tree 255*3def0cf2SSimon Glass """ 256*3def0cf2SSimon Glass return check_err(fdt_last_comp_version(self._fdt)) 257*3def0cf2SSimon Glass 258*3def0cf2SSimon Glass def boot_cpuid_phys(self): 259*3def0cf2SSimon Glass """Return the physical boot CPU ID 260*3def0cf2SSimon Glass 261*3def0cf2SSimon Glass Returns: 262*3def0cf2SSimon Glass Physical boot CPU ID 263*3def0cf2SSimon Glass """ 264*3def0cf2SSimon Glass return check_err(fdt_boot_cpuid_phys(self._fdt)) 265*3def0cf2SSimon Glass 266*3def0cf2SSimon Glass def size_dt_strings(self): 267*3def0cf2SSimon Glass """Return the start of the device-tree string area 268*3def0cf2SSimon Glass 269*3def0cf2SSimon Glass Returns: 270*3def0cf2SSimon Glass Start offset of string area 271*3def0cf2SSimon Glass """ 272*3def0cf2SSimon Glass return check_err(fdt_size_dt_strings(self._fdt)) 273*3def0cf2SSimon Glass 274*3def0cf2SSimon Glass def size_dt_struct(self): 275*3def0cf2SSimon Glass """Return the start of the device-tree struct area 276*3def0cf2SSimon Glass 277*3def0cf2SSimon Glass Returns: 278*3def0cf2SSimon Glass Start offset of struct area 279*3def0cf2SSimon Glass """ 280*3def0cf2SSimon Glass return check_err(fdt_size_dt_struct(self._fdt)) 281*3def0cf2SSimon Glass 282*3def0cf2SSimon Glass def num_mem_rsv(self, quiet=()): 283*3def0cf2SSimon Glass """Return the number of memory reserve-map records 284*3def0cf2SSimon Glass 285*3def0cf2SSimon Glass Returns: 286*3def0cf2SSimon Glass Number of memory reserve-map records 287*3def0cf2SSimon Glass """ 288*3def0cf2SSimon Glass return check_err(fdt_num_mem_rsv(self._fdt), quiet) 289*3def0cf2SSimon Glass 290*3def0cf2SSimon Glass def get_mem_rsv(self, index, quiet=()): 291*3def0cf2SSimon Glass """Return the indexed memory reserve-map record 292*3def0cf2SSimon Glass 293*3def0cf2SSimon Glass Args: 294*3def0cf2SSimon Glass index: Record to return (0=first) 295*3def0cf2SSimon Glass 296*3def0cf2SSimon Glass Returns: 297*3def0cf2SSimon Glass Number of memory reserve-map records 298*3def0cf2SSimon Glass """ 299*3def0cf2SSimon Glass return check_err(fdt_get_mem_rsv(self._fdt, index), quiet) 300*3def0cf2SSimon Glass 30115b97f5cSMasahiro Yamada def subnode_offset(self, parentoffset, name, quiet=()): 30215b97f5cSMasahiro Yamada """Get the offset of a named subnode 30315b97f5cSMasahiro Yamada 30415b97f5cSMasahiro Yamada Args: 30515b97f5cSMasahiro Yamada parentoffset: Offset of the parent node to check 30615b97f5cSMasahiro Yamada name: Name of the required subnode, e.g. 'subnode@1' 30715b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 30815b97f5cSMasahiro Yamada 30915b97f5cSMasahiro Yamada Returns: 31015b97f5cSMasahiro Yamada The node offset of the found node, if any 31115b97f5cSMasahiro Yamada 31215b97f5cSMasahiro Yamada Raises 31315b97f5cSMasahiro Yamada FdtException if there is no node with that name, or other error 31415b97f5cSMasahiro Yamada """ 31515b97f5cSMasahiro Yamada return check_err(fdt_subnode_offset(self._fdt, parentoffset, name), 31615b97f5cSMasahiro Yamada quiet) 31715b97f5cSMasahiro Yamada 31815b97f5cSMasahiro Yamada def path_offset(self, path, quiet=()): 31915b97f5cSMasahiro Yamada """Get the offset for a given path 32015b97f5cSMasahiro Yamada 32115b97f5cSMasahiro Yamada Args: 32215b97f5cSMasahiro Yamada path: Path to the required node, e.g. '/node@3/subnode@1' 32315b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 32415b97f5cSMasahiro Yamada 32515b97f5cSMasahiro Yamada Returns: 32615b97f5cSMasahiro Yamada Node offset 32715b97f5cSMasahiro Yamada 32815b97f5cSMasahiro Yamada Raises 32915b97f5cSMasahiro Yamada FdtException if the path is not valid or not found 33015b97f5cSMasahiro Yamada """ 33115b97f5cSMasahiro Yamada return check_err(fdt_path_offset(self._fdt, path), quiet) 33215b97f5cSMasahiro Yamada 333*3def0cf2SSimon Glass def get_name(self, nodeoffset): 334*3def0cf2SSimon Glass """Get the name of a node 335*3def0cf2SSimon Glass 336*3def0cf2SSimon Glass Args: 337*3def0cf2SSimon Glass nodeoffset: Offset of node to check 338*3def0cf2SSimon Glass 339*3def0cf2SSimon Glass Returns: 340*3def0cf2SSimon Glass Node name 341*3def0cf2SSimon Glass 342*3def0cf2SSimon Glass Raises: 343*3def0cf2SSimon Glass FdtException on error (e.g. nodeoffset is invalid) 344*3def0cf2SSimon Glass """ 345*3def0cf2SSimon Glass return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0] 346*3def0cf2SSimon Glass 34715b97f5cSMasahiro Yamada def first_property_offset(self, nodeoffset, quiet=()): 34815b97f5cSMasahiro Yamada """Get the offset of the first property in a node offset 34915b97f5cSMasahiro Yamada 35015b97f5cSMasahiro Yamada Args: 35115b97f5cSMasahiro Yamada nodeoffset: Offset to the node to check 35215b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 35315b97f5cSMasahiro Yamada 35415b97f5cSMasahiro Yamada Returns: 35515b97f5cSMasahiro Yamada Offset of the first property 35615b97f5cSMasahiro Yamada 35715b97f5cSMasahiro Yamada Raises 35815b97f5cSMasahiro Yamada FdtException if the associated node has no properties, or some 35915b97f5cSMasahiro Yamada other error occurred 36015b97f5cSMasahiro Yamada """ 36115b97f5cSMasahiro Yamada return check_err(fdt_first_property_offset(self._fdt, nodeoffset), 36215b97f5cSMasahiro Yamada quiet) 36315b97f5cSMasahiro Yamada 36415b97f5cSMasahiro Yamada def next_property_offset(self, prop_offset, quiet=()): 36515b97f5cSMasahiro Yamada """Get the next property in a node 36615b97f5cSMasahiro Yamada 36715b97f5cSMasahiro Yamada Args: 36815b97f5cSMasahiro Yamada prop_offset: Offset of the previous property 36915b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 37015b97f5cSMasahiro Yamada 37115b97f5cSMasahiro Yamada Returns: 37215b97f5cSMasahiro Yamada Offset of the next property 37315b97f5cSMasahiro Yamada 37415b97f5cSMasahiro Yamada Raises: 37515b97f5cSMasahiro Yamada FdtException if the associated node has no more properties, or 37615b97f5cSMasahiro Yamada some other error occurred 37715b97f5cSMasahiro Yamada """ 37815b97f5cSMasahiro Yamada return check_err(fdt_next_property_offset(self._fdt, prop_offset), 37915b97f5cSMasahiro Yamada quiet) 38015b97f5cSMasahiro Yamada 38115b97f5cSMasahiro Yamada def get_property_by_offset(self, prop_offset, quiet=()): 38215b97f5cSMasahiro Yamada """Obtains a property that can be examined 38315b97f5cSMasahiro Yamada 38415b97f5cSMasahiro Yamada Args: 38515b97f5cSMasahiro Yamada prop_offset: Offset of property (e.g. from first_property_offset()) 38615b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 38715b97f5cSMasahiro Yamada 38815b97f5cSMasahiro Yamada Returns: 38915b97f5cSMasahiro Yamada Property object, or None if not found 39015b97f5cSMasahiro Yamada 39115b97f5cSMasahiro Yamada Raises: 39215b97f5cSMasahiro Yamada FdtException on error (e.g. invalid prop_offset or device 39315b97f5cSMasahiro Yamada tree format) 39415b97f5cSMasahiro Yamada """ 39515b97f5cSMasahiro Yamada pdata = check_err_null( 39615b97f5cSMasahiro Yamada fdt_get_property_by_offset(self._fdt, prop_offset), quiet) 39715b97f5cSMasahiro Yamada if isinstance(pdata, (int)): 39815b97f5cSMasahiro Yamada return pdata 39915b97f5cSMasahiro Yamada return Property(pdata[0], pdata[1]) 40015b97f5cSMasahiro Yamada 401*3def0cf2SSimon Glass @staticmethod 402*3def0cf2SSimon Glass def create_empty_tree(size, quiet=()): 403*3def0cf2SSimon Glass """Create an empty device tree ready for use 40415b97f5cSMasahiro Yamada 40515b97f5cSMasahiro Yamada Args: 406*3def0cf2SSimon Glass size: Size of device tree in bytes 40715b97f5cSMasahiro Yamada 40815b97f5cSMasahiro Yamada Returns: 409*3def0cf2SSimon Glass Fdt object containing the device tree 41015b97f5cSMasahiro Yamada """ 411*3def0cf2SSimon Glass data = bytearray(size) 412*3def0cf2SSimon Glass err = check_err(fdt_create_empty_tree(data, size), quiet) 413*3def0cf2SSimon Glass if err: 414*3def0cf2SSimon Glass return err 415*3def0cf2SSimon Glass return Fdt(data) 41615b97f5cSMasahiro Yamada 417*3def0cf2SSimon Glass def open_into(self, size, quiet=()): 418*3def0cf2SSimon Glass """Move the device tree into a larger or smaller space 419*3def0cf2SSimon Glass 420*3def0cf2SSimon Glass This creates a new device tree of size @size and moves the existing 421*3def0cf2SSimon Glass device tree contents over to that. It can be used to create more space 422*3def0cf2SSimon Glass in a device tree. 42315b97f5cSMasahiro Yamada 42415b97f5cSMasahiro Yamada Args: 425*3def0cf2SSimon Glass size: Required new size of device tree in bytes 42615b97f5cSMasahiro Yamada """ 427*3def0cf2SSimon Glass fdt = bytearray(size) 428*3def0cf2SSimon Glass fdt[:len(self._fdt)] = self._fdt 429*3def0cf2SSimon Glass err = check_err(fdt_open_into(self._fdt, fdt, size), quiet) 430*3def0cf2SSimon Glass if err: 431*3def0cf2SSimon Glass return err 432*3def0cf2SSimon Glass self._fdt = fdt 43315b97f5cSMasahiro Yamada 43415b97f5cSMasahiro Yamada def pack(self, quiet=()): 43515b97f5cSMasahiro Yamada """Pack the device tree to remove unused space 43615b97f5cSMasahiro Yamada 43715b97f5cSMasahiro Yamada This adjusts the tree in place. 43815b97f5cSMasahiro Yamada 43915b97f5cSMasahiro Yamada Args: 44015b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 44115b97f5cSMasahiro Yamada 44215b97f5cSMasahiro Yamada Raises: 44315b97f5cSMasahiro Yamada FdtException if any error occurs 44415b97f5cSMasahiro Yamada """ 44515b97f5cSMasahiro Yamada return check_err(fdt_pack(self._fdt), quiet) 44615b97f5cSMasahiro Yamada 44715b97f5cSMasahiro Yamada def getprop(self, nodeoffset, prop_name, quiet=()): 44815b97f5cSMasahiro Yamada """Get a property from a node 44915b97f5cSMasahiro Yamada 45015b97f5cSMasahiro Yamada Args: 45115b97f5cSMasahiro Yamada nodeoffset: Node offset containing property to get 45215b97f5cSMasahiro Yamada prop_name: Name of property to get 45315b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 45415b97f5cSMasahiro Yamada 45515b97f5cSMasahiro Yamada Returns: 456*3def0cf2SSimon Glass Value of property as a string, or -ve error number 45715b97f5cSMasahiro Yamada 45815b97f5cSMasahiro Yamada Raises: 45915b97f5cSMasahiro Yamada FdtError if any error occurs (e.g. the property is not found) 46015b97f5cSMasahiro Yamada """ 46115b97f5cSMasahiro Yamada pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 46215b97f5cSMasahiro Yamada quiet) 46315b97f5cSMasahiro Yamada if isinstance(pdata, (int)): 46415b97f5cSMasahiro Yamada return pdata 465*3def0cf2SSimon Glass return str(pdata[0]) 466*3def0cf2SSimon Glass 467*3def0cf2SSimon Glass def getprop_obj(self, nodeoffset, prop_name, quiet=()): 468*3def0cf2SSimon Glass """Get a property from a node as a Property object 469*3def0cf2SSimon Glass 470*3def0cf2SSimon Glass Args: 471*3def0cf2SSimon Glass nodeoffset: Node offset containing property to get 472*3def0cf2SSimon Glass prop_name: Name of property to get 473*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 474*3def0cf2SSimon Glass 475*3def0cf2SSimon Glass Returns: 476*3def0cf2SSimon Glass Property object, or None if not found 477*3def0cf2SSimon Glass 478*3def0cf2SSimon Glass Raises: 479*3def0cf2SSimon Glass FdtError if any error occurs (e.g. the property is not found) 480*3def0cf2SSimon Glass """ 481*3def0cf2SSimon Glass pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 482*3def0cf2SSimon Glass quiet) 483*3def0cf2SSimon Glass if isinstance(pdata, (int)): 484*3def0cf2SSimon Glass return None 485*3def0cf2SSimon Glass return Property(prop_name, bytearray(pdata[0])) 48615b97f5cSMasahiro Yamada 48715b97f5cSMasahiro Yamada def get_phandle(self, nodeoffset): 48815b97f5cSMasahiro Yamada """Get the phandle of a node 48915b97f5cSMasahiro Yamada 49015b97f5cSMasahiro Yamada Args: 49115b97f5cSMasahiro Yamada nodeoffset: Node offset to check 49215b97f5cSMasahiro Yamada 49315b97f5cSMasahiro Yamada Returns: 49415b97f5cSMasahiro Yamada phandle of node, or 0 if the node has no phandle or another error 49515b97f5cSMasahiro Yamada occurs 49615b97f5cSMasahiro Yamada """ 49715b97f5cSMasahiro Yamada return fdt_get_phandle(self._fdt, nodeoffset) 49815b97f5cSMasahiro Yamada 49915b97f5cSMasahiro Yamada def parent_offset(self, nodeoffset, quiet=()): 50015b97f5cSMasahiro Yamada """Get the offset of a node's parent 50115b97f5cSMasahiro Yamada 50215b97f5cSMasahiro Yamada Args: 50315b97f5cSMasahiro Yamada nodeoffset: Node offset to check 50415b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 50515b97f5cSMasahiro Yamada 50615b97f5cSMasahiro Yamada Returns: 50715b97f5cSMasahiro Yamada The offset of the parent node, if any 50815b97f5cSMasahiro Yamada 50915b97f5cSMasahiro Yamada Raises: 51015b97f5cSMasahiro Yamada FdtException if no parent found or other error occurs 51115b97f5cSMasahiro Yamada """ 51215b97f5cSMasahiro Yamada return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet) 51315b97f5cSMasahiro Yamada 514*3def0cf2SSimon Glass def set_name(self, nodeoffset, name, quiet=()): 515*3def0cf2SSimon Glass """Set the name of a node 516*3def0cf2SSimon Glass 517*3def0cf2SSimon Glass Args: 518*3def0cf2SSimon Glass nodeoffset: Node offset of node to update 519*3def0cf2SSimon Glass name: New node name 520*3def0cf2SSimon Glass 521*3def0cf2SSimon Glass Returns: 522*3def0cf2SSimon Glass Error code, or 0 if OK 523*3def0cf2SSimon Glass 524*3def0cf2SSimon Glass Raises: 525*3def0cf2SSimon Glass FdtException if no parent found or other error occurs 526*3def0cf2SSimon Glass """ 527*3def0cf2SSimon Glass return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet) 528*3def0cf2SSimon Glass 529*3def0cf2SSimon Glass def setprop(self, nodeoffset, prop_name, val, quiet=()): 530*3def0cf2SSimon Glass """Set the value of a property 531*3def0cf2SSimon Glass 532*3def0cf2SSimon Glass Args: 533*3def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 534*3def0cf2SSimon Glass prop_name: Name of property 535*3def0cf2SSimon Glass val: Value to write (string or bytearray) 536*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 537*3def0cf2SSimon Glass 538*3def0cf2SSimon Glass Returns: 539*3def0cf2SSimon Glass Error code, or 0 if OK 540*3def0cf2SSimon Glass 541*3def0cf2SSimon Glass Raises: 542*3def0cf2SSimon Glass FdtException if no parent found or other error occurs 543*3def0cf2SSimon Glass """ 544*3def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, 545*3def0cf2SSimon Glass len(val)), quiet) 546*3def0cf2SSimon Glass 547*3def0cf2SSimon Glass def setprop_u32(self, nodeoffset, prop_name, val, quiet=()): 548*3def0cf2SSimon Glass """Set the value of a property 549*3def0cf2SSimon Glass 550*3def0cf2SSimon Glass Args: 551*3def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 552*3def0cf2SSimon Glass prop_name: Name of property 553*3def0cf2SSimon Glass val: Value to write (integer) 554*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 555*3def0cf2SSimon Glass 556*3def0cf2SSimon Glass Returns: 557*3def0cf2SSimon Glass Error code, or 0 if OK 558*3def0cf2SSimon Glass 559*3def0cf2SSimon Glass Raises: 560*3def0cf2SSimon Glass FdtException if no parent found or other error occurs 561*3def0cf2SSimon Glass """ 562*3def0cf2SSimon Glass return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val), 563*3def0cf2SSimon Glass quiet) 564*3def0cf2SSimon Glass 565*3def0cf2SSimon Glass def setprop_u64(self, nodeoffset, prop_name, val, quiet=()): 566*3def0cf2SSimon Glass """Set the value of a property 567*3def0cf2SSimon Glass 568*3def0cf2SSimon Glass Args: 569*3def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 570*3def0cf2SSimon Glass prop_name: Name of property 571*3def0cf2SSimon Glass val: Value to write (integer) 572*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 573*3def0cf2SSimon Glass 574*3def0cf2SSimon Glass Returns: 575*3def0cf2SSimon Glass Error code, or 0 if OK 576*3def0cf2SSimon Glass 577*3def0cf2SSimon Glass Raises: 578*3def0cf2SSimon Glass FdtException if no parent found or other error occurs 579*3def0cf2SSimon Glass """ 580*3def0cf2SSimon Glass return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), 581*3def0cf2SSimon Glass quiet) 582*3def0cf2SSimon Glass 583*3def0cf2SSimon Glass def setprop_str(self, nodeoffset, prop_name, val, quiet=()): 584*3def0cf2SSimon Glass """Set the string value of a property 585*3def0cf2SSimon Glass 586*3def0cf2SSimon Glass The property is set to the string, with a nul terminator added 587*3def0cf2SSimon Glass 588*3def0cf2SSimon Glass Args: 589*3def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 590*3def0cf2SSimon Glass prop_name: Name of property 591*3def0cf2SSimon Glass val: Value to write (string without nul terminator) 592*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 593*3def0cf2SSimon Glass 594*3def0cf2SSimon Glass Returns: 595*3def0cf2SSimon Glass Error code, or 0 if OK 596*3def0cf2SSimon Glass 597*3def0cf2SSimon Glass Raises: 598*3def0cf2SSimon Glass FdtException if no parent found or other error occurs 599*3def0cf2SSimon Glass """ 600*3def0cf2SSimon Glass val += '\0' 601*3def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, 602*3def0cf2SSimon Glass val, len(val)), quiet) 603*3def0cf2SSimon Glass 604*3def0cf2SSimon Glass def delprop(self, nodeoffset, prop_name): 605*3def0cf2SSimon Glass """Delete a property from a node 606*3def0cf2SSimon Glass 607*3def0cf2SSimon Glass Args: 608*3def0cf2SSimon Glass nodeoffset: Node offset containing property to delete 609*3def0cf2SSimon Glass prop_name: Name of property to delete 610*3def0cf2SSimon Glass 611*3def0cf2SSimon Glass Raises: 612*3def0cf2SSimon Glass FdtError if the property does not exist, or another error occurs 613*3def0cf2SSimon Glass """ 614*3def0cf2SSimon Glass return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name)) 615*3def0cf2SSimon Glass 61615b97f5cSMasahiro Yamada def node_offset_by_phandle(self, phandle, quiet=()): 61715b97f5cSMasahiro Yamada """Get the offset of a node with the given phandle 61815b97f5cSMasahiro Yamada 61915b97f5cSMasahiro Yamada Args: 62015b97f5cSMasahiro Yamada phandle: Phandle to search for 62115b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 62215b97f5cSMasahiro Yamada 62315b97f5cSMasahiro Yamada Returns: 62415b97f5cSMasahiro Yamada The offset of node with that phandle, if any 62515b97f5cSMasahiro Yamada 62615b97f5cSMasahiro Yamada Raises: 62715b97f5cSMasahiro Yamada FdtException if no node found or other error occurs 62815b97f5cSMasahiro Yamada """ 62915b97f5cSMasahiro Yamada return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet) 63015b97f5cSMasahiro Yamada 631*3def0cf2SSimon Glass 632*3def0cf2SSimon Glassclass Property(bytearray): 63315b97f5cSMasahiro Yamada """Holds a device tree property name and value. 63415b97f5cSMasahiro Yamada 63515b97f5cSMasahiro Yamada This holds a copy of a property taken from the device tree. It does not 63615b97f5cSMasahiro Yamada reference the device tree, so if anything changes in the device tree, 63715b97f5cSMasahiro Yamada a Property object will remain valid. 63815b97f5cSMasahiro Yamada 63915b97f5cSMasahiro Yamada Properties: 64015b97f5cSMasahiro Yamada name: Property name 641*3def0cf2SSimon Glass value: Property value as a bytearray 64215b97f5cSMasahiro Yamada """ 64315b97f5cSMasahiro Yamada def __init__(self, name, value): 644*3def0cf2SSimon Glass bytearray.__init__(self, value) 64515b97f5cSMasahiro Yamada self.name = name 646*3def0cf2SSimon Glass 647*3def0cf2SSimon Glass def as_cell(self, fmt): 648*3def0cf2SSimon Glass return struct.unpack('>' + fmt, self)[0] 649*3def0cf2SSimon Glass 650*3def0cf2SSimon Glass def as_uint32(self): 651*3def0cf2SSimon Glass return self.as_cell('L') 652*3def0cf2SSimon Glass 653*3def0cf2SSimon Glass def as_int32(self): 654*3def0cf2SSimon Glass return self.as_cell('l') 655*3def0cf2SSimon Glass 656*3def0cf2SSimon Glass def as_uint64(self): 657*3def0cf2SSimon Glass return self.as_cell('Q') 658*3def0cf2SSimon Glass 659*3def0cf2SSimon Glass def as_int64(self): 660*3def0cf2SSimon Glass return self.as_cell('q') 661*3def0cf2SSimon Glass 662*3def0cf2SSimon Glass def as_str(self): 663*3def0cf2SSimon Glass return self[:-1] 664*3def0cf2SSimon Glass 665*3def0cf2SSimon Glass 666*3def0cf2SSimon Glassclass FdtSw(object): 667*3def0cf2SSimon Glass """Software interface to create a device tree from scratch 668*3def0cf2SSimon Glass 669*3def0cf2SSimon Glass The methods in this class work by adding to an existing 'partial' device 670*3def0cf2SSimon Glass tree buffer of a fixed size created by instantiating this class. When the 671*3def0cf2SSimon Glass tree is complete, call finish() to complete the device tree so that it can 672*3def0cf2SSimon Glass be used. 673*3def0cf2SSimon Glass 674*3def0cf2SSimon Glass Similarly with nodes, a new node is started with begin_node() and finished 675*3def0cf2SSimon Glass with end_node(). 676*3def0cf2SSimon Glass 677*3def0cf2SSimon Glass The context manager functions can be used to make this a bit easier: 678*3def0cf2SSimon Glass 679*3def0cf2SSimon Glass # First create the device tree with a node and property: 680*3def0cf2SSimon Glass with FdtSw(small_size) as sw: 681*3def0cf2SSimon Glass with sw.AddNode('node'): 682*3def0cf2SSimon Glass sw.property_u32('reg', 2) 683*3def0cf2SSimon Glass fdt = sw.AsFdt() 684*3def0cf2SSimon Glass 685*3def0cf2SSimon Glass # Now we can use it as a real device tree 686*3def0cf2SSimon Glass fdt.setprop_u32(0, 'reg', 3) 687*3def0cf2SSimon Glass """ 688*3def0cf2SSimon Glass def __init__(self, size, quiet=()): 689*3def0cf2SSimon Glass fdtrw = bytearray(size) 690*3def0cf2SSimon Glass err = check_err(fdt_create(fdtrw, size)) 691*3def0cf2SSimon Glass if err: 692*3def0cf2SSimon Glass return err 693*3def0cf2SSimon Glass self._fdtrw = fdtrw 694*3def0cf2SSimon Glass 695*3def0cf2SSimon Glass def __enter__(self): 696*3def0cf2SSimon Glass """Contact manager to use to create a device tree via software""" 697*3def0cf2SSimon Glass return self 698*3def0cf2SSimon Glass 699*3def0cf2SSimon Glass def __exit__(self, type, value, traceback): 700*3def0cf2SSimon Glass check_err(fdt_finish(self._fdtrw)) 701*3def0cf2SSimon Glass 702*3def0cf2SSimon Glass def AsFdt(self): 703*3def0cf2SSimon Glass """Convert a FdtSw into an Fdt so it can be accessed as normal 704*3def0cf2SSimon Glass 705*3def0cf2SSimon Glass Note that finish() must be called before this function will work. If 706*3def0cf2SSimon Glass you are using the context manager (see 'with' code in the FdtSw class 707*3def0cf2SSimon Glass comment) then this will happen automatically. 708*3def0cf2SSimon Glass 709*3def0cf2SSimon Glass Returns: 710*3def0cf2SSimon Glass Fdt object allowing access to the newly created device tree 711*3def0cf2SSimon Glass """ 712*3def0cf2SSimon Glass return Fdt(self._fdtrw) 713*3def0cf2SSimon Glass 714*3def0cf2SSimon Glass def resize(self, size, quiet=()): 715*3def0cf2SSimon Glass """Resize the buffer to accommodate a larger tree 716*3def0cf2SSimon Glass 717*3def0cf2SSimon Glass Args: 718*3def0cf2SSimon Glass size: New size of tree 719*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 720*3def0cf2SSimon Glass 721*3def0cf2SSimon Glass Raises: 722*3def0cf2SSimon Glass FdtException if no node found or other error occurs 723*3def0cf2SSimon Glass """ 724*3def0cf2SSimon Glass fdt = bytearray(size) 725*3def0cf2SSimon Glass fdt[:len(self._fdtrw)] = self._fdtrw 726*3def0cf2SSimon Glass err = check_err(fdt_resize(self._fdtrw, fdt, size), quiet) 727*3def0cf2SSimon Glass if err: 728*3def0cf2SSimon Glass return err 729*3def0cf2SSimon Glass self._fdtrw = fdt 730*3def0cf2SSimon Glass 731*3def0cf2SSimon Glass def add_reservemap_entry(self, addr, size, quiet=()): 732*3def0cf2SSimon Glass """Add a new memory reserve map entry 733*3def0cf2SSimon Glass 734*3def0cf2SSimon Glass Once finished adding, you must call finish_reservemap(). 735*3def0cf2SSimon Glass 736*3def0cf2SSimon Glass Args: 737*3def0cf2SSimon Glass addr: 64-bit start address 738*3def0cf2SSimon Glass size: 64-bit size 739*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 740*3def0cf2SSimon Glass 741*3def0cf2SSimon Glass Raises: 742*3def0cf2SSimon Glass FdtException if no node found or other error occurs 743*3def0cf2SSimon Glass """ 744*3def0cf2SSimon Glass return check_err(fdt_add_reservemap_entry(self._fdtrw, addr, size), 745*3def0cf2SSimon Glass quiet) 746*3def0cf2SSimon Glass 747*3def0cf2SSimon Glass def finish_reservemap(self, quiet=()): 748*3def0cf2SSimon Glass """Indicate that there are no more reserve map entries to add 749*3def0cf2SSimon Glass 750*3def0cf2SSimon Glass Args: 751*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 752*3def0cf2SSimon Glass 753*3def0cf2SSimon Glass Raises: 754*3def0cf2SSimon Glass FdtException if no node found or other error occurs 755*3def0cf2SSimon Glass """ 756*3def0cf2SSimon Glass return check_err(fdt_finish_reservemap(self._fdtrw), quiet) 757*3def0cf2SSimon Glass 758*3def0cf2SSimon Glass def begin_node(self, name, quiet=()): 759*3def0cf2SSimon Glass """Begin a new node 760*3def0cf2SSimon Glass 761*3def0cf2SSimon Glass Use this before adding properties to the node. Then call end_node() to 762*3def0cf2SSimon Glass finish it. You can also use the context manager as shown in the FdtSw 763*3def0cf2SSimon Glass class comment. 764*3def0cf2SSimon Glass 765*3def0cf2SSimon Glass Args: 766*3def0cf2SSimon Glass name: Name of node to begin 767*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 768*3def0cf2SSimon Glass 769*3def0cf2SSimon Glass Raises: 770*3def0cf2SSimon Glass FdtException if no node found or other error occurs 771*3def0cf2SSimon Glass """ 772*3def0cf2SSimon Glass return check_err(fdt_begin_node(self._fdtrw, name), quiet) 773*3def0cf2SSimon Glass 774*3def0cf2SSimon Glass def property_string(self, name, string, quiet=()): 775*3def0cf2SSimon Glass """Add a property with a string value 776*3def0cf2SSimon Glass 777*3def0cf2SSimon Glass The string will be nul-terminated when written to the device tree 778*3def0cf2SSimon Glass 779*3def0cf2SSimon Glass Args: 780*3def0cf2SSimon Glass name: Name of property to add 781*3def0cf2SSimon Glass string: String value of property 782*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 783*3def0cf2SSimon Glass 784*3def0cf2SSimon Glass Raises: 785*3def0cf2SSimon Glass FdtException if no node found or other error occurs 786*3def0cf2SSimon Glass """ 787*3def0cf2SSimon Glass return check_err(fdt_property_string(self._fdtrw, name, string), quiet) 788*3def0cf2SSimon Glass 789*3def0cf2SSimon Glass def property_u32(self, name, val, quiet=()): 790*3def0cf2SSimon Glass """Add a property with a 32-bit value 791*3def0cf2SSimon Glass 792*3def0cf2SSimon Glass Write a single-cell value to the device tree 793*3def0cf2SSimon Glass 794*3def0cf2SSimon Glass Args: 795*3def0cf2SSimon Glass name: Name of property to add 796*3def0cf2SSimon Glass val: Value of property 797*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 798*3def0cf2SSimon Glass 799*3def0cf2SSimon Glass Raises: 800*3def0cf2SSimon Glass FdtException if no node found or other error occurs 801*3def0cf2SSimon Glass """ 802*3def0cf2SSimon Glass return check_err(fdt_property_u32(self._fdtrw, name, val), quiet) 803*3def0cf2SSimon Glass 804*3def0cf2SSimon Glass def property_u64(self, name, val, quiet=()): 805*3def0cf2SSimon Glass """Add a property with a 64-bit value 806*3def0cf2SSimon Glass 807*3def0cf2SSimon Glass Write a double-cell value to the device tree in big-endian format 808*3def0cf2SSimon Glass 809*3def0cf2SSimon Glass Args: 810*3def0cf2SSimon Glass name: Name of property to add 811*3def0cf2SSimon Glass val: Value of property 812*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 813*3def0cf2SSimon Glass 814*3def0cf2SSimon Glass Raises: 815*3def0cf2SSimon Glass FdtException if no node found or other error occurs 816*3def0cf2SSimon Glass """ 817*3def0cf2SSimon Glass return check_err(fdt_property_u64(self._fdtrw, name, val), quiet) 818*3def0cf2SSimon Glass 819*3def0cf2SSimon Glass def property_cell(self, name, val, quiet=()): 820*3def0cf2SSimon Glass """Add a property with a single-cell value 821*3def0cf2SSimon Glass 822*3def0cf2SSimon Glass Write a single-cell value to the device tree 823*3def0cf2SSimon Glass 824*3def0cf2SSimon Glass Args: 825*3def0cf2SSimon Glass name: Name of property to add 826*3def0cf2SSimon Glass val: Value of property 827*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 828*3def0cf2SSimon Glass 829*3def0cf2SSimon Glass Raises: 830*3def0cf2SSimon Glass FdtException if no node found or other error occurs 831*3def0cf2SSimon Glass """ 832*3def0cf2SSimon Glass return check_err(fdt_property_cell(self._fdtrw, name, val), quiet) 833*3def0cf2SSimon Glass 834*3def0cf2SSimon Glass def property(self, name, val, quiet=()): 835*3def0cf2SSimon Glass """Add a property 836*3def0cf2SSimon Glass 837*3def0cf2SSimon Glass Write a new property with the given value to the device tree. The value 838*3def0cf2SSimon Glass is taken as is and is not nul-terminated 839*3def0cf2SSimon Glass 840*3def0cf2SSimon Glass Args: 841*3def0cf2SSimon Glass name: Name of property to add 842*3def0cf2SSimon Glass val: Value of property 843*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 844*3def0cf2SSimon Glass 845*3def0cf2SSimon Glass Raises: 846*3def0cf2SSimon Glass FdtException if no node found or other error occurs 847*3def0cf2SSimon Glass """ 848*3def0cf2SSimon Glass return check_err(_fdt_property(self._fdtrw, name, val, len(val)), quiet) 849*3def0cf2SSimon Glass 850*3def0cf2SSimon Glass def end_node(self, quiet=()): 851*3def0cf2SSimon Glass """End a node 852*3def0cf2SSimon Glass 853*3def0cf2SSimon Glass Use this after adding properties to a node to close it off. You can also 854*3def0cf2SSimon Glass use the context manager as shown in the FdtSw class comment. 855*3def0cf2SSimon Glass 856*3def0cf2SSimon Glass Args: 857*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 858*3def0cf2SSimon Glass 859*3def0cf2SSimon Glass Raises: 860*3def0cf2SSimon Glass FdtException if no node found or other error occurs 861*3def0cf2SSimon Glass """ 862*3def0cf2SSimon Glass return check_err(fdt_end_node(self._fdtrw), quiet) 863*3def0cf2SSimon Glass 864*3def0cf2SSimon Glass def finish(self, quiet=()): 865*3def0cf2SSimon Glass """Finish writing the device tree 866*3def0cf2SSimon Glass 867*3def0cf2SSimon Glass This closes off the device tree ready for use 868*3def0cf2SSimon Glass 869*3def0cf2SSimon Glass Args: 870*3def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 871*3def0cf2SSimon Glass 872*3def0cf2SSimon Glass Raises: 873*3def0cf2SSimon Glass FdtException if no node found or other error occurs 874*3def0cf2SSimon Glass """ 875*3def0cf2SSimon Glass return check_err(fdt_finish(self._fdtrw), quiet) 876*3def0cf2SSimon Glass 877*3def0cf2SSimon Glass def AddNode(self, name): 878*3def0cf2SSimon Glass """Create a new context for adding a node 879*3def0cf2SSimon Glass 880*3def0cf2SSimon Glass When used in a 'with' clause this starts a new node and finishes it 881*3def0cf2SSimon Glass afterward. 882*3def0cf2SSimon Glass 883*3def0cf2SSimon Glass Args: 884*3def0cf2SSimon Glass name: Name of node to add 885*3def0cf2SSimon Glass """ 886*3def0cf2SSimon Glass return NodeAdder(self._fdtrw, name) 887*3def0cf2SSimon Glass 888*3def0cf2SSimon Glass 889*3def0cf2SSimon Glassclass NodeAdder(): 890*3def0cf2SSimon Glass """Class to provide a node context 891*3def0cf2SSimon Glass 892*3def0cf2SSimon Glass This allows you to add nodes in a more natural way: 893*3def0cf2SSimon Glass 894*3def0cf2SSimon Glass with fdtsw.AddNode('name'): 895*3def0cf2SSimon Glass fdtsw.property_string('test', 'value') 896*3def0cf2SSimon Glass 897*3def0cf2SSimon Glass The node is automatically completed with a call to end_node() when the 898*3def0cf2SSimon Glass context exits. 899*3def0cf2SSimon Glass """ 900*3def0cf2SSimon Glass def __init__(self, fdt, name): 901*3def0cf2SSimon Glass self._fdt = fdt 902*3def0cf2SSimon Glass self._name = name 903*3def0cf2SSimon Glass 904*3def0cf2SSimon Glass def __enter__(self): 905*3def0cf2SSimon Glass check_err(fdt_begin_node(self._fdt, self._name)) 906*3def0cf2SSimon Glass 907*3def0cf2SSimon Glass def __exit__(self, type, value, traceback): 908*3def0cf2SSimon Glass check_err(fdt_end_node(self._fdt)) 90915b97f5cSMasahiro Yamada%} 91015b97f5cSMasahiro Yamada 91115b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func; 91215b97f5cSMasahiro Yamada 91315b97f5cSMasahiro Yamadatypedef int fdt32_t; 91415b97f5cSMasahiro Yamada 91515b97f5cSMasahiro Yamada%include "libfdt/fdt.h" 91615b97f5cSMasahiro Yamada 91715b97f5cSMasahiro Yamada%include "typemaps.i" 91815b97f5cSMasahiro Yamada 91915b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */ 92015b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) { 92115b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 92215b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 92315b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 92415b97f5cSMasahiro Yamada } 92515b97f5cSMasahiro Yamada $1 = (void *)PyByteArray_AsString($input); 92615b97f5cSMasahiro Yamada fdt = $1; 92715b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 92815b97f5cSMasahiro Yamada} 92915b97f5cSMasahiro Yamada 93015b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */ 93115b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) { 93215b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 93315b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 93415b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 93515b97f5cSMasahiro Yamada } 93615b97f5cSMasahiro Yamada $1 = PyByteArray_AsString($input); 93715b97f5cSMasahiro Yamada fdt = $1; 93815b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 93915b97f5cSMasahiro Yamada} 94015b97f5cSMasahiro Yamada 941*3def0cf2SSimon Glass/* typemap used for fdt_get_property_by_offset() */ 94215b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) { 94315b97f5cSMasahiro Yamada PyObject *buff; 94415b97f5cSMasahiro Yamada 94515b97f5cSMasahiro Yamada if ($1) { 94615b97f5cSMasahiro Yamada resultobj = PyString_FromString( 94715b97f5cSMasahiro Yamada fdt_string(fdt1, fdt32_to_cpu($1->nameoff))); 94815b97f5cSMasahiro Yamada buff = PyByteArray_FromStringAndSize( 94915b97f5cSMasahiro Yamada (const char *)($1 + 1), fdt32_to_cpu($1->len)); 95015b97f5cSMasahiro Yamada resultobj = SWIG_Python_AppendOutput(resultobj, buff); 95115b97f5cSMasahiro Yamada } 95215b97f5cSMasahiro Yamada} 95315b97f5cSMasahiro Yamada 95415b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp }; 95515b97f5cSMasahiro Yamada 95615b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */ 95715b97f5cSMasahiro Yamada%typemap(out) (const void *) { 95815b97f5cSMasahiro Yamada if (!$1) 95915b97f5cSMasahiro Yamada $result = Py_None; 96015b97f5cSMasahiro Yamada else 96115b97f5cSMasahiro Yamada $result = Py_BuildValue("s#", $1, *arg4); 96215b97f5cSMasahiro Yamada} 96315b97f5cSMasahiro Yamada 964*3def0cf2SSimon Glass/* typemap used for fdt_setprop() */ 965*3def0cf2SSimon Glass%typemap(in) (const void *val) { 966*3def0cf2SSimon Glass $1 = PyString_AsString($input); /* char *str */ 967*3def0cf2SSimon Glass} 968*3def0cf2SSimon Glass 969*3def0cf2SSimon Glass/* typemap used for fdt_add_reservemap_entry() */ 970*3def0cf2SSimon Glass%typemap(in) uint64_t { 971*3def0cf2SSimon Glass $1 = PyLong_AsUnsignedLong($input); 972*3def0cf2SSimon Glass} 973*3def0cf2SSimon Glass 974*3def0cf2SSimon Glass/* typemaps used for fdt_next_node() */ 975*3def0cf2SSimon Glass%typemap(in, numinputs=1) int *depth (int depth) { 976*3def0cf2SSimon Glass depth = (int) PyInt_AsLong($input); 977*3def0cf2SSimon Glass $1 = &depth; 978*3def0cf2SSimon Glass} 979*3def0cf2SSimon Glass 980*3def0cf2SSimon Glass%typemap(argout) int *depth { 981*3def0cf2SSimon Glass PyObject *val = Py_BuildValue("i", *arg$argnum); 982*3def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 983*3def0cf2SSimon Glass} 984*3def0cf2SSimon Glass 985*3def0cf2SSimon Glass%apply int *depth { int *depth }; 986*3def0cf2SSimon Glass 987*3def0cf2SSimon Glass/* typemaps for fdt_get_mem_rsv */ 988*3def0cf2SSimon Glass%typemap(in, numinputs=0) uint64_t * (uint64_t temp) { 989*3def0cf2SSimon Glass $1 = &temp; 990*3def0cf2SSimon Glass} 991*3def0cf2SSimon Glass 992*3def0cf2SSimon Glass%typemap(argout) uint64_t * { 993*3def0cf2SSimon Glass PyObject *val = PyLong_FromUnsignedLong(*arg$argnum); 994*3def0cf2SSimon Glass if (!result) { 995*3def0cf2SSimon Glass if (PyTuple_GET_SIZE(resultobj) == 0) 996*3def0cf2SSimon Glass resultobj = val; 997*3def0cf2SSimon Glass else 998*3def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 999*3def0cf2SSimon Glass } 1000*3def0cf2SSimon Glass} 1001*3def0cf2SSimon Glass 100215b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */ 100315b97f5cSMasahiro Yamada%warnfilter(302) fdt_property; 100415b97f5cSMasahiro Yamada 100515b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */ 100615b97f5cSMasahiro Yamadaint fdt_magic(const void *fdt); 100715b97f5cSMasahiro Yamadaint fdt_totalsize(const void *fdt); 100815b97f5cSMasahiro Yamadaint fdt_off_dt_struct(const void *fdt); 100915b97f5cSMasahiro Yamadaint fdt_off_dt_strings(const void *fdt); 101015b97f5cSMasahiro Yamadaint fdt_off_mem_rsvmap(const void *fdt); 101115b97f5cSMasahiro Yamadaint fdt_version(const void *fdt); 101215b97f5cSMasahiro Yamadaint fdt_last_comp_version(const void *fdt); 101315b97f5cSMasahiro Yamadaint fdt_boot_cpuid_phys(const void *fdt); 101415b97f5cSMasahiro Yamadaint fdt_size_dt_strings(const void *fdt); 101515b97f5cSMasahiro Yamadaint fdt_size_dt_struct(const void *fdt); 1016*3def0cf2SSimon Glassint fdt_property_string(void *fdt, const char *name, const char *val); 1017*3def0cf2SSimon Glassint fdt_property_cell(void *fdt, const char *name, uint32_t val); 1018*3def0cf2SSimon Glass 1019*3def0cf2SSimon Glass/* 1020*3def0cf2SSimon Glass * This function has a stub since the name fdt_property is used for both a 1021*3def0cf2SSimon Glass * function and a struct, which confuses SWIG. 1022*3def0cf2SSimon Glass */ 1023*3def0cf2SSimon Glassint _fdt_property(void *fdt, const char *name, const char *val, int len); 102415b97f5cSMasahiro Yamada 102515b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h> 1026