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
401*c640ed0cSSimon Glass    def get_property(self, nodeoffset, prop_name, quiet=()):
402*c640ed0cSSimon Glass        """Obtains a property by name
403*c640ed0cSSimon Glass
404*c640ed0cSSimon Glass        Args:
405*c640ed0cSSimon Glass            nodeoffset: Offset to the node to check
406*c640ed0cSSimon Glass            prop_name: Name of property to get
407*c640ed0cSSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
408*c640ed0cSSimon Glass
409*c640ed0cSSimon Glass        Returns:
410*c640ed0cSSimon Glass            Property object, or None if not found
411*c640ed0cSSimon Glass
412*c640ed0cSSimon Glass        Raises:
413*c640ed0cSSimon Glass            FdtException on error (e.g. invalid prop_offset or device
414*c640ed0cSSimon Glass            tree format)
415*c640ed0cSSimon Glass        """
416*c640ed0cSSimon Glass        pdata = check_err_null(
417*c640ed0cSSimon Glass                fdt_get_property(self._fdt, nodeoffset, prop_name), quiet)
418*c640ed0cSSimon Glass        if isinstance(pdata, (int)):
419*c640ed0cSSimon Glass            return pdata
420*c640ed0cSSimon Glass        return Property(pdata[0], pdata[1])
421*c640ed0cSSimon Glass
4223def0cf2SSimon Glass    @staticmethod
4233def0cf2SSimon Glass    def create_empty_tree(size, quiet=()):
4243def0cf2SSimon Glass        """Create an empty device tree ready for use
42515b97f5cSMasahiro Yamada
42615b97f5cSMasahiro Yamada        Args:
4273def0cf2SSimon Glass            size: Size of device tree in bytes
42815b97f5cSMasahiro Yamada
42915b97f5cSMasahiro Yamada        Returns:
4303def0cf2SSimon Glass            Fdt object containing the device tree
43115b97f5cSMasahiro Yamada        """
4323def0cf2SSimon Glass        data = bytearray(size)
4333def0cf2SSimon Glass        err = check_err(fdt_create_empty_tree(data, size), quiet)
4343def0cf2SSimon Glass        if err:
4353def0cf2SSimon Glass            return err
4363def0cf2SSimon Glass        return Fdt(data)
43715b97f5cSMasahiro Yamada
4383def0cf2SSimon Glass    def open_into(self, size, quiet=()):
4393def0cf2SSimon Glass        """Move the device tree into a larger or smaller space
4403def0cf2SSimon Glass
4413def0cf2SSimon Glass        This creates a new device tree of size @size and moves the existing
4423def0cf2SSimon Glass        device tree contents over to that. It can be used to create more space
4433def0cf2SSimon Glass        in a device tree.
44415b97f5cSMasahiro Yamada
44515b97f5cSMasahiro Yamada        Args:
4463def0cf2SSimon Glass            size: Required new size of device tree in bytes
44715b97f5cSMasahiro Yamada        """
4483def0cf2SSimon Glass        fdt = bytearray(size)
4493def0cf2SSimon Glass        fdt[:len(self._fdt)] = self._fdt
4503def0cf2SSimon Glass        err = check_err(fdt_open_into(self._fdt, fdt, size), quiet)
4513def0cf2SSimon Glass        if err:
4523def0cf2SSimon Glass            return err
4533def0cf2SSimon Glass        self._fdt = fdt
45415b97f5cSMasahiro Yamada
45515b97f5cSMasahiro Yamada    def pack(self, quiet=()):
45615b97f5cSMasahiro Yamada        """Pack the device tree to remove unused space
45715b97f5cSMasahiro Yamada
45815b97f5cSMasahiro Yamada        This adjusts the tree in place.
45915b97f5cSMasahiro Yamada
46015b97f5cSMasahiro Yamada        Args:
46115b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
46215b97f5cSMasahiro Yamada
46315b97f5cSMasahiro Yamada        Raises:
46415b97f5cSMasahiro Yamada            FdtException if any error occurs
46515b97f5cSMasahiro Yamada        """
466a1e00855SSimon Glass        err = check_err(fdt_pack(self._fdt), quiet)
467a1e00855SSimon Glass        if err:
468a1e00855SSimon Glass            return err
469a1e00855SSimon Glass        del self._fdt[self.totalsize():]
470a1e00855SSimon Glass        return err
47115b97f5cSMasahiro Yamada
47215b97f5cSMasahiro Yamada    def getprop(self, nodeoffset, prop_name, quiet=()):
47315b97f5cSMasahiro Yamada        """Get a property from a node
47415b97f5cSMasahiro Yamada
47515b97f5cSMasahiro Yamada        Args:
47615b97f5cSMasahiro Yamada            nodeoffset: Node offset containing property to get
47715b97f5cSMasahiro Yamada            prop_name: Name of property to get
47815b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
47915b97f5cSMasahiro Yamada
48015b97f5cSMasahiro Yamada        Returns:
4813def0cf2SSimon Glass            Value of property as a string, or -ve error number
48215b97f5cSMasahiro Yamada
48315b97f5cSMasahiro Yamada        Raises:
48415b97f5cSMasahiro Yamada            FdtError if any error occurs (e.g. the property is not found)
48515b97f5cSMasahiro Yamada        """
48615b97f5cSMasahiro Yamada        pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
48715b97f5cSMasahiro Yamada                               quiet)
48815b97f5cSMasahiro Yamada        if isinstance(pdata, (int)):
48915b97f5cSMasahiro Yamada            return pdata
4903def0cf2SSimon Glass        return str(pdata[0])
4913def0cf2SSimon Glass
4923def0cf2SSimon Glass    def getprop_obj(self, nodeoffset, prop_name, quiet=()):
4933def0cf2SSimon Glass        """Get a property from a node as a Property object
4943def0cf2SSimon Glass
4953def0cf2SSimon Glass        Args:
4963def0cf2SSimon Glass            nodeoffset: Node offset containing property to get
4973def0cf2SSimon Glass            prop_name: Name of property to get
4983def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
4993def0cf2SSimon Glass
5003def0cf2SSimon Glass        Returns:
5013def0cf2SSimon Glass            Property object, or None if not found
5023def0cf2SSimon Glass
5033def0cf2SSimon Glass        Raises:
5043def0cf2SSimon Glass            FdtError if any error occurs (e.g. the property is not found)
5053def0cf2SSimon Glass        """
5063def0cf2SSimon Glass        pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
5073def0cf2SSimon Glass                               quiet)
5083def0cf2SSimon Glass        if isinstance(pdata, (int)):
5093def0cf2SSimon Glass            return None
5103def0cf2SSimon Glass        return Property(prop_name, bytearray(pdata[0]))
51115b97f5cSMasahiro Yamada
51215b97f5cSMasahiro Yamada    def get_phandle(self, nodeoffset):
51315b97f5cSMasahiro Yamada        """Get the phandle of a node
51415b97f5cSMasahiro Yamada
51515b97f5cSMasahiro Yamada        Args:
51615b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
51715b97f5cSMasahiro Yamada
51815b97f5cSMasahiro Yamada        Returns:
51915b97f5cSMasahiro Yamada            phandle of node, or 0 if the node has no phandle or another error
52015b97f5cSMasahiro Yamada            occurs
52115b97f5cSMasahiro Yamada        """
52215b97f5cSMasahiro Yamada        return fdt_get_phandle(self._fdt, nodeoffset)
52315b97f5cSMasahiro Yamada
52415b97f5cSMasahiro Yamada    def parent_offset(self, nodeoffset, quiet=()):
52515b97f5cSMasahiro Yamada        """Get the offset of a node's parent
52615b97f5cSMasahiro Yamada
52715b97f5cSMasahiro Yamada        Args:
52815b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
52915b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
53015b97f5cSMasahiro Yamada
53115b97f5cSMasahiro Yamada        Returns:
53215b97f5cSMasahiro Yamada            The offset of the parent node, if any
53315b97f5cSMasahiro Yamada
53415b97f5cSMasahiro Yamada        Raises:
53515b97f5cSMasahiro Yamada            FdtException if no parent found or other error occurs
53615b97f5cSMasahiro Yamada        """
53715b97f5cSMasahiro Yamada        return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
53815b97f5cSMasahiro Yamada
5393def0cf2SSimon Glass    def set_name(self, nodeoffset, name, quiet=()):
5403def0cf2SSimon Glass        """Set the name of a node
5413def0cf2SSimon Glass
5423def0cf2SSimon Glass        Args:
5433def0cf2SSimon Glass            nodeoffset: Node offset of node to update
5443def0cf2SSimon Glass            name: New node name
5453def0cf2SSimon Glass
5463def0cf2SSimon Glass        Returns:
5473def0cf2SSimon Glass            Error code, or 0 if OK
5483def0cf2SSimon Glass
5493def0cf2SSimon Glass        Raises:
5503def0cf2SSimon Glass            FdtException if no parent found or other error occurs
5513def0cf2SSimon Glass        """
5523def0cf2SSimon Glass        return check_err(fdt_set_name(self._fdt, nodeoffset, name), quiet)
5533def0cf2SSimon Glass
5543def0cf2SSimon Glass    def setprop(self, nodeoffset, prop_name, val, quiet=()):
5553def0cf2SSimon Glass        """Set the value of a property
5563def0cf2SSimon Glass
5573def0cf2SSimon Glass        Args:
5583def0cf2SSimon Glass            nodeoffset: Node offset containing the property to create/update
5593def0cf2SSimon Glass            prop_name: Name of property
5603def0cf2SSimon Glass            val: Value to write (string or bytearray)
5613def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
5623def0cf2SSimon Glass
5633def0cf2SSimon Glass        Returns:
5643def0cf2SSimon Glass            Error code, or 0 if OK
5653def0cf2SSimon Glass
5663def0cf2SSimon Glass        Raises:
5673def0cf2SSimon Glass            FdtException if no parent found or other error occurs
5683def0cf2SSimon Glass        """
5693def0cf2SSimon Glass        return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val,
5703def0cf2SSimon Glass                                     len(val)), quiet)
5713def0cf2SSimon Glass
5723def0cf2SSimon Glass    def setprop_u32(self, nodeoffset, prop_name, val, quiet=()):
5733def0cf2SSimon Glass        """Set the value of a property
5743def0cf2SSimon Glass
5753def0cf2SSimon Glass        Args:
5763def0cf2SSimon Glass            nodeoffset: Node offset containing the property to create/update
5773def0cf2SSimon Glass            prop_name: Name of property
5783def0cf2SSimon Glass            val: Value to write (integer)
5793def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
5803def0cf2SSimon Glass
5813def0cf2SSimon Glass        Returns:
5823def0cf2SSimon Glass            Error code, or 0 if OK
5833def0cf2SSimon Glass
5843def0cf2SSimon Glass        Raises:
5853def0cf2SSimon Glass            FdtException if no parent found or other error occurs
5863def0cf2SSimon Glass        """
5873def0cf2SSimon Glass        return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val),
5883def0cf2SSimon Glass                         quiet)
5893def0cf2SSimon Glass
5903def0cf2SSimon Glass    def setprop_u64(self, nodeoffset, prop_name, val, quiet=()):
5913def0cf2SSimon Glass        """Set the value of a property
5923def0cf2SSimon Glass
5933def0cf2SSimon Glass        Args:
5943def0cf2SSimon Glass            nodeoffset: Node offset containing the property to create/update
5953def0cf2SSimon Glass            prop_name: Name of property
5963def0cf2SSimon Glass            val: Value to write (integer)
5973def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
5983def0cf2SSimon Glass
5993def0cf2SSimon Glass        Returns:
6003def0cf2SSimon Glass            Error code, or 0 if OK
6013def0cf2SSimon Glass
6023def0cf2SSimon Glass        Raises:
6033def0cf2SSimon Glass            FdtException if no parent found or other error occurs
6043def0cf2SSimon Glass        """
6053def0cf2SSimon Glass        return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val),
6063def0cf2SSimon Glass                         quiet)
6073def0cf2SSimon Glass
6083def0cf2SSimon Glass    def setprop_str(self, nodeoffset, prop_name, val, quiet=()):
6093def0cf2SSimon Glass        """Set the string value of a property
6103def0cf2SSimon Glass
6113def0cf2SSimon Glass        The property is set to the string, with a nul terminator added
6123def0cf2SSimon Glass
6133def0cf2SSimon Glass        Args:
6143def0cf2SSimon Glass            nodeoffset: Node offset containing the property to create/update
6153def0cf2SSimon Glass            prop_name: Name of property
6163def0cf2SSimon Glass            val: Value to write (string without nul terminator)
6173def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
6183def0cf2SSimon Glass
6193def0cf2SSimon Glass        Returns:
6203def0cf2SSimon Glass            Error code, or 0 if OK
6213def0cf2SSimon Glass
6223def0cf2SSimon Glass        Raises:
6233def0cf2SSimon Glass            FdtException if no parent found or other error occurs
6243def0cf2SSimon Glass        """
6253def0cf2SSimon Glass        val += '\0'
6263def0cf2SSimon Glass        return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name,
6273def0cf2SSimon Glass                                     val, len(val)), quiet)
6283def0cf2SSimon Glass
6293def0cf2SSimon Glass    def delprop(self, nodeoffset, prop_name):
6303def0cf2SSimon Glass        """Delete a property from a node
6313def0cf2SSimon Glass
6323def0cf2SSimon Glass        Args:
6333def0cf2SSimon Glass            nodeoffset: Node offset containing property to delete
6343def0cf2SSimon Glass            prop_name: Name of property to delete
6353def0cf2SSimon Glass
6363def0cf2SSimon Glass        Raises:
6373def0cf2SSimon Glass            FdtError if the property does not exist, or another error occurs
6383def0cf2SSimon Glass        """
6393def0cf2SSimon Glass        return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
6403def0cf2SSimon Glass
64115b97f5cSMasahiro Yamada    def node_offset_by_phandle(self, phandle, quiet=()):
64215b97f5cSMasahiro Yamada        """Get the offset of a node with the given phandle
64315b97f5cSMasahiro Yamada
64415b97f5cSMasahiro Yamada        Args:
64515b97f5cSMasahiro Yamada            phandle: Phandle to search for
64615b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
64715b97f5cSMasahiro Yamada
64815b97f5cSMasahiro Yamada        Returns:
64915b97f5cSMasahiro Yamada            The offset of node with that phandle, if any
65015b97f5cSMasahiro Yamada
65115b97f5cSMasahiro Yamada        Raises:
65215b97f5cSMasahiro Yamada            FdtException if no node found or other error occurs
65315b97f5cSMasahiro Yamada        """
65415b97f5cSMasahiro Yamada        return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
65515b97f5cSMasahiro Yamada
656*c640ed0cSSimon Glass    def del_node(self, nodeoffset):
657*c640ed0cSSimon Glass        """Delete a node
658*c640ed0cSSimon Glass
659*c640ed0cSSimon Glass        Args:
660*c640ed0cSSimon Glass            nodeoffset: Node offset containing property to delete
661*c640ed0cSSimon Glass
662*c640ed0cSSimon Glass        Raises:
663*c640ed0cSSimon Glass            FdtError if the node does not exist, or another error occurs
664*c640ed0cSSimon Glass        """
665*c640ed0cSSimon Glass        return check_err(fdt_del_node(self._fdt, nodeoffset))
666*c640ed0cSSimon Glass
6673def0cf2SSimon Glass
6683def0cf2SSimon Glassclass Property(bytearray):
66915b97f5cSMasahiro Yamada    """Holds a device tree property name and value.
67015b97f5cSMasahiro Yamada
67115b97f5cSMasahiro Yamada    This holds a copy of a property taken from the device tree. It does not
67215b97f5cSMasahiro Yamada    reference the device tree, so if anything changes in the device tree,
67315b97f5cSMasahiro Yamada    a Property object will remain valid.
67415b97f5cSMasahiro Yamada
67515b97f5cSMasahiro Yamada    Properties:
67615b97f5cSMasahiro Yamada        name: Property name
6773def0cf2SSimon Glass        value: Property value as a bytearray
67815b97f5cSMasahiro Yamada    """
67915b97f5cSMasahiro Yamada    def __init__(self, name, value):
6803def0cf2SSimon Glass        bytearray.__init__(self, value)
68115b97f5cSMasahiro Yamada        self.name = name
6823def0cf2SSimon Glass
6833def0cf2SSimon Glass    def as_cell(self, fmt):
6843def0cf2SSimon Glass        return struct.unpack('>' + fmt, self)[0]
6853def0cf2SSimon Glass
6863def0cf2SSimon Glass    def as_uint32(self):
6873def0cf2SSimon Glass        return self.as_cell('L')
6883def0cf2SSimon Glass
6893def0cf2SSimon Glass    def as_int32(self):
6903def0cf2SSimon Glass        return self.as_cell('l')
6913def0cf2SSimon Glass
6923def0cf2SSimon Glass    def as_uint64(self):
6933def0cf2SSimon Glass        return self.as_cell('Q')
6943def0cf2SSimon Glass
6953def0cf2SSimon Glass    def as_int64(self):
6963def0cf2SSimon Glass        return self.as_cell('q')
6973def0cf2SSimon Glass
6983def0cf2SSimon Glass    def as_str(self):
6993def0cf2SSimon Glass        return self[:-1]
7003def0cf2SSimon Glass
7013def0cf2SSimon Glass
7023def0cf2SSimon Glassclass FdtSw(object):
7033def0cf2SSimon Glass    """Software interface to create a device tree from scratch
7043def0cf2SSimon Glass
7053def0cf2SSimon Glass    The methods in this class work by adding to an existing 'partial' device
7063def0cf2SSimon Glass    tree buffer of a fixed size created by instantiating this class. When the
7073def0cf2SSimon Glass    tree is complete, call finish() to complete the device tree so that it can
7083def0cf2SSimon Glass    be used.
7093def0cf2SSimon Glass
7103def0cf2SSimon Glass    Similarly with nodes, a new node is started with begin_node() and finished
7113def0cf2SSimon Glass    with end_node().
7123def0cf2SSimon Glass
7133def0cf2SSimon Glass    The context manager functions can be used to make this a bit easier:
7143def0cf2SSimon Glass
7153def0cf2SSimon Glass    # First create the device tree with a node and property:
7163def0cf2SSimon Glass    with FdtSw(small_size) as sw:
7173def0cf2SSimon Glass        with sw.AddNode('node'):
7183def0cf2SSimon Glass            sw.property_u32('reg', 2)
7193def0cf2SSimon Glass    fdt = sw.AsFdt()
7203def0cf2SSimon Glass
7213def0cf2SSimon Glass    # Now we can use it as a real device tree
7223def0cf2SSimon Glass    fdt.setprop_u32(0, 'reg', 3)
7233def0cf2SSimon Glass    """
7243def0cf2SSimon Glass    def __init__(self, size, quiet=()):
7253def0cf2SSimon Glass        fdtrw = bytearray(size)
7263def0cf2SSimon Glass        err = check_err(fdt_create(fdtrw, size))
7273def0cf2SSimon Glass        if err:
7283def0cf2SSimon Glass            return err
7293def0cf2SSimon Glass        self._fdtrw = fdtrw
7303def0cf2SSimon Glass
7313def0cf2SSimon Glass    def __enter__(self):
7323def0cf2SSimon Glass        """Contact manager to use to create a device tree via software"""
7333def0cf2SSimon Glass        return self
7343def0cf2SSimon Glass
7353def0cf2SSimon Glass    def __exit__(self, type, value, traceback):
7363def0cf2SSimon Glass        check_err(fdt_finish(self._fdtrw))
7373def0cf2SSimon Glass
7383def0cf2SSimon Glass    def AsFdt(self):
7393def0cf2SSimon Glass        """Convert a FdtSw into an Fdt so it can be accessed as normal
7403def0cf2SSimon Glass
7413def0cf2SSimon Glass        Note that finish() must be called before this function will work. If
7423def0cf2SSimon Glass        you are using the context manager (see 'with' code in the FdtSw class
7433def0cf2SSimon Glass        comment) then this will happen automatically.
7443def0cf2SSimon Glass
7453def0cf2SSimon Glass        Returns:
7463def0cf2SSimon Glass            Fdt object allowing access to the newly created device tree
7473def0cf2SSimon Glass        """
7483def0cf2SSimon Glass        return Fdt(self._fdtrw)
7493def0cf2SSimon Glass
7503def0cf2SSimon Glass    def resize(self, size, quiet=()):
7513def0cf2SSimon Glass        """Resize the buffer to accommodate a larger tree
7523def0cf2SSimon Glass
7533def0cf2SSimon Glass        Args:
7543def0cf2SSimon Glass            size: New size of tree
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        fdt = bytearray(size)
7613def0cf2SSimon Glass        fdt[:len(self._fdtrw)] = self._fdtrw
7623def0cf2SSimon Glass        err = check_err(fdt_resize(self._fdtrw, fdt, size), quiet)
7633def0cf2SSimon Glass        if err:
7643def0cf2SSimon Glass            return err
7653def0cf2SSimon Glass        self._fdtrw = fdt
7663def0cf2SSimon Glass
7673def0cf2SSimon Glass    def add_reservemap_entry(self, addr, size, quiet=()):
7683def0cf2SSimon Glass        """Add a new memory reserve map entry
7693def0cf2SSimon Glass
7703def0cf2SSimon Glass        Once finished adding, you must call finish_reservemap().
7713def0cf2SSimon Glass
7723def0cf2SSimon Glass        Args:
7733def0cf2SSimon Glass            addr: 64-bit start address
7743def0cf2SSimon Glass            size: 64-bit size
7753def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
7763def0cf2SSimon Glass
7773def0cf2SSimon Glass        Raises:
7783def0cf2SSimon Glass            FdtException if no node found or other error occurs
7793def0cf2SSimon Glass        """
7803def0cf2SSimon Glass        return check_err(fdt_add_reservemap_entry(self._fdtrw, addr, size),
7813def0cf2SSimon Glass                         quiet)
7823def0cf2SSimon Glass
7833def0cf2SSimon Glass    def finish_reservemap(self, quiet=()):
7843def0cf2SSimon Glass        """Indicate that there are no more reserve map entries to add
7853def0cf2SSimon Glass
7863def0cf2SSimon Glass        Args:
7873def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
7883def0cf2SSimon Glass
7893def0cf2SSimon Glass        Raises:
7903def0cf2SSimon Glass            FdtException if no node found or other error occurs
7913def0cf2SSimon Glass        """
7923def0cf2SSimon Glass        return check_err(fdt_finish_reservemap(self._fdtrw), quiet)
7933def0cf2SSimon Glass
7943def0cf2SSimon Glass    def begin_node(self, name, quiet=()):
7953def0cf2SSimon Glass        """Begin a new node
7963def0cf2SSimon Glass
7973def0cf2SSimon Glass        Use this before adding properties to the node. Then call end_node() to
7983def0cf2SSimon Glass        finish it. You can also use the context manager as shown in the FdtSw
7993def0cf2SSimon Glass        class comment.
8003def0cf2SSimon Glass
8013def0cf2SSimon Glass        Args:
8023def0cf2SSimon Glass            name: Name of node to begin
8033def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8043def0cf2SSimon Glass
8053def0cf2SSimon Glass        Raises:
8063def0cf2SSimon Glass            FdtException if no node found or other error occurs
8073def0cf2SSimon Glass        """
8083def0cf2SSimon Glass        return check_err(fdt_begin_node(self._fdtrw, name), quiet)
8093def0cf2SSimon Glass
8103def0cf2SSimon Glass    def property_string(self, name, string, quiet=()):
8113def0cf2SSimon Glass        """Add a property with a string value
8123def0cf2SSimon Glass
8133def0cf2SSimon Glass        The string will be nul-terminated when written to the device tree
8143def0cf2SSimon Glass
8153def0cf2SSimon Glass        Args:
8163def0cf2SSimon Glass            name: Name of property to add
8173def0cf2SSimon Glass            string: String value of property
8183def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8193def0cf2SSimon Glass
8203def0cf2SSimon Glass        Raises:
8213def0cf2SSimon Glass            FdtException if no node found or other error occurs
8223def0cf2SSimon Glass        """
8233def0cf2SSimon Glass        return check_err(fdt_property_string(self._fdtrw, name, string), quiet)
8243def0cf2SSimon Glass
8253def0cf2SSimon Glass    def property_u32(self, name, val, quiet=()):
8263def0cf2SSimon Glass        """Add a property with a 32-bit value
8273def0cf2SSimon Glass
8283def0cf2SSimon Glass        Write a single-cell value to the device tree
8293def0cf2SSimon Glass
8303def0cf2SSimon Glass        Args:
8313def0cf2SSimon Glass            name: Name of property to add
8323def0cf2SSimon Glass            val: Value of property
8333def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8343def0cf2SSimon Glass
8353def0cf2SSimon Glass        Raises:
8363def0cf2SSimon Glass            FdtException if no node found or other error occurs
8373def0cf2SSimon Glass        """
8383def0cf2SSimon Glass        return check_err(fdt_property_u32(self._fdtrw, name, val), quiet)
8393def0cf2SSimon Glass
8403def0cf2SSimon Glass    def property_u64(self, name, val, quiet=()):
8413def0cf2SSimon Glass        """Add a property with a 64-bit value
8423def0cf2SSimon Glass
8433def0cf2SSimon Glass        Write a double-cell value to the device tree in big-endian format
8443def0cf2SSimon Glass
8453def0cf2SSimon Glass        Args:
8463def0cf2SSimon Glass            name: Name of property to add
8473def0cf2SSimon Glass            val: Value of property
8483def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8493def0cf2SSimon Glass
8503def0cf2SSimon Glass        Raises:
8513def0cf2SSimon Glass            FdtException if no node found or other error occurs
8523def0cf2SSimon Glass        """
8533def0cf2SSimon Glass        return check_err(fdt_property_u64(self._fdtrw, name, val), quiet)
8543def0cf2SSimon Glass
8553def0cf2SSimon Glass    def property_cell(self, name, val, quiet=()):
8563def0cf2SSimon Glass        """Add a property with a single-cell value
8573def0cf2SSimon Glass
8583def0cf2SSimon Glass        Write a single-cell value to the device tree
8593def0cf2SSimon Glass
8603def0cf2SSimon Glass        Args:
8613def0cf2SSimon Glass            name: Name of property to add
8623def0cf2SSimon Glass            val: Value of property
8633def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8643def0cf2SSimon Glass
8653def0cf2SSimon Glass        Raises:
8663def0cf2SSimon Glass            FdtException if no node found or other error occurs
8673def0cf2SSimon Glass        """
8683def0cf2SSimon Glass        return check_err(fdt_property_cell(self._fdtrw, name, val), quiet)
8693def0cf2SSimon Glass
8703def0cf2SSimon Glass    def property(self, name, val, quiet=()):
8713def0cf2SSimon Glass        """Add a property
8723def0cf2SSimon Glass
8733def0cf2SSimon Glass        Write a new property with the given value to the device tree. The value
8743def0cf2SSimon Glass        is taken as is and is not nul-terminated
8753def0cf2SSimon Glass
8763def0cf2SSimon Glass        Args:
8773def0cf2SSimon Glass            name: Name of property to add
8783def0cf2SSimon Glass            val: Value of property
8793def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8803def0cf2SSimon Glass
8813def0cf2SSimon Glass        Raises:
8823def0cf2SSimon Glass            FdtException if no node found or other error occurs
8833def0cf2SSimon Glass        """
8843def0cf2SSimon Glass        return check_err(_fdt_property(self._fdtrw, name, val, len(val)), quiet)
8853def0cf2SSimon Glass
8863def0cf2SSimon Glass    def end_node(self, quiet=()):
8873def0cf2SSimon Glass        """End a node
8883def0cf2SSimon Glass
8893def0cf2SSimon Glass        Use this after adding properties to a node to close it off. You can also
8903def0cf2SSimon Glass        use the context manager as shown in the FdtSw class comment.
8913def0cf2SSimon Glass
8923def0cf2SSimon Glass        Args:
8933def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
8943def0cf2SSimon Glass
8953def0cf2SSimon Glass        Raises:
8963def0cf2SSimon Glass            FdtException if no node found or other error occurs
8973def0cf2SSimon Glass        """
8983def0cf2SSimon Glass        return check_err(fdt_end_node(self._fdtrw), quiet)
8993def0cf2SSimon Glass
9003def0cf2SSimon Glass    def finish(self, quiet=()):
9013def0cf2SSimon Glass        """Finish writing the device tree
9023def0cf2SSimon Glass
9033def0cf2SSimon Glass        This closes off the device tree ready for use
9043def0cf2SSimon Glass
9053def0cf2SSimon Glass        Args:
9063def0cf2SSimon Glass            quiet: Errors to ignore (empty to raise on all errors)
9073def0cf2SSimon Glass
9083def0cf2SSimon Glass        Raises:
9093def0cf2SSimon Glass            FdtException if no node found or other error occurs
9103def0cf2SSimon Glass        """
9113def0cf2SSimon Glass        return check_err(fdt_finish(self._fdtrw), quiet)
9123def0cf2SSimon Glass
9133def0cf2SSimon Glass    def AddNode(self, name):
9143def0cf2SSimon Glass        """Create a new context for adding a node
9153def0cf2SSimon Glass
9163def0cf2SSimon Glass        When used in a 'with' clause this starts a new node and finishes it
9173def0cf2SSimon Glass        afterward.
9183def0cf2SSimon Glass
9193def0cf2SSimon Glass        Args:
9203def0cf2SSimon Glass            name: Name of node to add
9213def0cf2SSimon Glass        """
9223def0cf2SSimon Glass        return NodeAdder(self._fdtrw, name)
9233def0cf2SSimon Glass
9243def0cf2SSimon Glass
9253def0cf2SSimon Glassclass NodeAdder():
9263def0cf2SSimon Glass    """Class to provide a node context
9273def0cf2SSimon Glass
9283def0cf2SSimon Glass    This allows you to add nodes in a more natural way:
9293def0cf2SSimon Glass
9303def0cf2SSimon Glass        with fdtsw.AddNode('name'):
9313def0cf2SSimon Glass            fdtsw.property_string('test', 'value')
9323def0cf2SSimon Glass
9333def0cf2SSimon Glass    The node is automatically completed with a call to end_node() when the
9343def0cf2SSimon Glass    context exits.
9353def0cf2SSimon Glass    """
9363def0cf2SSimon Glass    def __init__(self, fdt, name):
9373def0cf2SSimon Glass        self._fdt = fdt
9383def0cf2SSimon Glass        self._name = name
9393def0cf2SSimon Glass
9403def0cf2SSimon Glass    def __enter__(self):
9413def0cf2SSimon Glass        check_err(fdt_begin_node(self._fdt, self._name))
9423def0cf2SSimon Glass
9433def0cf2SSimon Glass    def __exit__(self, type, value, traceback):
9443def0cf2SSimon Glass        check_err(fdt_end_node(self._fdt))
94515b97f5cSMasahiro Yamada%}
94615b97f5cSMasahiro Yamada
94715b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func;
94815b97f5cSMasahiro Yamada
94915b97f5cSMasahiro Yamadatypedef int fdt32_t;
95015b97f5cSMasahiro Yamada
95115b97f5cSMasahiro Yamada%include "libfdt/fdt.h"
95215b97f5cSMasahiro Yamada
95315b97f5cSMasahiro Yamada%include "typemaps.i"
95415b97f5cSMasahiro Yamada
95515b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */
95615b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) {
95715b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
95815b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
95915b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
96015b97f5cSMasahiro Yamada	}
96115b97f5cSMasahiro Yamada	$1 = (void *)PyByteArray_AsString($input);
96215b97f5cSMasahiro Yamada        fdt = $1;
96315b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
96415b97f5cSMasahiro Yamada}
96515b97f5cSMasahiro Yamada
96615b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */
96715b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) {
96815b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
96915b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
97015b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
97115b97f5cSMasahiro Yamada	}
97215b97f5cSMasahiro Yamada	$1 = PyByteArray_AsString($input);
97315b97f5cSMasahiro Yamada        fdt = $1;
97415b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
97515b97f5cSMasahiro Yamada}
97615b97f5cSMasahiro Yamada
9773def0cf2SSimon Glass/* typemap used for fdt_get_property_by_offset() */
97815b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) {
97915b97f5cSMasahiro Yamada	PyObject *buff;
98015b97f5cSMasahiro Yamada
98115b97f5cSMasahiro Yamada	if ($1) {
98215b97f5cSMasahiro Yamada		resultobj = PyString_FromString(
98315b97f5cSMasahiro Yamada			fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
98415b97f5cSMasahiro Yamada		buff = PyByteArray_FromStringAndSize(
98515b97f5cSMasahiro Yamada			(const char *)($1 + 1), fdt32_to_cpu($1->len));
98615b97f5cSMasahiro Yamada		resultobj = SWIG_Python_AppendOutput(resultobj, buff);
98715b97f5cSMasahiro Yamada	}
98815b97f5cSMasahiro Yamada}
98915b97f5cSMasahiro Yamada
99015b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp };
99115b97f5cSMasahiro Yamada
99215b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */
99315b97f5cSMasahiro Yamada%typemap(out) (const void *) {
99415b97f5cSMasahiro Yamada	if (!$1)
99515b97f5cSMasahiro Yamada		$result = Py_None;
99615b97f5cSMasahiro Yamada	else
99715b97f5cSMasahiro Yamada		$result = Py_BuildValue("s#", $1, *arg4);
99815b97f5cSMasahiro Yamada}
99915b97f5cSMasahiro Yamada
10003def0cf2SSimon Glass/* typemap used for fdt_setprop() */
10013def0cf2SSimon Glass%typemap(in) (const void *val) {
10023def0cf2SSimon Glass    $1 = PyString_AsString($input);   /* char *str */
10033def0cf2SSimon Glass}
10043def0cf2SSimon Glass
10053def0cf2SSimon Glass/* typemap used for fdt_add_reservemap_entry() */
10063def0cf2SSimon Glass%typemap(in) uint64_t {
10073def0cf2SSimon Glass   $1 = PyLong_AsUnsignedLong($input);
10083def0cf2SSimon Glass}
10093def0cf2SSimon Glass
10103def0cf2SSimon Glass/* typemaps used for fdt_next_node() */
10113def0cf2SSimon Glass%typemap(in, numinputs=1) int *depth (int depth) {
10123def0cf2SSimon Glass   depth = (int) PyInt_AsLong($input);
10133def0cf2SSimon Glass   $1 = &depth;
10143def0cf2SSimon Glass}
10153def0cf2SSimon Glass
10163def0cf2SSimon Glass%typemap(argout) int *depth {
10173def0cf2SSimon Glass        PyObject *val = Py_BuildValue("i", *arg$argnum);
10183def0cf2SSimon Glass        resultobj = SWIG_Python_AppendOutput(resultobj, val);
10193def0cf2SSimon Glass}
10203def0cf2SSimon Glass
10213def0cf2SSimon Glass%apply int *depth { int *depth };
10223def0cf2SSimon Glass
10233def0cf2SSimon Glass/* typemaps for fdt_get_mem_rsv */
10243def0cf2SSimon Glass%typemap(in, numinputs=0) uint64_t * (uint64_t temp) {
10253def0cf2SSimon Glass   $1 = &temp;
10263def0cf2SSimon Glass}
10273def0cf2SSimon Glass
10283def0cf2SSimon Glass%typemap(argout) uint64_t * {
10293def0cf2SSimon Glass        PyObject *val = PyLong_FromUnsignedLong(*arg$argnum);
10303def0cf2SSimon Glass        if (!result) {
10313def0cf2SSimon Glass           if (PyTuple_GET_SIZE(resultobj) == 0)
10323def0cf2SSimon Glass              resultobj = val;
10333def0cf2SSimon Glass           else
10343def0cf2SSimon Glass              resultobj = SWIG_Python_AppendOutput(resultobj, val);
10353def0cf2SSimon Glass        }
10363def0cf2SSimon Glass}
10373def0cf2SSimon Glass
103815b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */
103915b97f5cSMasahiro Yamada%warnfilter(302) fdt_property;
104015b97f5cSMasahiro Yamada
104115b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */
104215b97f5cSMasahiro Yamadaint fdt_magic(const void *fdt);
104315b97f5cSMasahiro Yamadaint fdt_totalsize(const void *fdt);
104415b97f5cSMasahiro Yamadaint fdt_off_dt_struct(const void *fdt);
104515b97f5cSMasahiro Yamadaint fdt_off_dt_strings(const void *fdt);
104615b97f5cSMasahiro Yamadaint fdt_off_mem_rsvmap(const void *fdt);
104715b97f5cSMasahiro Yamadaint fdt_version(const void *fdt);
104815b97f5cSMasahiro Yamadaint fdt_last_comp_version(const void *fdt);
104915b97f5cSMasahiro Yamadaint fdt_boot_cpuid_phys(const void *fdt);
105015b97f5cSMasahiro Yamadaint fdt_size_dt_strings(const void *fdt);
105115b97f5cSMasahiro Yamadaint fdt_size_dt_struct(const void *fdt);
10523def0cf2SSimon Glassint fdt_property_string(void *fdt, const char *name, const char *val);
10533def0cf2SSimon Glassint fdt_property_cell(void *fdt, const char *name, uint32_t val);
10543def0cf2SSimon Glass
10553def0cf2SSimon Glass/*
10563def0cf2SSimon Glass * This function has a stub since the name fdt_property is used for both a
10573def0cf2SSimon Glass  * function and a struct, which confuses SWIG.
10583def0cf2SSimon Glass */
10593def0cf2SSimon Glassint _fdt_property(void *fdt, const char *name, const char *val, int len);
106015b97f5cSMasahiro Yamada
106115b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h>
1062