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" 153def0cf2SSimon Glass 163def0cf2SSimon Glass/* 173def0cf2SSimon Glass * We rename this function here to avoid problems with swig, since we also have 183def0cf2SSimon Glass * a struct called fdt_property. That struct causes swig to create a class in 193def0cf2SSimon Glass * libfdt.py called fdt_property(), which confuses things. 203def0cf2SSimon Glass */ 213def0cf2SSimon Glassstatic int _fdt_property(void *fdt, const char *name, const char *val, int len) 223def0cf2SSimon Glass{ 233def0cf2SSimon Glass return fdt_property(fdt, name, val, len); 243def0cf2SSimon Glass} 253def0cf2SSimon 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 1223def0cf2SSimon 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 1443def0cf2SSimon Glass def as_bytearray(self): 1453def0cf2SSimon Glass """Get the device tree contents as a bytearray 1463def0cf2SSimon Glass 1473def0cf2SSimon Glass This can be passed directly to libfdt functions that access a 1483def0cf2SSimon Glass const void * for the device tree. 1493def0cf2SSimon Glass 1503def0cf2SSimon Glass Returns: 1513def0cf2SSimon Glass bytearray containing the device tree 1523def0cf2SSimon Glass """ 1533def0cf2SSimon Glass return bytearray(self._fdt) 1543def0cf2SSimon Glass 1553def0cf2SSimon Glass def next_node(self, nodeoffset, depth, quiet=()): 1563def0cf2SSimon Glass """Find the next subnode 1573def0cf2SSimon Glass 1583def0cf2SSimon Glass Args: 1593def0cf2SSimon Glass nodeoffset: Node offset of previous node 1603def0cf2SSimon Glass depth: On input, the depth of the node at nodeoffset. On output, the 1613def0cf2SSimon Glass depth of the returned node 1623def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1633def0cf2SSimon Glass 1643def0cf2SSimon Glass Returns: 1653def0cf2SSimon Glass The offset of the next node, if any 1663def0cf2SSimon Glass 1673def0cf2SSimon Glass Raises: 1683def0cf2SSimon Glass FdtException if no more nodes found or other error occurs 1693def0cf2SSimon Glass """ 1703def0cf2SSimon Glass return check_err(fdt_next_node(self._fdt, nodeoffset, depth), quiet) 1713def0cf2SSimon Glass 1723def0cf2SSimon Glass def first_subnode(self, nodeoffset, quiet=()): 1733def0cf2SSimon Glass """Find the first subnode of a parent node 1743def0cf2SSimon Glass 1753def0cf2SSimon Glass Args: 1763def0cf2SSimon Glass nodeoffset: Node offset of parent node 1773def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1783def0cf2SSimon Glass 1793def0cf2SSimon Glass Returns: 1803def0cf2SSimon Glass The offset of the first subnode, if any 1813def0cf2SSimon Glass 1823def0cf2SSimon Glass Raises: 1833def0cf2SSimon Glass FdtException if no subnodes found or other error occurs 1843def0cf2SSimon Glass """ 1853def0cf2SSimon Glass return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet) 1863def0cf2SSimon Glass 1873def0cf2SSimon Glass def next_subnode(self, nodeoffset, quiet=()): 1883def0cf2SSimon Glass """Find the next subnode 1893def0cf2SSimon Glass 1903def0cf2SSimon Glass Args: 1913def0cf2SSimon Glass nodeoffset: Node offset of previous subnode 1923def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1933def0cf2SSimon Glass 1943def0cf2SSimon Glass Returns: 1953def0cf2SSimon Glass The offset of the next subnode, if any 1963def0cf2SSimon Glass 1973def0cf2SSimon Glass Raises: 1983def0cf2SSimon Glass FdtException if no more subnodes found or other error occurs 1993def0cf2SSimon Glass """ 2003def0cf2SSimon Glass return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet) 2013def0cf2SSimon Glass 2023def0cf2SSimon Glass def magic(self): 2033def0cf2SSimon Glass """Return the magic word from the header 2043def0cf2SSimon Glass 2053def0cf2SSimon Glass Returns: 2063def0cf2SSimon Glass Magic word 2073def0cf2SSimon Glass """ 2083def0cf2SSimon Glass return fdt_magic(self._fdt) & 0xffffffff 2093def0cf2SSimon Glass 2103def0cf2SSimon Glass def totalsize(self): 2113def0cf2SSimon Glass """Return the total size of the device tree 2123def0cf2SSimon Glass 2133def0cf2SSimon Glass Returns: 2143def0cf2SSimon Glass Total tree size in bytes 2153def0cf2SSimon Glass """ 2163def0cf2SSimon Glass return check_err(fdt_totalsize(self._fdt)) 2173def0cf2SSimon Glass 2183def0cf2SSimon Glass def off_dt_struct(self): 2193def0cf2SSimon Glass """Return the start of the device-tree struct area 2203def0cf2SSimon Glass 2213def0cf2SSimon Glass Returns: 2223def0cf2SSimon Glass Start offset of struct area 2233def0cf2SSimon Glass """ 2243def0cf2SSimon Glass return check_err(fdt_off_dt_struct(self._fdt)) 2253def0cf2SSimon Glass 2263def0cf2SSimon Glass def off_dt_strings(self): 2273def0cf2SSimon Glass """Return the start of the device-tree string area 2283def0cf2SSimon Glass 2293def0cf2SSimon Glass Returns: 2303def0cf2SSimon Glass Start offset of string area 2313def0cf2SSimon Glass """ 2323def0cf2SSimon Glass return check_err(fdt_off_dt_strings(self._fdt)) 2333def0cf2SSimon Glass 2343def0cf2SSimon Glass def off_mem_rsvmap(self): 2353def0cf2SSimon Glass """Return the start of the memory reserve map 2363def0cf2SSimon Glass 2373def0cf2SSimon Glass Returns: 2383def0cf2SSimon Glass Start offset of memory reserve map 2393def0cf2SSimon Glass """ 2403def0cf2SSimon Glass return check_err(fdt_off_mem_rsvmap(self._fdt)) 2413def0cf2SSimon Glass 2423def0cf2SSimon Glass def version(self): 2433def0cf2SSimon Glass """Return the version of the device tree 2443def0cf2SSimon Glass 2453def0cf2SSimon Glass Returns: 2463def0cf2SSimon Glass Version number of the device tree 2473def0cf2SSimon Glass """ 2483def0cf2SSimon Glass return check_err(fdt_version(self._fdt)) 2493def0cf2SSimon Glass 2503def0cf2SSimon Glass def last_comp_version(self): 2513def0cf2SSimon Glass """Return the last compatible version of the device tree 2523def0cf2SSimon Glass 2533def0cf2SSimon Glass Returns: 2543def0cf2SSimon Glass Last compatible version number of the device tree 2553def0cf2SSimon Glass """ 2563def0cf2SSimon Glass return check_err(fdt_last_comp_version(self._fdt)) 2573def0cf2SSimon Glass 2583def0cf2SSimon Glass def boot_cpuid_phys(self): 2593def0cf2SSimon Glass """Return the physical boot CPU ID 2603def0cf2SSimon Glass 2613def0cf2SSimon Glass Returns: 2623def0cf2SSimon Glass Physical boot CPU ID 2633def0cf2SSimon Glass """ 2643def0cf2SSimon Glass return check_err(fdt_boot_cpuid_phys(self._fdt)) 2653def0cf2SSimon Glass 2663def0cf2SSimon Glass def size_dt_strings(self): 2673def0cf2SSimon Glass """Return the start of the device-tree string area 2683def0cf2SSimon Glass 2693def0cf2SSimon Glass Returns: 2703def0cf2SSimon Glass Start offset of string area 2713def0cf2SSimon Glass """ 2723def0cf2SSimon Glass return check_err(fdt_size_dt_strings(self._fdt)) 2733def0cf2SSimon Glass 2743def0cf2SSimon Glass def size_dt_struct(self): 2753def0cf2SSimon Glass """Return the start of the device-tree struct area 2763def0cf2SSimon Glass 2773def0cf2SSimon Glass Returns: 2783def0cf2SSimon Glass Start offset of struct area 2793def0cf2SSimon Glass """ 2803def0cf2SSimon Glass return check_err(fdt_size_dt_struct(self._fdt)) 2813def0cf2SSimon Glass 2823def0cf2SSimon Glass def num_mem_rsv(self, quiet=()): 2833def0cf2SSimon Glass """Return the number of memory reserve-map records 2843def0cf2SSimon Glass 2853def0cf2SSimon Glass Returns: 2863def0cf2SSimon Glass Number of memory reserve-map records 2873def0cf2SSimon Glass """ 2883def0cf2SSimon Glass return check_err(fdt_num_mem_rsv(self._fdt), quiet) 2893def0cf2SSimon Glass 2903def0cf2SSimon Glass def get_mem_rsv(self, index, quiet=()): 2913def0cf2SSimon Glass """Return the indexed memory reserve-map record 2923def0cf2SSimon Glass 2933def0cf2SSimon Glass Args: 2943def0cf2SSimon Glass index: Record to return (0=first) 2953def0cf2SSimon Glass 2963def0cf2SSimon Glass Returns: 2973def0cf2SSimon Glass Number of memory reserve-map records 2983def0cf2SSimon Glass """ 2993def0cf2SSimon Glass return check_err(fdt_get_mem_rsv(self._fdt, index), quiet) 3003def0cf2SSimon 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 3333def0cf2SSimon Glass def get_name(self, nodeoffset): 3343def0cf2SSimon Glass """Get the name of a node 3353def0cf2SSimon Glass 3363def0cf2SSimon Glass Args: 3373def0cf2SSimon Glass nodeoffset: Offset of node to check 3383def0cf2SSimon Glass 3393def0cf2SSimon Glass Returns: 3403def0cf2SSimon Glass Node name 3413def0cf2SSimon Glass 3423def0cf2SSimon Glass Raises: 3433def0cf2SSimon Glass FdtException on error (e.g. nodeoffset is invalid) 3443def0cf2SSimon Glass """ 3453def0cf2SSimon Glass return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0] 3463def0cf2SSimon 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 4013def0cf2SSimon Glass @staticmethod 4023def0cf2SSimon Glass def create_empty_tree(size, quiet=()): 4033def0cf2SSimon Glass """Create an empty device tree ready for use 40415b97f5cSMasahiro Yamada 40515b97f5cSMasahiro Yamada Args: 4063def0cf2SSimon Glass size: Size of device tree in bytes 40715b97f5cSMasahiro Yamada 40815b97f5cSMasahiro Yamada Returns: 4093def0cf2SSimon Glass Fdt object containing the device tree 41015b97f5cSMasahiro Yamada """ 4113def0cf2SSimon Glass data = bytearray(size) 4123def0cf2SSimon Glass err = check_err(fdt_create_empty_tree(data, size), quiet) 4133def0cf2SSimon Glass if err: 4143def0cf2SSimon Glass return err 4153def0cf2SSimon Glass return Fdt(data) 41615b97f5cSMasahiro Yamada 4173def0cf2SSimon Glass def open_into(self, size, quiet=()): 4183def0cf2SSimon Glass """Move the device tree into a larger or smaller space 4193def0cf2SSimon Glass 4203def0cf2SSimon Glass This creates a new device tree of size @size and moves the existing 4213def0cf2SSimon Glass device tree contents over to that. It can be used to create more space 4223def0cf2SSimon Glass in a device tree. 42315b97f5cSMasahiro Yamada 42415b97f5cSMasahiro Yamada Args: 4253def0cf2SSimon Glass size: Required new size of device tree in bytes 42615b97f5cSMasahiro Yamada """ 4273def0cf2SSimon Glass fdt = bytearray(size) 4283def0cf2SSimon Glass fdt[:len(self._fdt)] = self._fdt 4293def0cf2SSimon Glass err = check_err(fdt_open_into(self._fdt, fdt, size), quiet) 4303def0cf2SSimon Glass if err: 4313def0cf2SSimon Glass return err 4323def0cf2SSimon 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 """ 445*a1e00855SSimon Glass err = check_err(fdt_pack(self._fdt), quiet) 446*a1e00855SSimon Glass if err: 447*a1e00855SSimon Glass return err 448*a1e00855SSimon Glass del self._fdt[self.totalsize():] 449*a1e00855SSimon Glass return err 45015b97f5cSMasahiro Yamada 45115b97f5cSMasahiro Yamada def getprop(self, nodeoffset, prop_name, quiet=()): 45215b97f5cSMasahiro Yamada """Get a property from a node 45315b97f5cSMasahiro Yamada 45415b97f5cSMasahiro Yamada Args: 45515b97f5cSMasahiro Yamada nodeoffset: Node offset containing property to get 45615b97f5cSMasahiro Yamada prop_name: Name of property to get 45715b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 45815b97f5cSMasahiro Yamada 45915b97f5cSMasahiro Yamada Returns: 4603def0cf2SSimon Glass Value of property as a string, or -ve error number 46115b97f5cSMasahiro Yamada 46215b97f5cSMasahiro Yamada Raises: 46315b97f5cSMasahiro Yamada FdtError if any error occurs (e.g. the property is not found) 46415b97f5cSMasahiro Yamada """ 46515b97f5cSMasahiro Yamada pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 46615b97f5cSMasahiro Yamada quiet) 46715b97f5cSMasahiro Yamada if isinstance(pdata, (int)): 46815b97f5cSMasahiro Yamada return pdata 4693def0cf2SSimon Glass return str(pdata[0]) 4703def0cf2SSimon Glass 4713def0cf2SSimon Glass def getprop_obj(self, nodeoffset, prop_name, quiet=()): 4723def0cf2SSimon Glass """Get a property from a node as a Property object 4733def0cf2SSimon Glass 4743def0cf2SSimon Glass Args: 4753def0cf2SSimon Glass nodeoffset: Node offset containing property to get 4763def0cf2SSimon Glass prop_name: Name of property to get 4773def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 4783def0cf2SSimon Glass 4793def0cf2SSimon Glass Returns: 4803def0cf2SSimon Glass Property object, or None if not found 4813def0cf2SSimon Glass 4823def0cf2SSimon Glass Raises: 4833def0cf2SSimon Glass FdtError if any error occurs (e.g. the property is not found) 4843def0cf2SSimon Glass """ 4853def0cf2SSimon Glass pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 4863def0cf2SSimon Glass quiet) 4873def0cf2SSimon Glass if isinstance(pdata, (int)): 4883def0cf2SSimon Glass return None 4893def0cf2SSimon Glass return Property(prop_name, bytearray(pdata[0])) 49015b97f5cSMasahiro Yamada 49115b97f5cSMasahiro Yamada def get_phandle(self, nodeoffset): 49215b97f5cSMasahiro Yamada """Get the phandle of a node 49315b97f5cSMasahiro Yamada 49415b97f5cSMasahiro Yamada Args: 49515b97f5cSMasahiro Yamada nodeoffset: Node offset to check 49615b97f5cSMasahiro Yamada 49715b97f5cSMasahiro Yamada Returns: 49815b97f5cSMasahiro Yamada phandle of node, or 0 if the node has no phandle or another error 49915b97f5cSMasahiro Yamada occurs 50015b97f5cSMasahiro Yamada """ 50115b97f5cSMasahiro Yamada return fdt_get_phandle(self._fdt, nodeoffset) 50215b97f5cSMasahiro Yamada 50315b97f5cSMasahiro Yamada def parent_offset(self, nodeoffset, quiet=()): 50415b97f5cSMasahiro Yamada """Get the offset of a node's parent 50515b97f5cSMasahiro Yamada 50615b97f5cSMasahiro Yamada Args: 50715b97f5cSMasahiro Yamada nodeoffset: Node offset to check 50815b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 50915b97f5cSMasahiro Yamada 51015b97f5cSMasahiro Yamada Returns: 51115b97f5cSMasahiro Yamada The offset of the parent node, if any 51215b97f5cSMasahiro Yamada 51315b97f5cSMasahiro Yamada Raises: 51415b97f5cSMasahiro Yamada FdtException if no parent found or other error occurs 51515b97f5cSMasahiro Yamada """ 51615b97f5cSMasahiro Yamada return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet) 51715b97f5cSMasahiro Yamada 5183def0cf2SSimon Glass def set_name(self, nodeoffset, name, quiet=()): 5193def0cf2SSimon Glass """Set the name of a node 5203def0cf2SSimon Glass 5213def0cf2SSimon Glass Args: 5223def0cf2SSimon Glass nodeoffset: Node offset of node to update 5233def0cf2SSimon Glass name: New node name 5243def0cf2SSimon Glass 5253def0cf2SSimon Glass Returns: 5263def0cf2SSimon Glass Error code, or 0 if OK 5273def0cf2SSimon Glass 5283def0cf2SSimon Glass Raises: 5293def0cf2SSimon Glass FdtException if no parent found or other error occurs 5303def0cf2SSimon Glass """ 5313def0cf2SSimon Glass return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet) 5323def0cf2SSimon Glass 5333def0cf2SSimon Glass def setprop(self, nodeoffset, prop_name, val, quiet=()): 5343def0cf2SSimon Glass """Set the value of a property 5353def0cf2SSimon Glass 5363def0cf2SSimon Glass Args: 5373def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5383def0cf2SSimon Glass prop_name: Name of property 5393def0cf2SSimon Glass val: Value to write (string or bytearray) 5403def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5413def0cf2SSimon Glass 5423def0cf2SSimon Glass Returns: 5433def0cf2SSimon Glass Error code, or 0 if OK 5443def0cf2SSimon Glass 5453def0cf2SSimon Glass Raises: 5463def0cf2SSimon Glass FdtException if no parent found or other error occurs 5473def0cf2SSimon Glass """ 5483def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, 5493def0cf2SSimon Glass len(val)), quiet) 5503def0cf2SSimon Glass 5513def0cf2SSimon Glass def setprop_u32(self, nodeoffset, prop_name, val, quiet=()): 5523def0cf2SSimon Glass """Set the value of a property 5533def0cf2SSimon Glass 5543def0cf2SSimon Glass Args: 5553def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5563def0cf2SSimon Glass prop_name: Name of property 5573def0cf2SSimon Glass val: Value to write (integer) 5583def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5593def0cf2SSimon Glass 5603def0cf2SSimon Glass Returns: 5613def0cf2SSimon Glass Error code, or 0 if OK 5623def0cf2SSimon Glass 5633def0cf2SSimon Glass Raises: 5643def0cf2SSimon Glass FdtException if no parent found or other error occurs 5653def0cf2SSimon Glass """ 5663def0cf2SSimon Glass return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val), 5673def0cf2SSimon Glass quiet) 5683def0cf2SSimon Glass 5693def0cf2SSimon Glass def setprop_u64(self, nodeoffset, prop_name, val, quiet=()): 5703def0cf2SSimon Glass """Set the value of a property 5713def0cf2SSimon Glass 5723def0cf2SSimon Glass Args: 5733def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5743def0cf2SSimon Glass prop_name: Name of property 5753def0cf2SSimon Glass val: Value to write (integer) 5763def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5773def0cf2SSimon Glass 5783def0cf2SSimon Glass Returns: 5793def0cf2SSimon Glass Error code, or 0 if OK 5803def0cf2SSimon Glass 5813def0cf2SSimon Glass Raises: 5823def0cf2SSimon Glass FdtException if no parent found or other error occurs 5833def0cf2SSimon Glass """ 5843def0cf2SSimon Glass return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), 5853def0cf2SSimon Glass quiet) 5863def0cf2SSimon Glass 5873def0cf2SSimon Glass def setprop_str(self, nodeoffset, prop_name, val, quiet=()): 5883def0cf2SSimon Glass """Set the string value of a property 5893def0cf2SSimon Glass 5903def0cf2SSimon Glass The property is set to the string, with a nul terminator added 5913def0cf2SSimon Glass 5923def0cf2SSimon Glass Args: 5933def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5943def0cf2SSimon Glass prop_name: Name of property 5953def0cf2SSimon Glass val: Value to write (string without nul terminator) 5963def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5973def0cf2SSimon Glass 5983def0cf2SSimon Glass Returns: 5993def0cf2SSimon Glass Error code, or 0 if OK 6003def0cf2SSimon Glass 6013def0cf2SSimon Glass Raises: 6023def0cf2SSimon Glass FdtException if no parent found or other error occurs 6033def0cf2SSimon Glass """ 6043def0cf2SSimon Glass val += '\0' 6053def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, 6063def0cf2SSimon Glass val, len(val)), quiet) 6073def0cf2SSimon Glass 6083def0cf2SSimon Glass def delprop(self, nodeoffset, prop_name): 6093def0cf2SSimon Glass """Delete a property from a node 6103def0cf2SSimon Glass 6113def0cf2SSimon Glass Args: 6123def0cf2SSimon Glass nodeoffset: Node offset containing property to delete 6133def0cf2SSimon Glass prop_name: Name of property to delete 6143def0cf2SSimon Glass 6153def0cf2SSimon Glass Raises: 6163def0cf2SSimon Glass FdtError if the property does not exist, or another error occurs 6173def0cf2SSimon Glass """ 6183def0cf2SSimon Glass return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name)) 6193def0cf2SSimon Glass 62015b97f5cSMasahiro Yamada def node_offset_by_phandle(self, phandle, quiet=()): 62115b97f5cSMasahiro Yamada """Get the offset of a node with the given phandle 62215b97f5cSMasahiro Yamada 62315b97f5cSMasahiro Yamada Args: 62415b97f5cSMasahiro Yamada phandle: Phandle to search for 62515b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 62615b97f5cSMasahiro Yamada 62715b97f5cSMasahiro Yamada Returns: 62815b97f5cSMasahiro Yamada The offset of node with that phandle, if any 62915b97f5cSMasahiro Yamada 63015b97f5cSMasahiro Yamada Raises: 63115b97f5cSMasahiro Yamada FdtException if no node found or other error occurs 63215b97f5cSMasahiro Yamada """ 63315b97f5cSMasahiro Yamada return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet) 63415b97f5cSMasahiro Yamada 6353def0cf2SSimon Glass 6363def0cf2SSimon Glassclass Property(bytearray): 63715b97f5cSMasahiro Yamada """Holds a device tree property name and value. 63815b97f5cSMasahiro Yamada 63915b97f5cSMasahiro Yamada This holds a copy of a property taken from the device tree. It does not 64015b97f5cSMasahiro Yamada reference the device tree, so if anything changes in the device tree, 64115b97f5cSMasahiro Yamada a Property object will remain valid. 64215b97f5cSMasahiro Yamada 64315b97f5cSMasahiro Yamada Properties: 64415b97f5cSMasahiro Yamada name: Property name 6453def0cf2SSimon Glass value: Property value as a bytearray 64615b97f5cSMasahiro Yamada """ 64715b97f5cSMasahiro Yamada def __init__(self, name, value): 6483def0cf2SSimon Glass bytearray.__init__(self, value) 64915b97f5cSMasahiro Yamada self.name = name 6503def0cf2SSimon Glass 6513def0cf2SSimon Glass def as_cell(self, fmt): 6523def0cf2SSimon Glass return struct.unpack('>' + fmt, self)[0] 6533def0cf2SSimon Glass 6543def0cf2SSimon Glass def as_uint32(self): 6553def0cf2SSimon Glass return self.as_cell('L') 6563def0cf2SSimon Glass 6573def0cf2SSimon Glass def as_int32(self): 6583def0cf2SSimon Glass return self.as_cell('l') 6593def0cf2SSimon Glass 6603def0cf2SSimon Glass def as_uint64(self): 6613def0cf2SSimon Glass return self.as_cell('Q') 6623def0cf2SSimon Glass 6633def0cf2SSimon Glass def as_int64(self): 6643def0cf2SSimon Glass return self.as_cell('q') 6653def0cf2SSimon Glass 6663def0cf2SSimon Glass def as_str(self): 6673def0cf2SSimon Glass return self[:-1] 6683def0cf2SSimon Glass 6693def0cf2SSimon Glass 6703def0cf2SSimon Glassclass FdtSw(object): 6713def0cf2SSimon Glass """Software interface to create a device tree from scratch 6723def0cf2SSimon Glass 6733def0cf2SSimon Glass The methods in this class work by adding to an existing 'partial' device 6743def0cf2SSimon Glass tree buffer of a fixed size created by instantiating this class. When the 6753def0cf2SSimon Glass tree is complete, call finish() to complete the device tree so that it can 6763def0cf2SSimon Glass be used. 6773def0cf2SSimon Glass 6783def0cf2SSimon Glass Similarly with nodes, a new node is started with begin_node() and finished 6793def0cf2SSimon Glass with end_node(). 6803def0cf2SSimon Glass 6813def0cf2SSimon Glass The context manager functions can be used to make this a bit easier: 6823def0cf2SSimon Glass 6833def0cf2SSimon Glass # First create the device tree with a node and property: 6843def0cf2SSimon Glass with FdtSw(small_size) as sw: 6853def0cf2SSimon Glass with sw.AddNode('node'): 6863def0cf2SSimon Glass sw.property_u32('reg', 2) 6873def0cf2SSimon Glass fdt = sw.AsFdt() 6883def0cf2SSimon Glass 6893def0cf2SSimon Glass # Now we can use it as a real device tree 6903def0cf2SSimon Glass fdt.setprop_u32(0, 'reg', 3) 6913def0cf2SSimon Glass """ 6923def0cf2SSimon Glass def __init__(self, size, quiet=()): 6933def0cf2SSimon Glass fdtrw = bytearray(size) 6943def0cf2SSimon Glass err = check_err(fdt_create(fdtrw, size)) 6953def0cf2SSimon Glass if err: 6963def0cf2SSimon Glass return err 6973def0cf2SSimon Glass self._fdtrw = fdtrw 6983def0cf2SSimon Glass 6993def0cf2SSimon Glass def __enter__(self): 7003def0cf2SSimon Glass """Contact manager to use to create a device tree via software""" 7013def0cf2SSimon Glass return self 7023def0cf2SSimon Glass 7033def0cf2SSimon Glass def __exit__(self, type, value, traceback): 7043def0cf2SSimon Glass check_err(fdt_finish(self._fdtrw)) 7053def0cf2SSimon Glass 7063def0cf2SSimon Glass def AsFdt(self): 7073def0cf2SSimon Glass """Convert a FdtSw into an Fdt so it can be accessed as normal 7083def0cf2SSimon Glass 7093def0cf2SSimon Glass Note that finish() must be called before this function will work. If 7103def0cf2SSimon Glass you are using the context manager (see 'with' code in the FdtSw class 7113def0cf2SSimon Glass comment) then this will happen automatically. 7123def0cf2SSimon Glass 7133def0cf2SSimon Glass Returns: 7143def0cf2SSimon Glass Fdt object allowing access to the newly created device tree 7153def0cf2SSimon Glass """ 7163def0cf2SSimon Glass return Fdt(self._fdtrw) 7173def0cf2SSimon Glass 7183def0cf2SSimon Glass def resize(self, size, quiet=()): 7193def0cf2SSimon Glass """Resize the buffer to accommodate a larger tree 7203def0cf2SSimon Glass 7213def0cf2SSimon Glass Args: 7223def0cf2SSimon Glass size: New size of tree 7233def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 7243def0cf2SSimon Glass 7253def0cf2SSimon Glass Raises: 7263def0cf2SSimon Glass FdtException if no node found or other error occurs 7273def0cf2SSimon Glass """ 7283def0cf2SSimon Glass fdt = bytearray(size) 7293def0cf2SSimon Glass fdt[:len(self._fdtrw)] = self._fdtrw 7303def0cf2SSimon Glass err = check_err(fdt_resize(self._fdtrw, fdt, size), quiet) 7313def0cf2SSimon Glass if err: 7323def0cf2SSimon Glass return err 7333def0cf2SSimon Glass self._fdtrw = fdt 7343def0cf2SSimon Glass 7353def0cf2SSimon Glass def add_reservemap_entry(self, addr, size, quiet=()): 7363def0cf2SSimon Glass """Add a new memory reserve map entry 7373def0cf2SSimon Glass 7383def0cf2SSimon Glass Once finished adding, you must call finish_reservemap(). 7393def0cf2SSimon Glass 7403def0cf2SSimon Glass Args: 7413def0cf2SSimon Glass addr: 64-bit start address 7423def0cf2SSimon Glass size: 64-bit size 7433def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 7443def0cf2SSimon Glass 7453def0cf2SSimon Glass Raises: 7463def0cf2SSimon Glass FdtException if no node found or other error occurs 7473def0cf2SSimon Glass """ 7483def0cf2SSimon Glass return check_err(fdt_add_reservemap_entry(self._fdtrw, addr, size), 7493def0cf2SSimon Glass quiet) 7503def0cf2SSimon Glass 7513def0cf2SSimon Glass def finish_reservemap(self, quiet=()): 7523def0cf2SSimon Glass """Indicate that there are no more reserve map entries to add 7533def0cf2SSimon Glass 7543def0cf2SSimon Glass Args: 7553def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 7563def0cf2SSimon Glass 7573def0cf2SSimon Glass Raises: 7583def0cf2SSimon Glass FdtException if no node found or other error occurs 7593def0cf2SSimon Glass """ 7603def0cf2SSimon Glass return check_err(fdt_finish_reservemap(self._fdtrw), quiet) 7613def0cf2SSimon Glass 7623def0cf2SSimon Glass def begin_node(self, name, quiet=()): 7633def0cf2SSimon Glass """Begin a new node 7643def0cf2SSimon Glass 7653def0cf2SSimon Glass Use this before adding properties to the node. Then call end_node() to 7663def0cf2SSimon Glass finish it. You can also use the context manager as shown in the FdtSw 7673def0cf2SSimon Glass class comment. 7683def0cf2SSimon Glass 7693def0cf2SSimon Glass Args: 7703def0cf2SSimon Glass name: Name of node to begin 7713def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 7723def0cf2SSimon Glass 7733def0cf2SSimon Glass Raises: 7743def0cf2SSimon Glass FdtException if no node found or other error occurs 7753def0cf2SSimon Glass """ 7763def0cf2SSimon Glass return check_err(fdt_begin_node(self._fdtrw, name), quiet) 7773def0cf2SSimon Glass 7783def0cf2SSimon Glass def property_string(self, name, string, quiet=()): 7793def0cf2SSimon Glass """Add a property with a string value 7803def0cf2SSimon Glass 7813def0cf2SSimon Glass The string will be nul-terminated when written to the device tree 7823def0cf2SSimon Glass 7833def0cf2SSimon Glass Args: 7843def0cf2SSimon Glass name: Name of property to add 7853def0cf2SSimon Glass string: String value of property 7863def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 7873def0cf2SSimon Glass 7883def0cf2SSimon Glass Raises: 7893def0cf2SSimon Glass FdtException if no node found or other error occurs 7903def0cf2SSimon Glass """ 7913def0cf2SSimon Glass return check_err(fdt_property_string(self._fdtrw, name, string), quiet) 7923def0cf2SSimon Glass 7933def0cf2SSimon Glass def property_u32(self, name, val, quiet=()): 7943def0cf2SSimon Glass """Add a property with a 32-bit value 7953def0cf2SSimon Glass 7963def0cf2SSimon Glass Write a single-cell value to the device tree 7973def0cf2SSimon Glass 7983def0cf2SSimon Glass Args: 7993def0cf2SSimon Glass name: Name of property to add 8003def0cf2SSimon Glass val: Value of property 8013def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8023def0cf2SSimon Glass 8033def0cf2SSimon Glass Raises: 8043def0cf2SSimon Glass FdtException if no node found or other error occurs 8053def0cf2SSimon Glass """ 8063def0cf2SSimon Glass return check_err(fdt_property_u32(self._fdtrw, name, val), quiet) 8073def0cf2SSimon Glass 8083def0cf2SSimon Glass def property_u64(self, name, val, quiet=()): 8093def0cf2SSimon Glass """Add a property with a 64-bit value 8103def0cf2SSimon Glass 8113def0cf2SSimon Glass Write a double-cell value to the device tree in big-endian format 8123def0cf2SSimon Glass 8133def0cf2SSimon Glass Args: 8143def0cf2SSimon Glass name: Name of property to add 8153def0cf2SSimon Glass val: Value of property 8163def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8173def0cf2SSimon Glass 8183def0cf2SSimon Glass Raises: 8193def0cf2SSimon Glass FdtException if no node found or other error occurs 8203def0cf2SSimon Glass """ 8213def0cf2SSimon Glass return check_err(fdt_property_u64(self._fdtrw, name, val), quiet) 8223def0cf2SSimon Glass 8233def0cf2SSimon Glass def property_cell(self, name, val, quiet=()): 8243def0cf2SSimon Glass """Add a property with a single-cell value 8253def0cf2SSimon Glass 8263def0cf2SSimon Glass Write a single-cell value to the device tree 8273def0cf2SSimon Glass 8283def0cf2SSimon Glass Args: 8293def0cf2SSimon Glass name: Name of property to add 8303def0cf2SSimon Glass val: Value of property 8313def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8323def0cf2SSimon Glass 8333def0cf2SSimon Glass Raises: 8343def0cf2SSimon Glass FdtException if no node found or other error occurs 8353def0cf2SSimon Glass """ 8363def0cf2SSimon Glass return check_err(fdt_property_cell(self._fdtrw, name, val), quiet) 8373def0cf2SSimon Glass 8383def0cf2SSimon Glass def property(self, name, val, quiet=()): 8393def0cf2SSimon Glass """Add a property 8403def0cf2SSimon Glass 8413def0cf2SSimon Glass Write a new property with the given value to the device tree. The value 8423def0cf2SSimon Glass is taken as is and is not nul-terminated 8433def0cf2SSimon Glass 8443def0cf2SSimon Glass Args: 8453def0cf2SSimon Glass name: Name of property to add 8463def0cf2SSimon Glass val: Value of property 8473def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8483def0cf2SSimon Glass 8493def0cf2SSimon Glass Raises: 8503def0cf2SSimon Glass FdtException if no node found or other error occurs 8513def0cf2SSimon Glass """ 8523def0cf2SSimon Glass return check_err(_fdt_property(self._fdtrw, name, val, len(val)), quiet) 8533def0cf2SSimon Glass 8543def0cf2SSimon Glass def end_node(self, quiet=()): 8553def0cf2SSimon Glass """End a node 8563def0cf2SSimon Glass 8573def0cf2SSimon Glass Use this after adding properties to a node to close it off. You can also 8583def0cf2SSimon Glass use the context manager as shown in the FdtSw class comment. 8593def0cf2SSimon Glass 8603def0cf2SSimon Glass Args: 8613def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8623def0cf2SSimon Glass 8633def0cf2SSimon Glass Raises: 8643def0cf2SSimon Glass FdtException if no node found or other error occurs 8653def0cf2SSimon Glass """ 8663def0cf2SSimon Glass return check_err(fdt_end_node(self._fdtrw), quiet) 8673def0cf2SSimon Glass 8683def0cf2SSimon Glass def finish(self, quiet=()): 8693def0cf2SSimon Glass """Finish writing the device tree 8703def0cf2SSimon Glass 8713def0cf2SSimon Glass This closes off the device tree ready for use 8723def0cf2SSimon Glass 8733def0cf2SSimon Glass Args: 8743def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8753def0cf2SSimon Glass 8763def0cf2SSimon Glass Raises: 8773def0cf2SSimon Glass FdtException if no node found or other error occurs 8783def0cf2SSimon Glass """ 8793def0cf2SSimon Glass return check_err(fdt_finish(self._fdtrw), quiet) 8803def0cf2SSimon Glass 8813def0cf2SSimon Glass def AddNode(self, name): 8823def0cf2SSimon Glass """Create a new context for adding a node 8833def0cf2SSimon Glass 8843def0cf2SSimon Glass When used in a 'with' clause this starts a new node and finishes it 8853def0cf2SSimon Glass afterward. 8863def0cf2SSimon Glass 8873def0cf2SSimon Glass Args: 8883def0cf2SSimon Glass name: Name of node to add 8893def0cf2SSimon Glass """ 8903def0cf2SSimon Glass return NodeAdder(self._fdtrw, name) 8913def0cf2SSimon Glass 8923def0cf2SSimon Glass 8933def0cf2SSimon Glassclass NodeAdder(): 8943def0cf2SSimon Glass """Class to provide a node context 8953def0cf2SSimon Glass 8963def0cf2SSimon Glass This allows you to add nodes in a more natural way: 8973def0cf2SSimon Glass 8983def0cf2SSimon Glass with fdtsw.AddNode('name'): 8993def0cf2SSimon Glass fdtsw.property_string('test', 'value') 9003def0cf2SSimon Glass 9013def0cf2SSimon Glass The node is automatically completed with a call to end_node() when the 9023def0cf2SSimon Glass context exits. 9033def0cf2SSimon Glass """ 9043def0cf2SSimon Glass def __init__(self, fdt, name): 9053def0cf2SSimon Glass self._fdt = fdt 9063def0cf2SSimon Glass self._name = name 9073def0cf2SSimon Glass 9083def0cf2SSimon Glass def __enter__(self): 9093def0cf2SSimon Glass check_err(fdt_begin_node(self._fdt, self._name)) 9103def0cf2SSimon Glass 9113def0cf2SSimon Glass def __exit__(self, type, value, traceback): 9123def0cf2SSimon Glass check_err(fdt_end_node(self._fdt)) 91315b97f5cSMasahiro Yamada%} 91415b97f5cSMasahiro Yamada 91515b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func; 91615b97f5cSMasahiro Yamada 91715b97f5cSMasahiro Yamadatypedef int fdt32_t; 91815b97f5cSMasahiro Yamada 91915b97f5cSMasahiro Yamada%include "libfdt/fdt.h" 92015b97f5cSMasahiro Yamada 92115b97f5cSMasahiro Yamada%include "typemaps.i" 92215b97f5cSMasahiro Yamada 92315b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */ 92415b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) { 92515b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 92615b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 92715b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 92815b97f5cSMasahiro Yamada } 92915b97f5cSMasahiro Yamada $1 = (void *)PyByteArray_AsString($input); 93015b97f5cSMasahiro Yamada fdt = $1; 93115b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 93215b97f5cSMasahiro Yamada} 93315b97f5cSMasahiro Yamada 93415b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */ 93515b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) { 93615b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 93715b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 93815b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 93915b97f5cSMasahiro Yamada } 94015b97f5cSMasahiro Yamada $1 = PyByteArray_AsString($input); 94115b97f5cSMasahiro Yamada fdt = $1; 94215b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 94315b97f5cSMasahiro Yamada} 94415b97f5cSMasahiro Yamada 9453def0cf2SSimon Glass/* typemap used for fdt_get_property_by_offset() */ 94615b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) { 94715b97f5cSMasahiro Yamada PyObject *buff; 94815b97f5cSMasahiro Yamada 94915b97f5cSMasahiro Yamada if ($1) { 95015b97f5cSMasahiro Yamada resultobj = PyString_FromString( 95115b97f5cSMasahiro Yamada fdt_string(fdt1, fdt32_to_cpu($1->nameoff))); 95215b97f5cSMasahiro Yamada buff = PyByteArray_FromStringAndSize( 95315b97f5cSMasahiro Yamada (const char *)($1 + 1), fdt32_to_cpu($1->len)); 95415b97f5cSMasahiro Yamada resultobj = SWIG_Python_AppendOutput(resultobj, buff); 95515b97f5cSMasahiro Yamada } 95615b97f5cSMasahiro Yamada} 95715b97f5cSMasahiro Yamada 95815b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp }; 95915b97f5cSMasahiro Yamada 96015b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */ 96115b97f5cSMasahiro Yamada%typemap(out) (const void *) { 96215b97f5cSMasahiro Yamada if (!$1) 96315b97f5cSMasahiro Yamada $result = Py_None; 96415b97f5cSMasahiro Yamada else 96515b97f5cSMasahiro Yamada $result = Py_BuildValue("s#", $1, *arg4); 96615b97f5cSMasahiro Yamada} 96715b97f5cSMasahiro Yamada 9683def0cf2SSimon Glass/* typemap used for fdt_setprop() */ 9693def0cf2SSimon Glass%typemap(in) (const void *val) { 9703def0cf2SSimon Glass $1 = PyString_AsString($input); /* char *str */ 9713def0cf2SSimon Glass} 9723def0cf2SSimon Glass 9733def0cf2SSimon Glass/* typemap used for fdt_add_reservemap_entry() */ 9743def0cf2SSimon Glass%typemap(in) uint64_t { 9753def0cf2SSimon Glass $1 = PyLong_AsUnsignedLong($input); 9763def0cf2SSimon Glass} 9773def0cf2SSimon Glass 9783def0cf2SSimon Glass/* typemaps used for fdt_next_node() */ 9793def0cf2SSimon Glass%typemap(in, numinputs=1) int *depth (int depth) { 9803def0cf2SSimon Glass depth = (int) PyInt_AsLong($input); 9813def0cf2SSimon Glass $1 = &depth; 9823def0cf2SSimon Glass} 9833def0cf2SSimon Glass 9843def0cf2SSimon Glass%typemap(argout) int *depth { 9853def0cf2SSimon Glass PyObject *val = Py_BuildValue("i", *arg$argnum); 9863def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 9873def0cf2SSimon Glass} 9883def0cf2SSimon Glass 9893def0cf2SSimon Glass%apply int *depth { int *depth }; 9903def0cf2SSimon Glass 9913def0cf2SSimon Glass/* typemaps for fdt_get_mem_rsv */ 9923def0cf2SSimon Glass%typemap(in, numinputs=0) uint64_t * (uint64_t temp) { 9933def0cf2SSimon Glass $1 = &temp; 9943def0cf2SSimon Glass} 9953def0cf2SSimon Glass 9963def0cf2SSimon Glass%typemap(argout) uint64_t * { 9973def0cf2SSimon Glass PyObject *val = PyLong_FromUnsignedLong(*arg$argnum); 9983def0cf2SSimon Glass if (!result) { 9993def0cf2SSimon Glass if (PyTuple_GET_SIZE(resultobj) == 0) 10003def0cf2SSimon Glass resultobj = val; 10013def0cf2SSimon Glass else 10023def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 10033def0cf2SSimon Glass } 10043def0cf2SSimon Glass} 10053def0cf2SSimon Glass 100615b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */ 100715b97f5cSMasahiro Yamada%warnfilter(302) fdt_property; 100815b97f5cSMasahiro Yamada 100915b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */ 101015b97f5cSMasahiro Yamadaint fdt_magic(const void *fdt); 101115b97f5cSMasahiro Yamadaint fdt_totalsize(const void *fdt); 101215b97f5cSMasahiro Yamadaint fdt_off_dt_struct(const void *fdt); 101315b97f5cSMasahiro Yamadaint fdt_off_dt_strings(const void *fdt); 101415b97f5cSMasahiro Yamadaint fdt_off_mem_rsvmap(const void *fdt); 101515b97f5cSMasahiro Yamadaint fdt_version(const void *fdt); 101615b97f5cSMasahiro Yamadaint fdt_last_comp_version(const void *fdt); 101715b97f5cSMasahiro Yamadaint fdt_boot_cpuid_phys(const void *fdt); 101815b97f5cSMasahiro Yamadaint fdt_size_dt_strings(const void *fdt); 101915b97f5cSMasahiro Yamadaint fdt_size_dt_struct(const void *fdt); 10203def0cf2SSimon Glassint fdt_property_string(void *fdt, const char *name, const char *val); 10213def0cf2SSimon Glassint fdt_property_cell(void *fdt, const char *name, uint32_t val); 10223def0cf2SSimon Glass 10233def0cf2SSimon Glass/* 10243def0cf2SSimon Glass * This function has a stub since the name fdt_property is used for both a 10253def0cf2SSimon Glass * function and a struct, which confuses SWIG. 10263def0cf2SSimon Glass */ 10273def0cf2SSimon Glassint _fdt_property(void *fdt, const char *name, const char *val, int len); 102815b97f5cSMasahiro Yamada 102915b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h> 1030