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 */ 21*50c59522SSimon Glassstatic int fdt_property_stub(void *fdt, const char *name, const char *val, 22*50c59522SSimon Glass int len) 233def0cf2SSimon Glass{ 243def0cf2SSimon Glass return fdt_property(fdt, name, val, len); 253def0cf2SSimon Glass} 263def0cf2SSimon Glass 2715b97f5cSMasahiro Yamada%} 2815b97f5cSMasahiro Yamada 2915b97f5cSMasahiro Yamada%pythoncode %{ 3015b97f5cSMasahiro Yamada 3115b97f5cSMasahiro Yamadaimport struct 3215b97f5cSMasahiro Yamada 3315b97f5cSMasahiro Yamada# Error codes, corresponding to FDT_ERR_... in libfdt.h 3415b97f5cSMasahiro Yamada(NOTFOUND, 3515b97f5cSMasahiro Yamada EXISTS, 3615b97f5cSMasahiro Yamada NOSPACE, 3715b97f5cSMasahiro Yamada BADOFFSET, 3815b97f5cSMasahiro Yamada BADPATH, 3915b97f5cSMasahiro Yamada BADPHANDLE, 4015b97f5cSMasahiro Yamada BADSTATE, 4115b97f5cSMasahiro Yamada TRUNCATED, 4215b97f5cSMasahiro Yamada BADMAGIC, 4315b97f5cSMasahiro Yamada BADVERSION, 4415b97f5cSMasahiro Yamada BADSTRUCTURE, 4515b97f5cSMasahiro Yamada BADLAYOUT, 4615b97f5cSMasahiro Yamada INTERNAL, 4715b97f5cSMasahiro Yamada BADNCELLS, 4815b97f5cSMasahiro Yamada BADVALUE, 4915b97f5cSMasahiro Yamada BADOVERLAY, 5015b97f5cSMasahiro Yamada NOPHANDLES) = QUIET_ALL = range(1, 18) 5115b97f5cSMasahiro Yamada# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions 5215b97f5cSMasahiro Yamada# altogether. All # functions passed this value will return an error instead 5315b97f5cSMasahiro Yamada# of raising an exception. 5415b97f5cSMasahiro Yamada 5515b97f5cSMasahiro Yamada# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors, 5615b97f5cSMasahiro Yamada# instead of raising an exception. 5715b97f5cSMasahiro YamadaQUIET_NOTFOUND = (NOTFOUND,) 58*50c59522SSimon GlassQUIET_NOSPACE = (NOSPACE,) 5915b97f5cSMasahiro Yamada 6015b97f5cSMasahiro Yamada 6115b97f5cSMasahiro Yamadaclass FdtException(Exception): 6215b97f5cSMasahiro Yamada """An exception caused by an error such as one of the codes above""" 6315b97f5cSMasahiro Yamada def __init__(self, err): 6415b97f5cSMasahiro Yamada self.err = err 6515b97f5cSMasahiro Yamada 6615b97f5cSMasahiro Yamada def __str__(self): 6715b97f5cSMasahiro Yamada return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err)) 6815b97f5cSMasahiro Yamada 6915b97f5cSMasahiro Yamadadef strerror(fdt_err): 7015b97f5cSMasahiro Yamada """Get the string for an error number 7115b97f5cSMasahiro Yamada 7215b97f5cSMasahiro Yamada Args: 7315b97f5cSMasahiro Yamada fdt_err: Error number (-ve) 7415b97f5cSMasahiro Yamada 7515b97f5cSMasahiro Yamada Returns: 7615b97f5cSMasahiro Yamada String containing the associated error 7715b97f5cSMasahiro Yamada """ 7815b97f5cSMasahiro Yamada return fdt_strerror(fdt_err) 7915b97f5cSMasahiro Yamada 8015b97f5cSMasahiro Yamadadef check_err(val, quiet=()): 8115b97f5cSMasahiro Yamada """Raise an error if the return value is -ve 8215b97f5cSMasahiro Yamada 8315b97f5cSMasahiro Yamada This is used to check for errors returned by libfdt C functions. 8415b97f5cSMasahiro Yamada 8515b97f5cSMasahiro Yamada Args: 8615b97f5cSMasahiro Yamada val: Return value from a libfdt function 8715b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 8815b97f5cSMasahiro Yamada 8915b97f5cSMasahiro Yamada Returns: 9015b97f5cSMasahiro Yamada val if val >= 0 9115b97f5cSMasahiro Yamada 9215b97f5cSMasahiro Yamada Raises 9315b97f5cSMasahiro Yamada FdtException if val < 0 9415b97f5cSMasahiro Yamada """ 9515b97f5cSMasahiro Yamada if val < 0: 9615b97f5cSMasahiro Yamada if -val not in quiet: 9715b97f5cSMasahiro Yamada raise FdtException(val) 9815b97f5cSMasahiro Yamada return val 9915b97f5cSMasahiro Yamada 10015b97f5cSMasahiro Yamadadef check_err_null(val, quiet=()): 10115b97f5cSMasahiro Yamada """Raise an error if the return value is NULL 10215b97f5cSMasahiro Yamada 10315b97f5cSMasahiro Yamada This is used to check for a NULL return value from certain libfdt C 10415b97f5cSMasahiro Yamada functions 10515b97f5cSMasahiro Yamada 10615b97f5cSMasahiro Yamada Args: 10715b97f5cSMasahiro Yamada val: Return value from a libfdt function 10815b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 10915b97f5cSMasahiro Yamada 11015b97f5cSMasahiro Yamada Returns: 11115b97f5cSMasahiro Yamada val if val is a list, None if not 11215b97f5cSMasahiro Yamada 11315b97f5cSMasahiro Yamada Raises 11415b97f5cSMasahiro Yamada FdtException if val indicates an error was reported and the error 11515b97f5cSMasahiro Yamada is not in @quiet. 11615b97f5cSMasahiro Yamada """ 11715b97f5cSMasahiro Yamada # Normally a list is returned which contains the data and its length. 11815b97f5cSMasahiro Yamada # If we get just an integer error code, it means the function failed. 11915b97f5cSMasahiro Yamada if not isinstance(val, list): 12015b97f5cSMasahiro Yamada if -val not in quiet: 12115b97f5cSMasahiro Yamada raise FdtException(val) 12215b97f5cSMasahiro Yamada return val 12315b97f5cSMasahiro Yamada 124*50c59522SSimon Glassclass FdtRo(object): 125*50c59522SSimon Glass """Class for a read-only device-tree 1263def0cf2SSimon Glass 127*50c59522SSimon Glass This is a base class used by FdtRw (read-write access) and FdtSw 128*50c59522SSimon Glass (sequential-write access). It implements read-only access to the 129*50c59522SSimon Glass device tree. 13015b97f5cSMasahiro Yamada 131*50c59522SSimon Glass Here are the three classes and when you should use them: 13215b97f5cSMasahiro Yamada 133*50c59522SSimon Glass FdtRo - read-only access to an existing FDT 134*50c59522SSimon Glass FdtRw - read-write access to an existing FDT (most common case) 135*50c59522SSimon Glass FdtSw - for creating a new FDT, as well as allowing read-only access 13615b97f5cSMasahiro Yamada """ 13715b97f5cSMasahiro Yamada def __init__(self, data): 13815b97f5cSMasahiro Yamada self._fdt = bytearray(data) 13915b97f5cSMasahiro Yamada check_err(fdt_check_header(self._fdt)); 14015b97f5cSMasahiro Yamada 1413def0cf2SSimon Glass def as_bytearray(self): 1423def0cf2SSimon Glass """Get the device tree contents as a bytearray 1433def0cf2SSimon Glass 1443def0cf2SSimon Glass This can be passed directly to libfdt functions that access a 1453def0cf2SSimon Glass const void * for the device tree. 1463def0cf2SSimon Glass 1473def0cf2SSimon Glass Returns: 1483def0cf2SSimon Glass bytearray containing the device tree 1493def0cf2SSimon Glass """ 1503def0cf2SSimon Glass return bytearray(self._fdt) 1513def0cf2SSimon Glass 1523def0cf2SSimon Glass def next_node(self, nodeoffset, depth, quiet=()): 1533def0cf2SSimon Glass """Find the next subnode 1543def0cf2SSimon Glass 1553def0cf2SSimon Glass Args: 1563def0cf2SSimon Glass nodeoffset: Node offset of previous node 157*50c59522SSimon Glass depth: The depth of the node at nodeoffset. This is used to 158*50c59522SSimon Glass calculate the depth of the returned node 1593def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1603def0cf2SSimon Glass 1613def0cf2SSimon Glass Returns: 162*50c59522SSimon Glass Typle: 163*50c59522SSimon Glass Offset of the next node, if any, else a -ve error 164*50c59522SSimon Glass Depth of the returned node, if any, else undefined 1653def0cf2SSimon Glass 1663def0cf2SSimon Glass Raises: 1673def0cf2SSimon Glass FdtException if no more nodes found or other error occurs 1683def0cf2SSimon Glass """ 1693def0cf2SSimon Glass return check_err(fdt_next_node(self._fdt, nodeoffset, depth), quiet) 1703def0cf2SSimon Glass 1713def0cf2SSimon Glass def first_subnode(self, nodeoffset, quiet=()): 1723def0cf2SSimon Glass """Find the first subnode of a parent node 1733def0cf2SSimon Glass 1743def0cf2SSimon Glass Args: 1753def0cf2SSimon Glass nodeoffset: Node offset of parent node 1763def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1773def0cf2SSimon Glass 1783def0cf2SSimon Glass Returns: 1793def0cf2SSimon Glass The offset of the first subnode, if any 1803def0cf2SSimon Glass 1813def0cf2SSimon Glass Raises: 1823def0cf2SSimon Glass FdtException if no subnodes found or other error occurs 1833def0cf2SSimon Glass """ 1843def0cf2SSimon Glass return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet) 1853def0cf2SSimon Glass 1863def0cf2SSimon Glass def next_subnode(self, nodeoffset, quiet=()): 1873def0cf2SSimon Glass """Find the next subnode 1883def0cf2SSimon Glass 1893def0cf2SSimon Glass Args: 1903def0cf2SSimon Glass nodeoffset: Node offset of previous subnode 1913def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 1923def0cf2SSimon Glass 1933def0cf2SSimon Glass Returns: 1943def0cf2SSimon Glass The offset of the next subnode, if any 1953def0cf2SSimon Glass 1963def0cf2SSimon Glass Raises: 1973def0cf2SSimon Glass FdtException if no more subnodes found or other error occurs 1983def0cf2SSimon Glass """ 1993def0cf2SSimon Glass return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet) 2003def0cf2SSimon Glass 2013def0cf2SSimon Glass def magic(self): 2023def0cf2SSimon Glass """Return the magic word from the header 2033def0cf2SSimon Glass 2043def0cf2SSimon Glass Returns: 2053def0cf2SSimon Glass Magic word 2063def0cf2SSimon Glass """ 207*50c59522SSimon Glass return fdt_magic(self._fdt) 2083def0cf2SSimon Glass 2093def0cf2SSimon Glass def totalsize(self): 2103def0cf2SSimon Glass """Return the total size of the device tree 2113def0cf2SSimon Glass 2123def0cf2SSimon Glass Returns: 2133def0cf2SSimon Glass Total tree size in bytes 2143def0cf2SSimon Glass """ 215*50c59522SSimon Glass return fdt_totalsize(self._fdt) 2163def0cf2SSimon Glass 2173def0cf2SSimon Glass def off_dt_struct(self): 2183def0cf2SSimon Glass """Return the start of the device-tree struct area 2193def0cf2SSimon Glass 2203def0cf2SSimon Glass Returns: 2213def0cf2SSimon Glass Start offset of struct area 2223def0cf2SSimon Glass """ 223*50c59522SSimon Glass return fdt_off_dt_struct(self._fdt) 2243def0cf2SSimon Glass 2253def0cf2SSimon Glass def off_dt_strings(self): 2263def0cf2SSimon Glass """Return the start of the device-tree string area 2273def0cf2SSimon Glass 2283def0cf2SSimon Glass Returns: 2293def0cf2SSimon Glass Start offset of string area 2303def0cf2SSimon Glass """ 231*50c59522SSimon Glass return fdt_off_dt_strings(self._fdt) 2323def0cf2SSimon Glass 2333def0cf2SSimon Glass def off_mem_rsvmap(self): 2343def0cf2SSimon Glass """Return the start of the memory reserve map 2353def0cf2SSimon Glass 2363def0cf2SSimon Glass Returns: 2373def0cf2SSimon Glass Start offset of memory reserve map 2383def0cf2SSimon Glass """ 239*50c59522SSimon Glass return fdt_off_mem_rsvmap(self._fdt) 2403def0cf2SSimon Glass 2413def0cf2SSimon Glass def version(self): 2423def0cf2SSimon Glass """Return the version of the device tree 2433def0cf2SSimon Glass 2443def0cf2SSimon Glass Returns: 2453def0cf2SSimon Glass Version number of the device tree 2463def0cf2SSimon Glass """ 247*50c59522SSimon Glass return fdt_version(self._fdt) 2483def0cf2SSimon Glass 2493def0cf2SSimon Glass def last_comp_version(self): 2503def0cf2SSimon Glass """Return the last compatible version of the device tree 2513def0cf2SSimon Glass 2523def0cf2SSimon Glass Returns: 2533def0cf2SSimon Glass Last compatible version number of the device tree 2543def0cf2SSimon Glass """ 255*50c59522SSimon Glass return fdt_last_comp_version(self._fdt) 2563def0cf2SSimon Glass 2573def0cf2SSimon Glass def boot_cpuid_phys(self): 2583def0cf2SSimon Glass """Return the physical boot CPU ID 2593def0cf2SSimon Glass 2603def0cf2SSimon Glass Returns: 2613def0cf2SSimon Glass Physical boot CPU ID 2623def0cf2SSimon Glass """ 263*50c59522SSimon Glass return fdt_boot_cpuid_phys(self._fdt) 2643def0cf2SSimon Glass 2653def0cf2SSimon Glass def size_dt_strings(self): 2663def0cf2SSimon Glass """Return the start of the device-tree string area 2673def0cf2SSimon Glass 2683def0cf2SSimon Glass Returns: 2693def0cf2SSimon Glass Start offset of string area 2703def0cf2SSimon Glass """ 271*50c59522SSimon Glass return fdt_size_dt_strings(self._fdt) 2723def0cf2SSimon Glass 2733def0cf2SSimon Glass def size_dt_struct(self): 2743def0cf2SSimon Glass """Return the start of the device-tree struct area 2753def0cf2SSimon Glass 2763def0cf2SSimon Glass Returns: 2773def0cf2SSimon Glass Start offset of struct area 2783def0cf2SSimon Glass """ 279*50c59522SSimon Glass return fdt_size_dt_struct(self._fdt) 2803def0cf2SSimon Glass 2813def0cf2SSimon Glass def num_mem_rsv(self, quiet=()): 2823def0cf2SSimon Glass """Return the number of memory reserve-map records 2833def0cf2SSimon Glass 2843def0cf2SSimon Glass Returns: 2853def0cf2SSimon Glass Number of memory reserve-map records 2863def0cf2SSimon Glass """ 2873def0cf2SSimon Glass return check_err(fdt_num_mem_rsv(self._fdt), quiet) 2883def0cf2SSimon Glass 2893def0cf2SSimon Glass def get_mem_rsv(self, index, quiet=()): 2903def0cf2SSimon Glass """Return the indexed memory reserve-map record 2913def0cf2SSimon Glass 2923def0cf2SSimon Glass Args: 2933def0cf2SSimon Glass index: Record to return (0=first) 2943def0cf2SSimon Glass 2953def0cf2SSimon Glass Returns: 2963def0cf2SSimon Glass Number of memory reserve-map records 2973def0cf2SSimon Glass """ 2983def0cf2SSimon Glass return check_err(fdt_get_mem_rsv(self._fdt, index), quiet) 2993def0cf2SSimon Glass 30015b97f5cSMasahiro Yamada def subnode_offset(self, parentoffset, name, quiet=()): 30115b97f5cSMasahiro Yamada """Get the offset of a named subnode 30215b97f5cSMasahiro Yamada 30315b97f5cSMasahiro Yamada Args: 30415b97f5cSMasahiro Yamada parentoffset: Offset of the parent node to check 30515b97f5cSMasahiro Yamada name: Name of the required subnode, e.g. 'subnode@1' 30615b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 30715b97f5cSMasahiro Yamada 30815b97f5cSMasahiro Yamada Returns: 30915b97f5cSMasahiro Yamada The node offset of the found node, if any 31015b97f5cSMasahiro Yamada 31115b97f5cSMasahiro Yamada Raises 31215b97f5cSMasahiro Yamada FdtException if there is no node with that name, or other error 31315b97f5cSMasahiro Yamada """ 31415b97f5cSMasahiro Yamada return check_err(fdt_subnode_offset(self._fdt, parentoffset, name), 31515b97f5cSMasahiro Yamada quiet) 31615b97f5cSMasahiro Yamada 31715b97f5cSMasahiro Yamada def path_offset(self, path, quiet=()): 31815b97f5cSMasahiro Yamada """Get the offset for a given path 31915b97f5cSMasahiro Yamada 32015b97f5cSMasahiro Yamada Args: 32115b97f5cSMasahiro Yamada path: Path to the required node, e.g. '/node@3/subnode@1' 32215b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 32315b97f5cSMasahiro Yamada 32415b97f5cSMasahiro Yamada Returns: 32515b97f5cSMasahiro Yamada Node offset 32615b97f5cSMasahiro Yamada 32715b97f5cSMasahiro Yamada Raises 32815b97f5cSMasahiro Yamada FdtException if the path is not valid or not found 32915b97f5cSMasahiro Yamada """ 33015b97f5cSMasahiro Yamada return check_err(fdt_path_offset(self._fdt, path), quiet) 33115b97f5cSMasahiro Yamada 3323def0cf2SSimon Glass def get_name(self, nodeoffset): 3333def0cf2SSimon Glass """Get the name of a node 3343def0cf2SSimon Glass 3353def0cf2SSimon Glass Args: 3363def0cf2SSimon Glass nodeoffset: Offset of node to check 3373def0cf2SSimon Glass 3383def0cf2SSimon Glass Returns: 3393def0cf2SSimon Glass Node name 3403def0cf2SSimon Glass 3413def0cf2SSimon Glass Raises: 3423def0cf2SSimon Glass FdtException on error (e.g. nodeoffset is invalid) 3433def0cf2SSimon Glass """ 3443def0cf2SSimon Glass return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0] 3453def0cf2SSimon Glass 34615b97f5cSMasahiro Yamada def first_property_offset(self, nodeoffset, quiet=()): 34715b97f5cSMasahiro Yamada """Get the offset of the first property in a node offset 34815b97f5cSMasahiro Yamada 34915b97f5cSMasahiro Yamada Args: 35015b97f5cSMasahiro Yamada nodeoffset: Offset to the node to check 35115b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 35215b97f5cSMasahiro Yamada 35315b97f5cSMasahiro Yamada Returns: 35415b97f5cSMasahiro Yamada Offset of the first property 35515b97f5cSMasahiro Yamada 35615b97f5cSMasahiro Yamada Raises 35715b97f5cSMasahiro Yamada FdtException if the associated node has no properties, or some 35815b97f5cSMasahiro Yamada other error occurred 35915b97f5cSMasahiro Yamada """ 36015b97f5cSMasahiro Yamada return check_err(fdt_first_property_offset(self._fdt, nodeoffset), 36115b97f5cSMasahiro Yamada quiet) 36215b97f5cSMasahiro Yamada 36315b97f5cSMasahiro Yamada def next_property_offset(self, prop_offset, quiet=()): 36415b97f5cSMasahiro Yamada """Get the next property in a node 36515b97f5cSMasahiro Yamada 36615b97f5cSMasahiro Yamada Args: 36715b97f5cSMasahiro Yamada prop_offset: Offset of the previous property 36815b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 36915b97f5cSMasahiro Yamada 37015b97f5cSMasahiro Yamada Returns: 37115b97f5cSMasahiro Yamada Offset of the next property 37215b97f5cSMasahiro Yamada 37315b97f5cSMasahiro Yamada Raises: 37415b97f5cSMasahiro Yamada FdtException if the associated node has no more properties, or 37515b97f5cSMasahiro Yamada some other error occurred 37615b97f5cSMasahiro Yamada """ 37715b97f5cSMasahiro Yamada return check_err(fdt_next_property_offset(self._fdt, prop_offset), 37815b97f5cSMasahiro Yamada quiet) 37915b97f5cSMasahiro Yamada 38015b97f5cSMasahiro Yamada def get_property_by_offset(self, prop_offset, quiet=()): 38115b97f5cSMasahiro Yamada """Obtains a property that can be examined 38215b97f5cSMasahiro Yamada 38315b97f5cSMasahiro Yamada Args: 38415b97f5cSMasahiro Yamada prop_offset: Offset of property (e.g. from first_property_offset()) 38515b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 38615b97f5cSMasahiro Yamada 38715b97f5cSMasahiro Yamada Returns: 38815b97f5cSMasahiro Yamada Property object, or None if not found 38915b97f5cSMasahiro Yamada 39015b97f5cSMasahiro Yamada Raises: 39115b97f5cSMasahiro Yamada FdtException on error (e.g. invalid prop_offset or device 39215b97f5cSMasahiro Yamada tree format) 39315b97f5cSMasahiro Yamada """ 39415b97f5cSMasahiro Yamada pdata = check_err_null( 39515b97f5cSMasahiro Yamada fdt_get_property_by_offset(self._fdt, prop_offset), quiet) 39615b97f5cSMasahiro Yamada if isinstance(pdata, (int)): 39715b97f5cSMasahiro Yamada return pdata 39815b97f5cSMasahiro Yamada return Property(pdata[0], pdata[1]) 39915b97f5cSMasahiro Yamada 40015b97f5cSMasahiro Yamada def getprop(self, nodeoffset, prop_name, quiet=()): 40115b97f5cSMasahiro Yamada """Get a property from a node 40215b97f5cSMasahiro Yamada 40315b97f5cSMasahiro Yamada Args: 40415b97f5cSMasahiro Yamada nodeoffset: Node offset containing property to get 40515b97f5cSMasahiro Yamada prop_name: Name of property to get 40615b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 40715b97f5cSMasahiro Yamada 40815b97f5cSMasahiro Yamada Returns: 409*50c59522SSimon Glass Value of property as a Property object (which can be used as a 410*50c59522SSimon Glass bytearray/string), or -ve error number. On failure, returns an 411*50c59522SSimon Glass integer error 41215b97f5cSMasahiro Yamada 41315b97f5cSMasahiro Yamada Raises: 41415b97f5cSMasahiro Yamada FdtError if any error occurs (e.g. the property is not found) 41515b97f5cSMasahiro Yamada """ 41615b97f5cSMasahiro Yamada pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name), 41715b97f5cSMasahiro Yamada quiet) 41815b97f5cSMasahiro Yamada if isinstance(pdata, (int)): 41915b97f5cSMasahiro Yamada return pdata 4203def0cf2SSimon Glass return Property(prop_name, bytearray(pdata[0])) 42115b97f5cSMasahiro Yamada 42215b97f5cSMasahiro Yamada def get_phandle(self, nodeoffset): 42315b97f5cSMasahiro Yamada """Get the phandle of a node 42415b97f5cSMasahiro Yamada 42515b97f5cSMasahiro Yamada Args: 42615b97f5cSMasahiro Yamada nodeoffset: Node offset to check 42715b97f5cSMasahiro Yamada 42815b97f5cSMasahiro Yamada Returns: 42915b97f5cSMasahiro Yamada phandle of node, or 0 if the node has no phandle or another error 43015b97f5cSMasahiro Yamada occurs 43115b97f5cSMasahiro Yamada """ 43215b97f5cSMasahiro Yamada return fdt_get_phandle(self._fdt, nodeoffset) 43315b97f5cSMasahiro Yamada 43415b97f5cSMasahiro Yamada def parent_offset(self, nodeoffset, quiet=()): 43515b97f5cSMasahiro Yamada """Get the offset of a node's parent 43615b97f5cSMasahiro Yamada 43715b97f5cSMasahiro Yamada Args: 43815b97f5cSMasahiro Yamada nodeoffset: Node offset to check 43915b97f5cSMasahiro Yamada quiet: Errors to ignore (empty to raise on all errors) 44015b97f5cSMasahiro Yamada 44115b97f5cSMasahiro Yamada Returns: 44215b97f5cSMasahiro Yamada The offset of the parent node, if any 44315b97f5cSMasahiro Yamada 44415b97f5cSMasahiro Yamada Raises: 44515b97f5cSMasahiro Yamada FdtException if no parent found or other error occurs 44615b97f5cSMasahiro Yamada """ 44715b97f5cSMasahiro Yamada return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet) 44815b97f5cSMasahiro Yamada 449*50c59522SSimon Glass def node_offset_by_phandle(self, phandle, quiet=()): 450*50c59522SSimon Glass """Get the offset of a node with the given phandle 451*50c59522SSimon Glass 452*50c59522SSimon Glass Args: 453*50c59522SSimon Glass phandle: Phandle to search for 454*50c59522SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 455*50c59522SSimon Glass 456*50c59522SSimon Glass Returns: 457*50c59522SSimon Glass The offset of node with that phandle, if any 458*50c59522SSimon Glass 459*50c59522SSimon Glass Raises: 460*50c59522SSimon Glass FdtException if no node found or other error occurs 461*50c59522SSimon Glass """ 462*50c59522SSimon Glass return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet) 463*50c59522SSimon Glass 464*50c59522SSimon Glass 465*50c59522SSimon Glassclass Fdt(FdtRo): 466*50c59522SSimon Glass """Device tree class, supporting all operations 467*50c59522SSimon Glass 468*50c59522SSimon Glass The Fdt object is created is created from a device tree binary file, 469*50c59522SSimon Glass e.g. with something like: 470*50c59522SSimon Glass 471*50c59522SSimon Glass fdt = Fdt(open("filename.dtb").read()) 472*50c59522SSimon Glass 473*50c59522SSimon Glass Operations can then be performed using the methods in this class. Each 474*50c59522SSimon Glass method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...). 475*50c59522SSimon Glass 476*50c59522SSimon Glass All methods raise an FdtException if an error occurs. To avoid this 477*50c59522SSimon Glass behaviour a 'quiet' parameter is provided for some functions. This 478*50c59522SSimon Glass defaults to empty, but you can pass a list of errors that you expect. 479*50c59522SSimon Glass If one of these errors occurs, the function will return an error number 480*50c59522SSimon Glass (e.g. -NOTFOUND). 481*50c59522SSimon Glass """ 482*50c59522SSimon Glass def __init__(self, data): 483*50c59522SSimon Glass FdtRo.__init__(self, data) 484*50c59522SSimon Glass 485*50c59522SSimon Glass @staticmethod 486*50c59522SSimon Glass def create_empty_tree(size, quiet=()): 487*50c59522SSimon Glass """Create an empty device tree ready for use 488*50c59522SSimon Glass 489*50c59522SSimon Glass Args: 490*50c59522SSimon Glass size: Size of device tree in bytes 491*50c59522SSimon Glass 492*50c59522SSimon Glass Returns: 493*50c59522SSimon Glass Fdt object containing the device tree 494*50c59522SSimon Glass """ 495*50c59522SSimon Glass data = bytearray(size) 496*50c59522SSimon Glass err = check_err(fdt_create_empty_tree(data, size), quiet) 497*50c59522SSimon Glass if err: 498*50c59522SSimon Glass return err 499*50c59522SSimon Glass return Fdt(data) 500*50c59522SSimon Glass 501*50c59522SSimon Glass def resize(self, size, quiet=()): 502*50c59522SSimon Glass """Move the device tree into a larger or smaller space 503*50c59522SSimon Glass 504*50c59522SSimon Glass This creates a new device tree of size @size and moves the existing 505*50c59522SSimon Glass device tree contents over to that. It can be used to create more space 506*50c59522SSimon Glass in a device tree. Note that the Fdt object remains the same, but it 507*50c59522SSimon Glass now has a new bytearray holding the contents. 508*50c59522SSimon Glass 509*50c59522SSimon Glass Args: 510*50c59522SSimon Glass size: Required new size of device tree in bytes 511*50c59522SSimon Glass """ 512*50c59522SSimon Glass fdt = bytearray(size) 513*50c59522SSimon Glass err = check_err(fdt_open_into(self._fdt, fdt, size), quiet) 514*50c59522SSimon Glass if err: 515*50c59522SSimon Glass return err 516*50c59522SSimon Glass self._fdt = fdt 517*50c59522SSimon Glass 518*50c59522SSimon Glass def pack(self, quiet=()): 519*50c59522SSimon Glass """Pack the device tree to remove unused space 520*50c59522SSimon Glass 521*50c59522SSimon Glass This adjusts the tree in place. 522*50c59522SSimon Glass 523*50c59522SSimon Glass Args: 524*50c59522SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 525*50c59522SSimon Glass 526*50c59522SSimon Glass Returns: 527*50c59522SSimon Glass Error code, or 0 if OK 528*50c59522SSimon Glass 529*50c59522SSimon Glass Raises: 530*50c59522SSimon Glass FdtException if any error occurs 531*50c59522SSimon Glass """ 532*50c59522SSimon Glass err = check_err(fdt_pack(self._fdt), quiet) 533*50c59522SSimon Glass if err: 534*50c59522SSimon Glass return err 535*50c59522SSimon Glass del self._fdt[self.totalsize():] 536*50c59522SSimon Glass return err 537*50c59522SSimon Glass 5383def0cf2SSimon Glass def set_name(self, nodeoffset, name, quiet=()): 5393def0cf2SSimon Glass """Set the name of a node 5403def0cf2SSimon Glass 5413def0cf2SSimon Glass Args: 5423def0cf2SSimon Glass nodeoffset: Node offset of node to update 543*50c59522SSimon Glass name: New node name (string without \0) 5443def0cf2SSimon Glass 5453def0cf2SSimon Glass Returns: 5463def0cf2SSimon Glass Error code, or 0 if OK 5473def0cf2SSimon Glass 5483def0cf2SSimon Glass Raises: 5493def0cf2SSimon Glass FdtException if no parent found or other error occurs 5503def0cf2SSimon Glass """ 551*50c59522SSimon Glass if chr(0) in name: 552*50c59522SSimon Glass raise ValueError('Property contains embedded nul characters') 5533def0cf2SSimon Glass return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet) 5543def0cf2SSimon Glass 5553def0cf2SSimon Glass def setprop(self, nodeoffset, prop_name, val, quiet=()): 5563def0cf2SSimon Glass """Set the value of a property 5573def0cf2SSimon Glass 5583def0cf2SSimon Glass Args: 5593def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5603def0cf2SSimon Glass prop_name: Name of property 5613def0cf2SSimon Glass val: Value to write (string or bytearray) 5623def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5633def0cf2SSimon Glass 5643def0cf2SSimon Glass Returns: 5653def0cf2SSimon Glass Error code, or 0 if OK 5663def0cf2SSimon Glass 5673def0cf2SSimon Glass Raises: 5683def0cf2SSimon Glass FdtException if no parent found or other error occurs 5693def0cf2SSimon Glass """ 5703def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, 5713def0cf2SSimon Glass len(val)), quiet) 5723def0cf2SSimon Glass 5733def0cf2SSimon Glass def setprop_u32(self, nodeoffset, prop_name, val, quiet=()): 5743def0cf2SSimon Glass """Set the value of a property 5753def0cf2SSimon Glass 5763def0cf2SSimon Glass Args: 5773def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5783def0cf2SSimon Glass prop_name: Name of property 5793def0cf2SSimon Glass val: Value to write (integer) 5803def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5813def0cf2SSimon Glass 5823def0cf2SSimon Glass Returns: 5833def0cf2SSimon Glass Error code, or 0 if OK 5843def0cf2SSimon Glass 5853def0cf2SSimon Glass Raises: 5863def0cf2SSimon Glass FdtException if no parent found or other error occurs 5873def0cf2SSimon Glass """ 5883def0cf2SSimon Glass return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val), 5893def0cf2SSimon Glass quiet) 5903def0cf2SSimon Glass 5913def0cf2SSimon Glass def setprop_u64(self, nodeoffset, prop_name, val, quiet=()): 5923def0cf2SSimon Glass """Set the value of a property 5933def0cf2SSimon Glass 5943def0cf2SSimon Glass Args: 5953def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 5963def0cf2SSimon Glass prop_name: Name of property 5973def0cf2SSimon Glass val: Value to write (integer) 5983def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 5993def0cf2SSimon Glass 6003def0cf2SSimon Glass Returns: 6013def0cf2SSimon Glass Error code, or 0 if OK 6023def0cf2SSimon Glass 6033def0cf2SSimon Glass Raises: 6043def0cf2SSimon Glass FdtException if no parent found or other error occurs 6053def0cf2SSimon Glass """ 6063def0cf2SSimon Glass return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), 6073def0cf2SSimon Glass quiet) 6083def0cf2SSimon Glass 6093def0cf2SSimon Glass def setprop_str(self, nodeoffset, prop_name, val, quiet=()): 6103def0cf2SSimon Glass """Set the string value of a property 6113def0cf2SSimon Glass 6123def0cf2SSimon Glass The property is set to the string, with a nul terminator added 6133def0cf2SSimon Glass 6143def0cf2SSimon Glass Args: 6153def0cf2SSimon Glass nodeoffset: Node offset containing the property to create/update 6163def0cf2SSimon Glass prop_name: Name of property 617*50c59522SSimon Glass val: Value to write (string without nul terminator). Unicode is 618*50c59522SSimon Glass supposed by encoding to UTF-8 6193def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 6203def0cf2SSimon Glass 6213def0cf2SSimon Glass Returns: 6223def0cf2SSimon Glass Error code, or 0 if OK 6233def0cf2SSimon Glass 6243def0cf2SSimon Glass Raises: 6253def0cf2SSimon Glass FdtException if no parent found or other error occurs 6263def0cf2SSimon Glass """ 627*50c59522SSimon Glass val = val.encode('utf-8') + '\0' 6283def0cf2SSimon Glass return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, 6293def0cf2SSimon Glass val, len(val)), quiet) 6303def0cf2SSimon Glass 6313def0cf2SSimon Glass def delprop(self, nodeoffset, prop_name): 6323def0cf2SSimon Glass """Delete a property from a node 6333def0cf2SSimon Glass 6343def0cf2SSimon Glass Args: 6353def0cf2SSimon Glass nodeoffset: Node offset containing property to delete 6363def0cf2SSimon Glass prop_name: Name of property to delete 6373def0cf2SSimon Glass 6383def0cf2SSimon Glass Raises: 6393def0cf2SSimon Glass FdtError if the property does not exist, or another error occurs 6403def0cf2SSimon Glass """ 6413def0cf2SSimon Glass return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name)) 6423def0cf2SSimon Glass 643c640ed0cSSimon Glass def del_node(self, nodeoffset): 644c640ed0cSSimon Glass """Delete a node 645c640ed0cSSimon Glass 646c640ed0cSSimon Glass Args: 647c640ed0cSSimon Glass nodeoffset: Node offset containing property to delete 648c640ed0cSSimon Glass 649c640ed0cSSimon Glass Raises: 650c640ed0cSSimon Glass FdtError if the node does not exist, or another error occurs 651c640ed0cSSimon Glass """ 652c640ed0cSSimon Glass return check_err(fdt_del_node(self._fdt, nodeoffset)) 653c640ed0cSSimon Glass 6543def0cf2SSimon Glass 6553def0cf2SSimon Glassclass Property(bytearray): 65615b97f5cSMasahiro Yamada """Holds a device tree property name and value. 65715b97f5cSMasahiro Yamada 65815b97f5cSMasahiro Yamada This holds a copy of a property taken from the device tree. It does not 65915b97f5cSMasahiro Yamada reference the device tree, so if anything changes in the device tree, 66015b97f5cSMasahiro Yamada a Property object will remain valid. 66115b97f5cSMasahiro Yamada 66215b97f5cSMasahiro Yamada Properties: 66315b97f5cSMasahiro Yamada name: Property name 6643def0cf2SSimon Glass value: Property value as a bytearray 66515b97f5cSMasahiro Yamada """ 66615b97f5cSMasahiro Yamada def __init__(self, name, value): 6673def0cf2SSimon Glass bytearray.__init__(self, value) 66815b97f5cSMasahiro Yamada self.name = name 6693def0cf2SSimon Glass 6703def0cf2SSimon Glass def as_cell(self, fmt): 6713def0cf2SSimon Glass return struct.unpack('>' + fmt, self)[0] 6723def0cf2SSimon Glass 6733def0cf2SSimon Glass def as_uint32(self): 6743def0cf2SSimon Glass return self.as_cell('L') 6753def0cf2SSimon Glass 6763def0cf2SSimon Glass def as_int32(self): 6773def0cf2SSimon Glass return self.as_cell('l') 6783def0cf2SSimon Glass 6793def0cf2SSimon Glass def as_uint64(self): 6803def0cf2SSimon Glass return self.as_cell('Q') 6813def0cf2SSimon Glass 6823def0cf2SSimon Glass def as_int64(self): 6833def0cf2SSimon Glass return self.as_cell('q') 6843def0cf2SSimon Glass 6853def0cf2SSimon Glass def as_str(self): 686*50c59522SSimon Glass """Unicode is supported by decoding from UTF-8""" 687*50c59522SSimon Glass if self[-1] != 0: 688*50c59522SSimon Glass raise ValueError('Property lacks nul termination') 689*50c59522SSimon Glass if 0 in self[:-1]: 690*50c59522SSimon Glass raise ValueError('Property contains embedded nul characters') 691*50c59522SSimon Glass return self[:-1].decode('utf-8') 6923def0cf2SSimon Glass 6933def0cf2SSimon Glass 694*50c59522SSimon Glassclass FdtSw(FdtRo): 6953def0cf2SSimon Glass """Software interface to create a device tree from scratch 6963def0cf2SSimon Glass 6973def0cf2SSimon Glass The methods in this class work by adding to an existing 'partial' device 6983def0cf2SSimon Glass tree buffer of a fixed size created by instantiating this class. When the 699*50c59522SSimon Glass tree is complete, call as_fdt() to obtain a device tree ready to be used. 7003def0cf2SSimon Glass 7013def0cf2SSimon Glass Similarly with nodes, a new node is started with begin_node() and finished 7023def0cf2SSimon Glass with end_node(). 7033def0cf2SSimon Glass 7043def0cf2SSimon Glass The context manager functions can be used to make this a bit easier: 7053def0cf2SSimon Glass 7063def0cf2SSimon Glass # First create the device tree with a node and property: 707*50c59522SSimon Glass sw = FdtSw() 708*50c59522SSimon Glass with sw.add_node('node'): 7093def0cf2SSimon Glass sw.property_u32('reg', 2) 710*50c59522SSimon Glass fdt = sw.as_fdt() 7113def0cf2SSimon Glass 7123def0cf2SSimon Glass # Now we can use it as a real device tree 7133def0cf2SSimon Glass fdt.setprop_u32(0, 'reg', 3) 714*50c59522SSimon Glass 715*50c59522SSimon Glass The size hint provides a starting size for the space to be used by the 716*50c59522SSimon Glass device tree. This will be increased automatically as needed as new items 717*50c59522SSimon Glass are added to the tree. 7183def0cf2SSimon Glass """ 719*50c59522SSimon Glass INC_SIZE = 1024 # Expand size by this much when out of space 720*50c59522SSimon Glass 721*50c59522SSimon Glass def __init__(self, size_hint=None): 722*50c59522SSimon Glass """Create a new FdtSw object 723*50c59522SSimon Glass 724*50c59522SSimon Glass Args: 725*50c59522SSimon Glass size_hint: A hint as to the initial size to use 726*50c59522SSimon Glass 727*50c59522SSimon Glass Raises: 728*50c59522SSimon Glass ValueError if size_hint is negative 729*50c59522SSimon Glass 730*50c59522SSimon Glass Returns: 731*50c59522SSimon Glass FdtSw object on success, else integer error code (if not raising) 732*50c59522SSimon Glass """ 733*50c59522SSimon Glass if not size_hint: 734*50c59522SSimon Glass size_hint = self.INC_SIZE 735*50c59522SSimon Glass fdtsw = bytearray(size_hint) 736*50c59522SSimon Glass err = check_err(fdt_create(fdtsw, size_hint)) 7373def0cf2SSimon Glass if err: 7383def0cf2SSimon Glass return err 739*50c59522SSimon Glass self._fdt = fdtsw 7403def0cf2SSimon Glass 741*50c59522SSimon Glass def as_fdt(self): 7423def0cf2SSimon Glass """Convert a FdtSw into an Fdt so it can be accessed as normal 7433def0cf2SSimon Glass 744*50c59522SSimon Glass Creates a new Fdt object from the work-in-progress device tree. This 745*50c59522SSimon Glass does not call fdt_finish() on the current object, so it is possible to 746*50c59522SSimon Glass add more nodes/properties and call as_fdt() again to get an updated 747*50c59522SSimon Glass tree. 7483def0cf2SSimon Glass 7493def0cf2SSimon Glass Returns: 7503def0cf2SSimon Glass Fdt object allowing access to the newly created device tree 7513def0cf2SSimon Glass """ 752*50c59522SSimon Glass fdtsw = bytearray(self._fdt) 753*50c59522SSimon Glass check_err(fdt_finish(fdtsw)) 754*50c59522SSimon Glass return Fdt(fdtsw) 7553def0cf2SSimon Glass 756*50c59522SSimon Glass def check_space(self, val): 757*50c59522SSimon Glass """Check if we need to add more space to the FDT 758*50c59522SSimon Glass 759*50c59522SSimon Glass This should be called with the error code from an operation. If this is 760*50c59522SSimon Glass -NOSPACE then the FDT will be expanded to have more space, and True will 761*50c59522SSimon Glass be returned, indicating that the operation needs to be tried again. 762*50c59522SSimon Glass 763*50c59522SSimon Glass Args: 764*50c59522SSimon Glass val: Return value from the operation that was attempted 765*50c59522SSimon Glass 766*50c59522SSimon Glass Returns: 767*50c59522SSimon Glass True if the operation must be retried, else False 768*50c59522SSimon Glass """ 769*50c59522SSimon Glass if check_err(val, QUIET_NOSPACE) < 0: 770*50c59522SSimon Glass self.resize(len(self._fdt) + self.INC_SIZE) 771*50c59522SSimon Glass return True 772*50c59522SSimon Glass return False 773*50c59522SSimon Glass 774*50c59522SSimon Glass def resize(self, size): 7753def0cf2SSimon Glass """Resize the buffer to accommodate a larger tree 7763def0cf2SSimon Glass 7773def0cf2SSimon Glass Args: 7783def0cf2SSimon Glass size: New size of tree 7793def0cf2SSimon Glass 7803def0cf2SSimon Glass Raises: 781*50c59522SSimon Glass FdtException on any error 7823def0cf2SSimon Glass """ 7833def0cf2SSimon Glass fdt = bytearray(size) 784*50c59522SSimon Glass err = check_err(fdt_resize(self._fdt, fdt, size)) 785*50c59522SSimon Glass self._fdt = fdt 7863def0cf2SSimon Glass 787*50c59522SSimon Glass def add_reservemap_entry(self, addr, size): 7883def0cf2SSimon Glass """Add a new memory reserve map entry 7893def0cf2SSimon Glass 7903def0cf2SSimon Glass Once finished adding, you must call finish_reservemap(). 7913def0cf2SSimon Glass 7923def0cf2SSimon Glass Args: 7933def0cf2SSimon Glass addr: 64-bit start address 7943def0cf2SSimon Glass size: 64-bit size 7953def0cf2SSimon Glass 7963def0cf2SSimon Glass Raises: 797*50c59522SSimon Glass FdtException on any error 7983def0cf2SSimon Glass """ 799*50c59522SSimon Glass while self.check_space(fdt_add_reservemap_entry(self._fdt, addr, 800*50c59522SSimon Glass size)): 801*50c59522SSimon Glass pass 8023def0cf2SSimon Glass 803*50c59522SSimon Glass def finish_reservemap(self): 8043def0cf2SSimon Glass """Indicate that there are no more reserve map entries to add 8053def0cf2SSimon Glass 8063def0cf2SSimon Glass Raises: 807*50c59522SSimon Glass FdtException on any error 8083def0cf2SSimon Glass """ 809*50c59522SSimon Glass while self.check_space(fdt_finish_reservemap(self._fdt)): 810*50c59522SSimon Glass pass 8113def0cf2SSimon Glass 812*50c59522SSimon Glass def begin_node(self, name): 8133def0cf2SSimon Glass """Begin a new node 8143def0cf2SSimon Glass 8153def0cf2SSimon Glass Use this before adding properties to the node. Then call end_node() to 8163def0cf2SSimon Glass finish it. You can also use the context manager as shown in the FdtSw 8173def0cf2SSimon Glass class comment. 8183def0cf2SSimon Glass 8193def0cf2SSimon Glass Args: 8203def0cf2SSimon Glass name: Name of node to begin 8213def0cf2SSimon Glass 8223def0cf2SSimon Glass Raises: 823*50c59522SSimon Glass FdtException on any error 8243def0cf2SSimon Glass """ 825*50c59522SSimon Glass while self.check_space(fdt_begin_node(self._fdt, name)): 826*50c59522SSimon Glass pass 8273def0cf2SSimon Glass 828*50c59522SSimon Glass def property_string(self, name, string): 8293def0cf2SSimon Glass """Add a property with a string value 8303def0cf2SSimon Glass 8313def0cf2SSimon Glass The string will be nul-terminated when written to the device tree 8323def0cf2SSimon Glass 8333def0cf2SSimon Glass Args: 8343def0cf2SSimon Glass name: Name of property to add 8353def0cf2SSimon Glass string: String value of property 8363def0cf2SSimon Glass 8373def0cf2SSimon Glass Raises: 838*50c59522SSimon Glass FdtException on any error 8393def0cf2SSimon Glass """ 840*50c59522SSimon Glass while self.check_space(fdt_property_string(self._fdt, name, string)): 841*50c59522SSimon Glass pass 8423def0cf2SSimon Glass 843*50c59522SSimon Glass def property_u32(self, name, val): 8443def0cf2SSimon Glass """Add a property with a 32-bit value 8453def0cf2SSimon Glass 8463def0cf2SSimon Glass Write a single-cell value to the device tree 8473def0cf2SSimon Glass 8483def0cf2SSimon Glass Args: 8493def0cf2SSimon Glass name: Name of property to add 8503def0cf2SSimon Glass val: Value of property 8513def0cf2SSimon Glass 8523def0cf2SSimon Glass Raises: 853*50c59522SSimon Glass FdtException on any error 8543def0cf2SSimon Glass """ 855*50c59522SSimon Glass while self.check_space(fdt_property_u32(self._fdt, name, val)): 856*50c59522SSimon Glass pass 8573def0cf2SSimon Glass 858*50c59522SSimon Glass def property_u64(self, name, val): 8593def0cf2SSimon Glass """Add a property with a 64-bit value 8603def0cf2SSimon Glass 8613def0cf2SSimon Glass Write a double-cell value to the device tree in big-endian format 8623def0cf2SSimon Glass 8633def0cf2SSimon Glass Args: 8643def0cf2SSimon Glass name: Name of property to add 8653def0cf2SSimon Glass val: Value of property 8663def0cf2SSimon Glass 8673def0cf2SSimon Glass Raises: 868*50c59522SSimon Glass FdtException on any error 8693def0cf2SSimon Glass """ 870*50c59522SSimon Glass while self.check_space(fdt_property_u64(self._fdt, name, val)): 871*50c59522SSimon Glass pass 8723def0cf2SSimon Glass 873*50c59522SSimon Glass def property_cell(self, name, val): 8743def0cf2SSimon Glass """Add a property with a single-cell value 8753def0cf2SSimon Glass 8763def0cf2SSimon Glass Write a single-cell value to the device tree 8773def0cf2SSimon Glass 8783def0cf2SSimon Glass Args: 8793def0cf2SSimon Glass name: Name of property to add 8803def0cf2SSimon Glass val: Value of property 8813def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8823def0cf2SSimon Glass 8833def0cf2SSimon Glass Raises: 884*50c59522SSimon Glass FdtException on any error 8853def0cf2SSimon Glass """ 886*50c59522SSimon Glass while self.check_space(fdt_property_cell(self._fdt, name, val)): 887*50c59522SSimon Glass pass 8883def0cf2SSimon Glass 889*50c59522SSimon Glass def property(self, name, val): 8903def0cf2SSimon Glass """Add a property 8913def0cf2SSimon Glass 8923def0cf2SSimon Glass Write a new property with the given value to the device tree. The value 8933def0cf2SSimon Glass is taken as is and is not nul-terminated 8943def0cf2SSimon Glass 8953def0cf2SSimon Glass Args: 8963def0cf2SSimon Glass name: Name of property to add 8973def0cf2SSimon Glass val: Value of property 8983def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 8993def0cf2SSimon Glass 9003def0cf2SSimon Glass Raises: 901*50c59522SSimon Glass FdtException on any error 9023def0cf2SSimon Glass """ 903*50c59522SSimon Glass while self.check_space(fdt_property_stub(self._fdt, name, val, 904*50c59522SSimon Glass len(val))): 905*50c59522SSimon Glass pass 9063def0cf2SSimon Glass 907*50c59522SSimon Glass def end_node(self): 9083def0cf2SSimon Glass """End a node 9093def0cf2SSimon Glass 9103def0cf2SSimon Glass Use this after adding properties to a node to close it off. You can also 9113def0cf2SSimon Glass use the context manager as shown in the FdtSw class comment. 9123def0cf2SSimon Glass 9133def0cf2SSimon Glass Args: 9143def0cf2SSimon Glass quiet: Errors to ignore (empty to raise on all errors) 9153def0cf2SSimon Glass 9163def0cf2SSimon Glass Raises: 917*50c59522SSimon Glass FdtException on any error 9183def0cf2SSimon Glass """ 919*50c59522SSimon Glass while self.check_space(fdt_end_node(self._fdt)): 920*50c59522SSimon Glass pass 9213def0cf2SSimon Glass 922*50c59522SSimon Glass def add_node(self, name): 9233def0cf2SSimon Glass """Create a new context for adding a node 9243def0cf2SSimon Glass 9253def0cf2SSimon Glass When used in a 'with' clause this starts a new node and finishes it 9263def0cf2SSimon Glass afterward. 9273def0cf2SSimon Glass 9283def0cf2SSimon Glass Args: 9293def0cf2SSimon Glass name: Name of node to add 9303def0cf2SSimon Glass """ 931*50c59522SSimon Glass return NodeAdder(self, name) 9323def0cf2SSimon Glass 9333def0cf2SSimon Glass 9343def0cf2SSimon Glassclass NodeAdder(): 9353def0cf2SSimon Glass """Class to provide a node context 9363def0cf2SSimon Glass 9373def0cf2SSimon Glass This allows you to add nodes in a more natural way: 9383def0cf2SSimon Glass 939*50c59522SSimon Glass with fdtsw.add_node('name'): 9403def0cf2SSimon Glass fdtsw.property_string('test', 'value') 9413def0cf2SSimon Glass 9423def0cf2SSimon Glass The node is automatically completed with a call to end_node() when the 9433def0cf2SSimon Glass context exits. 9443def0cf2SSimon Glass """ 945*50c59522SSimon Glass def __init__(self, fdtsw, name): 946*50c59522SSimon Glass self._fdt = fdtsw 9473def0cf2SSimon Glass self._name = name 9483def0cf2SSimon Glass 9493def0cf2SSimon Glass def __enter__(self): 950*50c59522SSimon Glass self._fdt.begin_node(self._name) 9513def0cf2SSimon Glass 9523def0cf2SSimon Glass def __exit__(self, type, value, traceback): 953*50c59522SSimon Glass self._fdt.end_node() 95415b97f5cSMasahiro Yamada%} 95515b97f5cSMasahiro Yamada 95615b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func; 95715b97f5cSMasahiro Yamada 958*50c59522SSimon Glass/* 959*50c59522SSimon Glass * fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h 960*50c59522SSimon Glass * so use the same type here. 961*50c59522SSimon Glass */ 962*50c59522SSimon Glasstypedef uint32_t fdt32_t; 96315b97f5cSMasahiro Yamada 96415b97f5cSMasahiro Yamada%include "libfdt/fdt.h" 96515b97f5cSMasahiro Yamada 96615b97f5cSMasahiro Yamada%include "typemaps.i" 96715b97f5cSMasahiro Yamada 96815b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */ 96915b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) { 97015b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 97115b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 97215b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 97315b97f5cSMasahiro Yamada } 97415b97f5cSMasahiro Yamada $1 = (void *)PyByteArray_AsString($input); 97515b97f5cSMasahiro Yamada fdt = $1; 97615b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 97715b97f5cSMasahiro Yamada} 97815b97f5cSMasahiro Yamada 97915b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */ 98015b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) { 98115b97f5cSMasahiro Yamada if (!PyByteArray_Check($input)) { 98215b97f5cSMasahiro Yamada SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname" 98315b97f5cSMasahiro Yamada "', argument " "$argnum"" of type '" "$type""'"); 98415b97f5cSMasahiro Yamada } 98515b97f5cSMasahiro Yamada $1 = PyByteArray_AsString($input); 98615b97f5cSMasahiro Yamada fdt = $1; 98715b97f5cSMasahiro Yamada fdt = fdt; /* avoid unused variable warning */ 98815b97f5cSMasahiro Yamada} 98915b97f5cSMasahiro Yamada 9903def0cf2SSimon Glass/* typemap used for fdt_get_property_by_offset() */ 99115b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) { 99215b97f5cSMasahiro Yamada PyObject *buff; 99315b97f5cSMasahiro Yamada 99415b97f5cSMasahiro Yamada if ($1) { 99515b97f5cSMasahiro Yamada resultobj = PyString_FromString( 99615b97f5cSMasahiro Yamada fdt_string(fdt1, fdt32_to_cpu($1->nameoff))); 99715b97f5cSMasahiro Yamada buff = PyByteArray_FromStringAndSize( 99815b97f5cSMasahiro Yamada (const char *)($1 + 1), fdt32_to_cpu($1->len)); 99915b97f5cSMasahiro Yamada resultobj = SWIG_Python_AppendOutput(resultobj, buff); 100015b97f5cSMasahiro Yamada } 100115b97f5cSMasahiro Yamada} 100215b97f5cSMasahiro Yamada 100315b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp }; 100415b97f5cSMasahiro Yamada 100515b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */ 100615b97f5cSMasahiro Yamada%typemap(out) (const void *) { 100715b97f5cSMasahiro Yamada if (!$1) 100815b97f5cSMasahiro Yamada $result = Py_None; 100915b97f5cSMasahiro Yamada else 101015b97f5cSMasahiro Yamada $result = Py_BuildValue("s#", $1, *arg4); 101115b97f5cSMasahiro Yamada} 101215b97f5cSMasahiro Yamada 10133def0cf2SSimon Glass/* typemap used for fdt_setprop() */ 10143def0cf2SSimon Glass%typemap(in) (const void *val) { 10153def0cf2SSimon Glass $1 = PyString_AsString($input); /* char *str */ 10163def0cf2SSimon Glass} 10173def0cf2SSimon Glass 10183def0cf2SSimon Glass/* typemap used for fdt_add_reservemap_entry() */ 10193def0cf2SSimon Glass%typemap(in) uint64_t { 10203def0cf2SSimon Glass $1 = PyLong_AsUnsignedLong($input); 10213def0cf2SSimon Glass} 10223def0cf2SSimon Glass 10233def0cf2SSimon Glass/* typemaps used for fdt_next_node() */ 10243def0cf2SSimon Glass%typemap(in, numinputs=1) int *depth (int depth) { 10253def0cf2SSimon Glass depth = (int) PyInt_AsLong($input); 10263def0cf2SSimon Glass $1 = &depth; 10273def0cf2SSimon Glass} 10283def0cf2SSimon Glass 10293def0cf2SSimon Glass%typemap(argout) int *depth { 10303def0cf2SSimon Glass PyObject *val = Py_BuildValue("i", *arg$argnum); 10313def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 10323def0cf2SSimon Glass} 10333def0cf2SSimon Glass 10343def0cf2SSimon Glass%apply int *depth { int *depth }; 10353def0cf2SSimon Glass 10363def0cf2SSimon Glass/* typemaps for fdt_get_mem_rsv */ 10373def0cf2SSimon Glass%typemap(in, numinputs=0) uint64_t * (uint64_t temp) { 10383def0cf2SSimon Glass $1 = &temp; 10393def0cf2SSimon Glass} 10403def0cf2SSimon Glass 10413def0cf2SSimon Glass%typemap(argout) uint64_t * { 10423def0cf2SSimon Glass PyObject *val = PyLong_FromUnsignedLong(*arg$argnum); 10433def0cf2SSimon Glass if (!result) { 10443def0cf2SSimon Glass if (PyTuple_GET_SIZE(resultobj) == 0) 10453def0cf2SSimon Glass resultobj = val; 10463def0cf2SSimon Glass else 10473def0cf2SSimon Glass resultobj = SWIG_Python_AppendOutput(resultobj, val); 10483def0cf2SSimon Glass } 10493def0cf2SSimon Glass} 10503def0cf2SSimon Glass 105115b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */ 105215b97f5cSMasahiro Yamada%warnfilter(302) fdt_property; 105315b97f5cSMasahiro Yamada 105415b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */ 1055*50c59522SSimon Glassuint32_t fdt_magic(const void *fdt); 1056*50c59522SSimon Glassuint32_t fdt_totalsize(const void *fdt); 1057*50c59522SSimon Glassuint32_t fdt_off_dt_struct(const void *fdt); 1058*50c59522SSimon Glassuint32_t fdt_off_dt_strings(const void *fdt); 1059*50c59522SSimon Glassuint32_t fdt_off_mem_rsvmap(const void *fdt); 1060*50c59522SSimon Glassuint32_t fdt_version(const void *fdt); 1061*50c59522SSimon Glassuint32_t fdt_last_comp_version(const void *fdt); 1062*50c59522SSimon Glassuint32_t fdt_boot_cpuid_phys(const void *fdt); 1063*50c59522SSimon Glassuint32_t fdt_size_dt_strings(const void *fdt); 1064*50c59522SSimon Glassuint32_t fdt_size_dt_struct(const void *fdt); 1065*50c59522SSimon Glass 10663def0cf2SSimon Glassint fdt_property_string(void *fdt, const char *name, const char *val); 10673def0cf2SSimon Glassint fdt_property_cell(void *fdt, const char *name, uint32_t val); 10683def0cf2SSimon Glass 10693def0cf2SSimon Glass/* 10703def0cf2SSimon Glass * This function has a stub since the name fdt_property is used for both a 10713def0cf2SSimon Glass * function and a struct, which confuses SWIG. 10723def0cf2SSimon Glass */ 1073*50c59522SSimon Glassint fdt_property_stub(void *fdt, const char *name, const char *val, int len); 107415b97f5cSMasahiro Yamada 107515b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h> 1076