1*4549e789STom 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"
1515b97f5cSMasahiro Yamada%}
1615b97f5cSMasahiro Yamada
1715b97f5cSMasahiro Yamada%pythoncode %{
1815b97f5cSMasahiro Yamada
1915b97f5cSMasahiro Yamadaimport struct
2015b97f5cSMasahiro Yamada
2115b97f5cSMasahiro Yamada# Error codes, corresponding to FDT_ERR_... in libfdt.h
2215b97f5cSMasahiro Yamada(NOTFOUND,
2315b97f5cSMasahiro Yamada        EXISTS,
2415b97f5cSMasahiro Yamada        NOSPACE,
2515b97f5cSMasahiro Yamada        BADOFFSET,
2615b97f5cSMasahiro Yamada        BADPATH,
2715b97f5cSMasahiro Yamada        BADPHANDLE,
2815b97f5cSMasahiro Yamada        BADSTATE,
2915b97f5cSMasahiro Yamada        TRUNCATED,
3015b97f5cSMasahiro Yamada        BADMAGIC,
3115b97f5cSMasahiro Yamada        BADVERSION,
3215b97f5cSMasahiro Yamada        BADSTRUCTURE,
3315b97f5cSMasahiro Yamada        BADLAYOUT,
3415b97f5cSMasahiro Yamada        INTERNAL,
3515b97f5cSMasahiro Yamada        BADNCELLS,
3615b97f5cSMasahiro Yamada        BADVALUE,
3715b97f5cSMasahiro Yamada        BADOVERLAY,
3815b97f5cSMasahiro Yamada        NOPHANDLES) = QUIET_ALL = range(1, 18)
3915b97f5cSMasahiro Yamada# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions
4015b97f5cSMasahiro Yamada# altogether. All # functions passed this value will return an error instead
4115b97f5cSMasahiro Yamada# of raising an exception.
4215b97f5cSMasahiro Yamada
4315b97f5cSMasahiro Yamada# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors,
4415b97f5cSMasahiro Yamada# instead of raising an exception.
4515b97f5cSMasahiro YamadaQUIET_NOTFOUND = (NOTFOUND,)
4615b97f5cSMasahiro Yamada
4715b97f5cSMasahiro Yamada
4815b97f5cSMasahiro Yamadaclass FdtException(Exception):
4915b97f5cSMasahiro Yamada    """An exception caused by an error such as one of the codes above"""
5015b97f5cSMasahiro Yamada    def __init__(self, err):
5115b97f5cSMasahiro Yamada        self.err = err
5215b97f5cSMasahiro Yamada
5315b97f5cSMasahiro Yamada    def __str__(self):
5415b97f5cSMasahiro Yamada        return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err))
5515b97f5cSMasahiro Yamada
5615b97f5cSMasahiro Yamadadef strerror(fdt_err):
5715b97f5cSMasahiro Yamada    """Get the string for an error number
5815b97f5cSMasahiro Yamada
5915b97f5cSMasahiro Yamada    Args:
6015b97f5cSMasahiro Yamada        fdt_err: Error number (-ve)
6115b97f5cSMasahiro Yamada
6215b97f5cSMasahiro Yamada    Returns:
6315b97f5cSMasahiro Yamada        String containing the associated error
6415b97f5cSMasahiro Yamada    """
6515b97f5cSMasahiro Yamada    return fdt_strerror(fdt_err)
6615b97f5cSMasahiro Yamada
6715b97f5cSMasahiro Yamadadef check_err(val, quiet=()):
6815b97f5cSMasahiro Yamada    """Raise an error if the return value is -ve
6915b97f5cSMasahiro Yamada
7015b97f5cSMasahiro Yamada    This is used to check for errors returned by libfdt C functions.
7115b97f5cSMasahiro Yamada
7215b97f5cSMasahiro Yamada    Args:
7315b97f5cSMasahiro Yamada        val: Return value from a libfdt function
7415b97f5cSMasahiro Yamada        quiet: Errors to ignore (empty to raise on all errors)
7515b97f5cSMasahiro Yamada
7615b97f5cSMasahiro Yamada    Returns:
7715b97f5cSMasahiro Yamada        val if val >= 0
7815b97f5cSMasahiro Yamada
7915b97f5cSMasahiro Yamada    Raises
8015b97f5cSMasahiro Yamada        FdtException if val < 0
8115b97f5cSMasahiro Yamada    """
8215b97f5cSMasahiro Yamada    if val < 0:
8315b97f5cSMasahiro Yamada        if -val not in quiet:
8415b97f5cSMasahiro Yamada            raise FdtException(val)
8515b97f5cSMasahiro Yamada    return val
8615b97f5cSMasahiro Yamada
8715b97f5cSMasahiro Yamadadef check_err_null(val, quiet=()):
8815b97f5cSMasahiro Yamada    """Raise an error if the return value is NULL
8915b97f5cSMasahiro Yamada
9015b97f5cSMasahiro Yamada    This is used to check for a NULL return value from certain libfdt C
9115b97f5cSMasahiro Yamada    functions
9215b97f5cSMasahiro Yamada
9315b97f5cSMasahiro Yamada    Args:
9415b97f5cSMasahiro Yamada        val: Return value from a libfdt function
9515b97f5cSMasahiro Yamada        quiet: Errors to ignore (empty to raise on all errors)
9615b97f5cSMasahiro Yamada
9715b97f5cSMasahiro Yamada    Returns:
9815b97f5cSMasahiro Yamada        val if val is a list, None if not
9915b97f5cSMasahiro Yamada
10015b97f5cSMasahiro Yamada    Raises
10115b97f5cSMasahiro Yamada        FdtException if val indicates an error was reported and the error
10215b97f5cSMasahiro Yamada        is not in @quiet.
10315b97f5cSMasahiro Yamada    """
10415b97f5cSMasahiro Yamada    # Normally a list is returned which contains the data and its length.
10515b97f5cSMasahiro Yamada    # If we get just an integer error code, it means the function failed.
10615b97f5cSMasahiro Yamada    if not isinstance(val, list):
10715b97f5cSMasahiro Yamada        if -val not in quiet:
10815b97f5cSMasahiro Yamada            raise FdtException(val)
10915b97f5cSMasahiro Yamada    return val
11015b97f5cSMasahiro Yamada
11115b97f5cSMasahiro Yamadaclass Fdt:
11215b97f5cSMasahiro Yamada    """Device tree class, supporting all operations
11315b97f5cSMasahiro Yamada
11415b97f5cSMasahiro Yamada    The Fdt object is created is created from a device tree binary file,
11515b97f5cSMasahiro Yamada    e.g. with something like:
11615b97f5cSMasahiro Yamada
11715b97f5cSMasahiro Yamada       fdt = Fdt(open("filename.dtb").read())
11815b97f5cSMasahiro Yamada
11915b97f5cSMasahiro Yamada    Operations can then be performed using the methods in this class. Each
12015b97f5cSMasahiro Yamada    method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...).
12115b97f5cSMasahiro Yamada
12215b97f5cSMasahiro Yamada    All methods raise an FdtException if an error occurs. To avoid this
12315b97f5cSMasahiro Yamada    behaviour a 'quiet' parameter is provided for some functions. This
12415b97f5cSMasahiro Yamada    defaults to empty, but you can pass a list of errors that you expect.
12515b97f5cSMasahiro Yamada    If one of these errors occurs, the function will return an error number
12615b97f5cSMasahiro Yamada    (e.g. -NOTFOUND).
12715b97f5cSMasahiro Yamada    """
12815b97f5cSMasahiro Yamada    def __init__(self, data):
12915b97f5cSMasahiro Yamada        self._fdt = bytearray(data)
13015b97f5cSMasahiro Yamada        check_err(fdt_check_header(self._fdt));
13115b97f5cSMasahiro Yamada
13215b97f5cSMasahiro Yamada    def subnode_offset(self, parentoffset, name, quiet=()):
13315b97f5cSMasahiro Yamada        """Get the offset of a named subnode
13415b97f5cSMasahiro Yamada
13515b97f5cSMasahiro Yamada        Args:
13615b97f5cSMasahiro Yamada            parentoffset: Offset of the parent node to check
13715b97f5cSMasahiro Yamada            name: Name of the required subnode, e.g. 'subnode@1'
13815b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
13915b97f5cSMasahiro Yamada
14015b97f5cSMasahiro Yamada        Returns:
14115b97f5cSMasahiro Yamada            The node offset of the found node, if any
14215b97f5cSMasahiro Yamada
14315b97f5cSMasahiro Yamada        Raises
14415b97f5cSMasahiro Yamada            FdtException if there is no node with that name, or other error
14515b97f5cSMasahiro Yamada        """
14615b97f5cSMasahiro Yamada        return check_err(fdt_subnode_offset(self._fdt, parentoffset, name),
14715b97f5cSMasahiro Yamada                         quiet)
14815b97f5cSMasahiro Yamada
14915b97f5cSMasahiro Yamada    def path_offset(self, path, quiet=()):
15015b97f5cSMasahiro Yamada        """Get the offset for a given path
15115b97f5cSMasahiro Yamada
15215b97f5cSMasahiro Yamada        Args:
15315b97f5cSMasahiro Yamada            path: Path to the required node, e.g. '/node@3/subnode@1'
15415b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
15515b97f5cSMasahiro Yamada
15615b97f5cSMasahiro Yamada        Returns:
15715b97f5cSMasahiro Yamada            Node offset
15815b97f5cSMasahiro Yamada
15915b97f5cSMasahiro Yamada        Raises
16015b97f5cSMasahiro Yamada            FdtException if the path is not valid or not found
16115b97f5cSMasahiro Yamada        """
16215b97f5cSMasahiro Yamada        return check_err(fdt_path_offset(self._fdt, path), quiet)
16315b97f5cSMasahiro Yamada
16415b97f5cSMasahiro Yamada    def first_property_offset(self, nodeoffset, quiet=()):
16515b97f5cSMasahiro Yamada        """Get the offset of the first property in a node offset
16615b97f5cSMasahiro Yamada
16715b97f5cSMasahiro Yamada        Args:
16815b97f5cSMasahiro Yamada            nodeoffset: Offset to the node to check
16915b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
17015b97f5cSMasahiro Yamada
17115b97f5cSMasahiro Yamada        Returns:
17215b97f5cSMasahiro Yamada            Offset of the first property
17315b97f5cSMasahiro Yamada
17415b97f5cSMasahiro Yamada        Raises
17515b97f5cSMasahiro Yamada            FdtException if the associated node has no properties, or some
17615b97f5cSMasahiro Yamada                other error occurred
17715b97f5cSMasahiro Yamada        """
17815b97f5cSMasahiro Yamada        return check_err(fdt_first_property_offset(self._fdt, nodeoffset),
17915b97f5cSMasahiro Yamada                         quiet)
18015b97f5cSMasahiro Yamada
18115b97f5cSMasahiro Yamada    def next_property_offset(self, prop_offset, quiet=()):
18215b97f5cSMasahiro Yamada        """Get the next property in a node
18315b97f5cSMasahiro Yamada
18415b97f5cSMasahiro Yamada        Args:
18515b97f5cSMasahiro Yamada            prop_offset: Offset of the previous property
18615b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
18715b97f5cSMasahiro Yamada
18815b97f5cSMasahiro Yamada        Returns:
18915b97f5cSMasahiro Yamada            Offset of the next property
19015b97f5cSMasahiro Yamada
19115b97f5cSMasahiro Yamada        Raises:
19215b97f5cSMasahiro Yamada            FdtException if the associated node has no more properties, or
19315b97f5cSMasahiro Yamada                some other error occurred
19415b97f5cSMasahiro Yamada        """
19515b97f5cSMasahiro Yamada        return check_err(fdt_next_property_offset(self._fdt, prop_offset),
19615b97f5cSMasahiro Yamada                         quiet)
19715b97f5cSMasahiro Yamada
19815b97f5cSMasahiro Yamada    def get_name(self, nodeoffset):
19915b97f5cSMasahiro Yamada        """Get the name of a node
20015b97f5cSMasahiro Yamada
20115b97f5cSMasahiro Yamada        Args:
20215b97f5cSMasahiro Yamada            nodeoffset: Offset of node to check
20315b97f5cSMasahiro Yamada
20415b97f5cSMasahiro Yamada        Returns:
20515b97f5cSMasahiro Yamada            Node name
20615b97f5cSMasahiro Yamada
20715b97f5cSMasahiro Yamada        Raises:
20815b97f5cSMasahiro Yamada            FdtException on error (e.g. nodeoffset is invalid)
20915b97f5cSMasahiro Yamada        """
21015b97f5cSMasahiro Yamada        return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0]
21115b97f5cSMasahiro Yamada
21215b97f5cSMasahiro Yamada    def get_property_by_offset(self, prop_offset, quiet=()):
21315b97f5cSMasahiro Yamada        """Obtains a property that can be examined
21415b97f5cSMasahiro Yamada
21515b97f5cSMasahiro Yamada        Args:
21615b97f5cSMasahiro Yamada            prop_offset: Offset of property (e.g. from first_property_offset())
21715b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
21815b97f5cSMasahiro Yamada
21915b97f5cSMasahiro Yamada        Returns:
22015b97f5cSMasahiro Yamada            Property object, or None if not found
22115b97f5cSMasahiro Yamada
22215b97f5cSMasahiro Yamada        Raises:
22315b97f5cSMasahiro Yamada            FdtException on error (e.g. invalid prop_offset or device
22415b97f5cSMasahiro Yamada            tree format)
22515b97f5cSMasahiro Yamada        """
22615b97f5cSMasahiro Yamada        pdata = check_err_null(
22715b97f5cSMasahiro Yamada                fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
22815b97f5cSMasahiro Yamada        if isinstance(pdata, (int)):
22915b97f5cSMasahiro Yamada            return pdata
23015b97f5cSMasahiro Yamada        return Property(pdata[0], pdata[1])
23115b97f5cSMasahiro Yamada
23215b97f5cSMasahiro Yamada    def first_subnode(self, nodeoffset, quiet=()):
23315b97f5cSMasahiro Yamada        """Find the first subnode of a parent node
23415b97f5cSMasahiro Yamada
23515b97f5cSMasahiro Yamada        Args:
23615b97f5cSMasahiro Yamada            nodeoffset: Node offset of parent node
23715b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
23815b97f5cSMasahiro Yamada
23915b97f5cSMasahiro Yamada        Returns:
24015b97f5cSMasahiro Yamada            The offset of the first subnode, if any
24115b97f5cSMasahiro Yamada
24215b97f5cSMasahiro Yamada        Raises:
24315b97f5cSMasahiro Yamada            FdtException if no subnode found or other error occurs
24415b97f5cSMasahiro Yamada        """
24515b97f5cSMasahiro Yamada        return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet)
24615b97f5cSMasahiro Yamada
24715b97f5cSMasahiro Yamada    def next_subnode(self, nodeoffset, quiet=()):
24815b97f5cSMasahiro Yamada        """Find the next subnode
24915b97f5cSMasahiro Yamada
25015b97f5cSMasahiro Yamada        Args:
25115b97f5cSMasahiro Yamada            nodeoffset: Node offset of previous subnode
25215b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
25315b97f5cSMasahiro Yamada
25415b97f5cSMasahiro Yamada        Returns:
25515b97f5cSMasahiro Yamada            The offset of the next subnode, if any
25615b97f5cSMasahiro Yamada
25715b97f5cSMasahiro Yamada        Raises:
25815b97f5cSMasahiro Yamada            FdtException if no more subnode found or other error occurs
25915b97f5cSMasahiro Yamada        """
26015b97f5cSMasahiro Yamada        return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
26115b97f5cSMasahiro Yamada
26215b97f5cSMasahiro Yamada    def totalsize(self):
26315b97f5cSMasahiro Yamada        """Return the total size of the device tree
26415b97f5cSMasahiro Yamada
26515b97f5cSMasahiro Yamada        Returns:
26615b97f5cSMasahiro Yamada            Total tree size in bytes
26715b97f5cSMasahiro Yamada        """
26815b97f5cSMasahiro Yamada        return check_err(fdt_totalsize(self._fdt))
26915b97f5cSMasahiro Yamada
27015b97f5cSMasahiro Yamada    def off_dt_struct(self):
27115b97f5cSMasahiro Yamada        """Return the start of the device tree struct area
27215b97f5cSMasahiro Yamada
27315b97f5cSMasahiro Yamada        Returns:
27415b97f5cSMasahiro Yamada            Start offset of struct area
27515b97f5cSMasahiro Yamada        """
27615b97f5cSMasahiro Yamada        return check_err(fdt_off_dt_struct(self._fdt))
27715b97f5cSMasahiro Yamada
27815b97f5cSMasahiro Yamada    def pack(self, quiet=()):
27915b97f5cSMasahiro Yamada        """Pack the device tree to remove unused space
28015b97f5cSMasahiro Yamada
28115b97f5cSMasahiro Yamada        This adjusts the tree in place.
28215b97f5cSMasahiro Yamada
28315b97f5cSMasahiro Yamada        Args:
28415b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
28515b97f5cSMasahiro Yamada
28615b97f5cSMasahiro Yamada        Raises:
28715b97f5cSMasahiro Yamada            FdtException if any error occurs
28815b97f5cSMasahiro Yamada        """
28915b97f5cSMasahiro Yamada        return check_err(fdt_pack(self._fdt), quiet)
29015b97f5cSMasahiro Yamada
29115b97f5cSMasahiro Yamada    def delprop(self, nodeoffset, prop_name):
29215b97f5cSMasahiro Yamada        """Delete a property from a node
29315b97f5cSMasahiro Yamada
29415b97f5cSMasahiro Yamada        Args:
29515b97f5cSMasahiro Yamada            nodeoffset: Node offset containing property to delete
29615b97f5cSMasahiro Yamada            prop_name: Name of property to delete
29715b97f5cSMasahiro Yamada
29815b97f5cSMasahiro Yamada        Raises:
29915b97f5cSMasahiro Yamada            FdtError if the property does not exist, or another error occurs
30015b97f5cSMasahiro Yamada        """
30115b97f5cSMasahiro Yamada        return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
30215b97f5cSMasahiro Yamada
30315b97f5cSMasahiro Yamada    def getprop(self, nodeoffset, prop_name, quiet=()):
30415b97f5cSMasahiro Yamada        """Get a property from a node
30515b97f5cSMasahiro Yamada
30615b97f5cSMasahiro Yamada        Args:
30715b97f5cSMasahiro Yamada            nodeoffset: Node offset containing property to get
30815b97f5cSMasahiro Yamada            prop_name: Name of property to get
30915b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
31015b97f5cSMasahiro Yamada
31115b97f5cSMasahiro Yamada        Returns:
31215b97f5cSMasahiro Yamada            Value of property as a bytearray, or -ve error number
31315b97f5cSMasahiro Yamada
31415b97f5cSMasahiro Yamada        Raises:
31515b97f5cSMasahiro Yamada            FdtError if any error occurs (e.g. the property is not found)
31615b97f5cSMasahiro Yamada        """
31715b97f5cSMasahiro Yamada        pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
31815b97f5cSMasahiro Yamada                               quiet)
31915b97f5cSMasahiro Yamada        if isinstance(pdata, (int)):
32015b97f5cSMasahiro Yamada            return pdata
32115b97f5cSMasahiro Yamada        return bytearray(pdata[0])
32215b97f5cSMasahiro Yamada
32315b97f5cSMasahiro Yamada    def get_phandle(self, nodeoffset):
32415b97f5cSMasahiro Yamada        """Get the phandle of a node
32515b97f5cSMasahiro Yamada
32615b97f5cSMasahiro Yamada        Args:
32715b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
32815b97f5cSMasahiro Yamada
32915b97f5cSMasahiro Yamada        Returns:
33015b97f5cSMasahiro Yamada            phandle of node, or 0 if the node has no phandle or another error
33115b97f5cSMasahiro Yamada            occurs
33215b97f5cSMasahiro Yamada        """
33315b97f5cSMasahiro Yamada        return fdt_get_phandle(self._fdt, nodeoffset)
33415b97f5cSMasahiro Yamada
33515b97f5cSMasahiro Yamada    def parent_offset(self, nodeoffset, quiet=()):
33615b97f5cSMasahiro Yamada        """Get the offset of a node's parent
33715b97f5cSMasahiro Yamada
33815b97f5cSMasahiro Yamada        Args:
33915b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
34015b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
34115b97f5cSMasahiro Yamada
34215b97f5cSMasahiro Yamada        Returns:
34315b97f5cSMasahiro Yamada            The offset of the parent node, if any
34415b97f5cSMasahiro Yamada
34515b97f5cSMasahiro Yamada        Raises:
34615b97f5cSMasahiro Yamada            FdtException if no parent found or other error occurs
34715b97f5cSMasahiro Yamada        """
34815b97f5cSMasahiro Yamada        return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
34915b97f5cSMasahiro Yamada
35015b97f5cSMasahiro Yamada    def node_offset_by_phandle(self, phandle, quiet=()):
35115b97f5cSMasahiro Yamada        """Get the offset of a node with the given phandle
35215b97f5cSMasahiro Yamada
35315b97f5cSMasahiro Yamada        Args:
35415b97f5cSMasahiro Yamada            phandle: Phandle to search for
35515b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
35615b97f5cSMasahiro Yamada
35715b97f5cSMasahiro Yamada        Returns:
35815b97f5cSMasahiro Yamada            The offset of node with that phandle, if any
35915b97f5cSMasahiro Yamada
36015b97f5cSMasahiro Yamada        Raises:
36115b97f5cSMasahiro Yamada            FdtException if no node found or other error occurs
36215b97f5cSMasahiro Yamada        """
36315b97f5cSMasahiro Yamada        return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
36415b97f5cSMasahiro Yamada
36515b97f5cSMasahiro Yamadaclass Property:
36615b97f5cSMasahiro Yamada    """Holds a device tree property name and value.
36715b97f5cSMasahiro Yamada
36815b97f5cSMasahiro Yamada    This holds a copy of a property taken from the device tree. It does not
36915b97f5cSMasahiro Yamada    reference the device tree, so if anything changes in the device tree,
37015b97f5cSMasahiro Yamada    a Property object will remain valid.
37115b97f5cSMasahiro Yamada
37215b97f5cSMasahiro Yamada    Properties:
37315b97f5cSMasahiro Yamada        name: Property name
37415b97f5cSMasahiro Yamada        value: Proper value as a bytearray
37515b97f5cSMasahiro Yamada    """
37615b97f5cSMasahiro Yamada    def __init__(self, name, value):
37715b97f5cSMasahiro Yamada        self.name = name
37815b97f5cSMasahiro Yamada        self.value = value
37915b97f5cSMasahiro Yamada%}
38015b97f5cSMasahiro Yamada
38115b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func;
38215b97f5cSMasahiro Yamada
38315b97f5cSMasahiro Yamadatypedef int fdt32_t;
38415b97f5cSMasahiro Yamada
38515b97f5cSMasahiro Yamada%include "libfdt/fdt.h"
38615b97f5cSMasahiro Yamada
38715b97f5cSMasahiro Yamada%include "typemaps.i"
38815b97f5cSMasahiro Yamada
38915b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */
39015b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) {
39115b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
39215b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
39315b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
39415b97f5cSMasahiro Yamada	}
39515b97f5cSMasahiro Yamada	$1 = (void *)PyByteArray_AsString($input);
39615b97f5cSMasahiro Yamada        fdt = $1;
39715b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
39815b97f5cSMasahiro Yamada}
39915b97f5cSMasahiro Yamada
40015b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */
40115b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) {
40215b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
40315b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
40415b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
40515b97f5cSMasahiro Yamada	}
40615b97f5cSMasahiro Yamada	$1 = PyByteArray_AsString($input);
40715b97f5cSMasahiro Yamada        fdt = $1;
40815b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
40915b97f5cSMasahiro Yamada}
41015b97f5cSMasahiro Yamada
41115b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) {
41215b97f5cSMasahiro Yamada	PyObject *buff;
41315b97f5cSMasahiro Yamada
41415b97f5cSMasahiro Yamada	if ($1) {
41515b97f5cSMasahiro Yamada		resultobj = PyString_FromString(
41615b97f5cSMasahiro Yamada			fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
41715b97f5cSMasahiro Yamada		buff = PyByteArray_FromStringAndSize(
41815b97f5cSMasahiro Yamada			(const char *)($1 + 1), fdt32_to_cpu($1->len));
41915b97f5cSMasahiro Yamada		resultobj = SWIG_Python_AppendOutput(resultobj, buff);
42015b97f5cSMasahiro Yamada	}
42115b97f5cSMasahiro Yamada}
42215b97f5cSMasahiro Yamada
42315b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp };
42415b97f5cSMasahiro Yamada
42515b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */
42615b97f5cSMasahiro Yamada%typemap(out) (const void *) {
42715b97f5cSMasahiro Yamada	if (!$1)
42815b97f5cSMasahiro Yamada		$result = Py_None;
42915b97f5cSMasahiro Yamada	else
43015b97f5cSMasahiro Yamada		$result = Py_BuildValue("s#", $1, *arg4);
43115b97f5cSMasahiro Yamada}
43215b97f5cSMasahiro Yamada
43315b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */
43415b97f5cSMasahiro Yamada%warnfilter(302) fdt_property;
43515b97f5cSMasahiro Yamada
43615b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */
43715b97f5cSMasahiro Yamadaint fdt_magic(const void *fdt);
43815b97f5cSMasahiro Yamadaint fdt_totalsize(const void *fdt);
43915b97f5cSMasahiro Yamadaint fdt_off_dt_struct(const void *fdt);
44015b97f5cSMasahiro Yamadaint fdt_off_dt_strings(const void *fdt);
44115b97f5cSMasahiro Yamadaint fdt_off_mem_rsvmap(const void *fdt);
44215b97f5cSMasahiro Yamadaint fdt_version(const void *fdt);
44315b97f5cSMasahiro Yamadaint fdt_last_comp_version(const void *fdt);
44415b97f5cSMasahiro Yamadaint fdt_boot_cpuid_phys(const void *fdt);
44515b97f5cSMasahiro Yamadaint fdt_size_dt_strings(const void *fdt);
44615b97f5cSMasahiro Yamadaint fdt_size_dt_struct(const void *fdt);
44715b97f5cSMasahiro Yamada
44815b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h>
449