1*15b97f5cSMasahiro Yamada/*
2*15b97f5cSMasahiro Yamada * pylibfdt - Flat Device Tree manipulation in Python
3*15b97f5cSMasahiro Yamada * Copyright (C) 2017 Google, Inc.
4*15b97f5cSMasahiro Yamada * Written by Simon Glass <sjg@chromium.org>
5*15b97f5cSMasahiro Yamada *
6*15b97f5cSMasahiro Yamada * SPDX-License-Identifier:	GPL-2.0+ BSD-2-Clause
7*15b97f5cSMasahiro Yamada */
8*15b97f5cSMasahiro Yamada
9*15b97f5cSMasahiro Yamada%module libfdt
10*15b97f5cSMasahiro Yamada
11*15b97f5cSMasahiro Yamada%include <stdint.i>
12*15b97f5cSMasahiro Yamada
13*15b97f5cSMasahiro Yamada%{
14*15b97f5cSMasahiro Yamada#define SWIG_FILE_WITH_INIT
15*15b97f5cSMasahiro Yamada#include "libfdt.h"
16*15b97f5cSMasahiro Yamada%}
17*15b97f5cSMasahiro Yamada
18*15b97f5cSMasahiro Yamada%pythoncode %{
19*15b97f5cSMasahiro Yamada
20*15b97f5cSMasahiro Yamadaimport struct
21*15b97f5cSMasahiro Yamada
22*15b97f5cSMasahiro Yamada# Error codes, corresponding to FDT_ERR_... in libfdt.h
23*15b97f5cSMasahiro Yamada(NOTFOUND,
24*15b97f5cSMasahiro Yamada        EXISTS,
25*15b97f5cSMasahiro Yamada        NOSPACE,
26*15b97f5cSMasahiro Yamada        BADOFFSET,
27*15b97f5cSMasahiro Yamada        BADPATH,
28*15b97f5cSMasahiro Yamada        BADPHANDLE,
29*15b97f5cSMasahiro Yamada        BADSTATE,
30*15b97f5cSMasahiro Yamada        TRUNCATED,
31*15b97f5cSMasahiro Yamada        BADMAGIC,
32*15b97f5cSMasahiro Yamada        BADVERSION,
33*15b97f5cSMasahiro Yamada        BADSTRUCTURE,
34*15b97f5cSMasahiro Yamada        BADLAYOUT,
35*15b97f5cSMasahiro Yamada        INTERNAL,
36*15b97f5cSMasahiro Yamada        BADNCELLS,
37*15b97f5cSMasahiro Yamada        BADVALUE,
38*15b97f5cSMasahiro Yamada        BADOVERLAY,
39*15b97f5cSMasahiro Yamada        NOPHANDLES) = QUIET_ALL = range(1, 18)
40*15b97f5cSMasahiro Yamada# QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions
41*15b97f5cSMasahiro Yamada# altogether. All # functions passed this value will return an error instead
42*15b97f5cSMasahiro Yamada# of raising an exception.
43*15b97f5cSMasahiro Yamada
44*15b97f5cSMasahiro Yamada# Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors,
45*15b97f5cSMasahiro Yamada# instead of raising an exception.
46*15b97f5cSMasahiro YamadaQUIET_NOTFOUND = (NOTFOUND,)
47*15b97f5cSMasahiro Yamada
48*15b97f5cSMasahiro Yamada
49*15b97f5cSMasahiro Yamadaclass FdtException(Exception):
50*15b97f5cSMasahiro Yamada    """An exception caused by an error such as one of the codes above"""
51*15b97f5cSMasahiro Yamada    def __init__(self, err):
52*15b97f5cSMasahiro Yamada        self.err = err
53*15b97f5cSMasahiro Yamada
54*15b97f5cSMasahiro Yamada    def __str__(self):
55*15b97f5cSMasahiro Yamada        return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err))
56*15b97f5cSMasahiro Yamada
57*15b97f5cSMasahiro Yamadadef strerror(fdt_err):
58*15b97f5cSMasahiro Yamada    """Get the string for an error number
59*15b97f5cSMasahiro Yamada
60*15b97f5cSMasahiro Yamada    Args:
61*15b97f5cSMasahiro Yamada        fdt_err: Error number (-ve)
62*15b97f5cSMasahiro Yamada
63*15b97f5cSMasahiro Yamada    Returns:
64*15b97f5cSMasahiro Yamada        String containing the associated error
65*15b97f5cSMasahiro Yamada    """
66*15b97f5cSMasahiro Yamada    return fdt_strerror(fdt_err)
67*15b97f5cSMasahiro Yamada
68*15b97f5cSMasahiro Yamadadef check_err(val, quiet=()):
69*15b97f5cSMasahiro Yamada    """Raise an error if the return value is -ve
70*15b97f5cSMasahiro Yamada
71*15b97f5cSMasahiro Yamada    This is used to check for errors returned by libfdt C functions.
72*15b97f5cSMasahiro Yamada
73*15b97f5cSMasahiro Yamada    Args:
74*15b97f5cSMasahiro Yamada        val: Return value from a libfdt function
75*15b97f5cSMasahiro Yamada        quiet: Errors to ignore (empty to raise on all errors)
76*15b97f5cSMasahiro Yamada
77*15b97f5cSMasahiro Yamada    Returns:
78*15b97f5cSMasahiro Yamada        val if val >= 0
79*15b97f5cSMasahiro Yamada
80*15b97f5cSMasahiro Yamada    Raises
81*15b97f5cSMasahiro Yamada        FdtException if val < 0
82*15b97f5cSMasahiro Yamada    """
83*15b97f5cSMasahiro Yamada    if val < 0:
84*15b97f5cSMasahiro Yamada        if -val not in quiet:
85*15b97f5cSMasahiro Yamada            raise FdtException(val)
86*15b97f5cSMasahiro Yamada    return val
87*15b97f5cSMasahiro Yamada
88*15b97f5cSMasahiro Yamadadef check_err_null(val, quiet=()):
89*15b97f5cSMasahiro Yamada    """Raise an error if the return value is NULL
90*15b97f5cSMasahiro Yamada
91*15b97f5cSMasahiro Yamada    This is used to check for a NULL return value from certain libfdt C
92*15b97f5cSMasahiro Yamada    functions
93*15b97f5cSMasahiro Yamada
94*15b97f5cSMasahiro Yamada    Args:
95*15b97f5cSMasahiro Yamada        val: Return value from a libfdt function
96*15b97f5cSMasahiro Yamada        quiet: Errors to ignore (empty to raise on all errors)
97*15b97f5cSMasahiro Yamada
98*15b97f5cSMasahiro Yamada    Returns:
99*15b97f5cSMasahiro Yamada        val if val is a list, None if not
100*15b97f5cSMasahiro Yamada
101*15b97f5cSMasahiro Yamada    Raises
102*15b97f5cSMasahiro Yamada        FdtException if val indicates an error was reported and the error
103*15b97f5cSMasahiro Yamada        is not in @quiet.
104*15b97f5cSMasahiro Yamada    """
105*15b97f5cSMasahiro Yamada    # Normally a list is returned which contains the data and its length.
106*15b97f5cSMasahiro Yamada    # If we get just an integer error code, it means the function failed.
107*15b97f5cSMasahiro Yamada    if not isinstance(val, list):
108*15b97f5cSMasahiro Yamada        if -val not in quiet:
109*15b97f5cSMasahiro Yamada            raise FdtException(val)
110*15b97f5cSMasahiro Yamada    return val
111*15b97f5cSMasahiro Yamada
112*15b97f5cSMasahiro Yamadaclass Fdt:
113*15b97f5cSMasahiro Yamada    """Device tree class, supporting all operations
114*15b97f5cSMasahiro Yamada
115*15b97f5cSMasahiro Yamada    The Fdt object is created is created from a device tree binary file,
116*15b97f5cSMasahiro Yamada    e.g. with something like:
117*15b97f5cSMasahiro Yamada
118*15b97f5cSMasahiro Yamada       fdt = Fdt(open("filename.dtb").read())
119*15b97f5cSMasahiro Yamada
120*15b97f5cSMasahiro Yamada    Operations can then be performed using the methods in this class. Each
121*15b97f5cSMasahiro Yamada    method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...).
122*15b97f5cSMasahiro Yamada
123*15b97f5cSMasahiro Yamada    All methods raise an FdtException if an error occurs. To avoid this
124*15b97f5cSMasahiro Yamada    behaviour a 'quiet' parameter is provided for some functions. This
125*15b97f5cSMasahiro Yamada    defaults to empty, but you can pass a list of errors that you expect.
126*15b97f5cSMasahiro Yamada    If one of these errors occurs, the function will return an error number
127*15b97f5cSMasahiro Yamada    (e.g. -NOTFOUND).
128*15b97f5cSMasahiro Yamada    """
129*15b97f5cSMasahiro Yamada    def __init__(self, data):
130*15b97f5cSMasahiro Yamada        self._fdt = bytearray(data)
131*15b97f5cSMasahiro Yamada        check_err(fdt_check_header(self._fdt));
132*15b97f5cSMasahiro Yamada
133*15b97f5cSMasahiro Yamada    def subnode_offset(self, parentoffset, name, quiet=()):
134*15b97f5cSMasahiro Yamada        """Get the offset of a named subnode
135*15b97f5cSMasahiro Yamada
136*15b97f5cSMasahiro Yamada        Args:
137*15b97f5cSMasahiro Yamada            parentoffset: Offset of the parent node to check
138*15b97f5cSMasahiro Yamada            name: Name of the required subnode, e.g. 'subnode@1'
139*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
140*15b97f5cSMasahiro Yamada
141*15b97f5cSMasahiro Yamada        Returns:
142*15b97f5cSMasahiro Yamada            The node offset of the found node, if any
143*15b97f5cSMasahiro Yamada
144*15b97f5cSMasahiro Yamada        Raises
145*15b97f5cSMasahiro Yamada            FdtException if there is no node with that name, or other error
146*15b97f5cSMasahiro Yamada        """
147*15b97f5cSMasahiro Yamada        return check_err(fdt_subnode_offset(self._fdt, parentoffset, name),
148*15b97f5cSMasahiro Yamada                         quiet)
149*15b97f5cSMasahiro Yamada
150*15b97f5cSMasahiro Yamada    def path_offset(self, path, quiet=()):
151*15b97f5cSMasahiro Yamada        """Get the offset for a given path
152*15b97f5cSMasahiro Yamada
153*15b97f5cSMasahiro Yamada        Args:
154*15b97f5cSMasahiro Yamada            path: Path to the required node, e.g. '/node@3/subnode@1'
155*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
156*15b97f5cSMasahiro Yamada
157*15b97f5cSMasahiro Yamada        Returns:
158*15b97f5cSMasahiro Yamada            Node offset
159*15b97f5cSMasahiro Yamada
160*15b97f5cSMasahiro Yamada        Raises
161*15b97f5cSMasahiro Yamada            FdtException if the path is not valid or not found
162*15b97f5cSMasahiro Yamada        """
163*15b97f5cSMasahiro Yamada        return check_err(fdt_path_offset(self._fdt, path), quiet)
164*15b97f5cSMasahiro Yamada
165*15b97f5cSMasahiro Yamada    def first_property_offset(self, nodeoffset, quiet=()):
166*15b97f5cSMasahiro Yamada        """Get the offset of the first property in a node offset
167*15b97f5cSMasahiro Yamada
168*15b97f5cSMasahiro Yamada        Args:
169*15b97f5cSMasahiro Yamada            nodeoffset: Offset to the node to check
170*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
171*15b97f5cSMasahiro Yamada
172*15b97f5cSMasahiro Yamada        Returns:
173*15b97f5cSMasahiro Yamada            Offset of the first property
174*15b97f5cSMasahiro Yamada
175*15b97f5cSMasahiro Yamada        Raises
176*15b97f5cSMasahiro Yamada            FdtException if the associated node has no properties, or some
177*15b97f5cSMasahiro Yamada                other error occurred
178*15b97f5cSMasahiro Yamada        """
179*15b97f5cSMasahiro Yamada        return check_err(fdt_first_property_offset(self._fdt, nodeoffset),
180*15b97f5cSMasahiro Yamada                         quiet)
181*15b97f5cSMasahiro Yamada
182*15b97f5cSMasahiro Yamada    def next_property_offset(self, prop_offset, quiet=()):
183*15b97f5cSMasahiro Yamada        """Get the next property in a node
184*15b97f5cSMasahiro Yamada
185*15b97f5cSMasahiro Yamada        Args:
186*15b97f5cSMasahiro Yamada            prop_offset: Offset of the previous property
187*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
188*15b97f5cSMasahiro Yamada
189*15b97f5cSMasahiro Yamada        Returns:
190*15b97f5cSMasahiro Yamada            Offset of the next property
191*15b97f5cSMasahiro Yamada
192*15b97f5cSMasahiro Yamada        Raises:
193*15b97f5cSMasahiro Yamada            FdtException if the associated node has no more properties, or
194*15b97f5cSMasahiro Yamada                some other error occurred
195*15b97f5cSMasahiro Yamada        """
196*15b97f5cSMasahiro Yamada        return check_err(fdt_next_property_offset(self._fdt, prop_offset),
197*15b97f5cSMasahiro Yamada                         quiet)
198*15b97f5cSMasahiro Yamada
199*15b97f5cSMasahiro Yamada    def get_name(self, nodeoffset):
200*15b97f5cSMasahiro Yamada        """Get the name of a node
201*15b97f5cSMasahiro Yamada
202*15b97f5cSMasahiro Yamada        Args:
203*15b97f5cSMasahiro Yamada            nodeoffset: Offset of node to check
204*15b97f5cSMasahiro Yamada
205*15b97f5cSMasahiro Yamada        Returns:
206*15b97f5cSMasahiro Yamada            Node name
207*15b97f5cSMasahiro Yamada
208*15b97f5cSMasahiro Yamada        Raises:
209*15b97f5cSMasahiro Yamada            FdtException on error (e.g. nodeoffset is invalid)
210*15b97f5cSMasahiro Yamada        """
211*15b97f5cSMasahiro Yamada        return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0]
212*15b97f5cSMasahiro Yamada
213*15b97f5cSMasahiro Yamada    def get_property_by_offset(self, prop_offset, quiet=()):
214*15b97f5cSMasahiro Yamada        """Obtains a property that can be examined
215*15b97f5cSMasahiro Yamada
216*15b97f5cSMasahiro Yamada        Args:
217*15b97f5cSMasahiro Yamada            prop_offset: Offset of property (e.g. from first_property_offset())
218*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
219*15b97f5cSMasahiro Yamada
220*15b97f5cSMasahiro Yamada        Returns:
221*15b97f5cSMasahiro Yamada            Property object, or None if not found
222*15b97f5cSMasahiro Yamada
223*15b97f5cSMasahiro Yamada        Raises:
224*15b97f5cSMasahiro Yamada            FdtException on error (e.g. invalid prop_offset or device
225*15b97f5cSMasahiro Yamada            tree format)
226*15b97f5cSMasahiro Yamada        """
227*15b97f5cSMasahiro Yamada        pdata = check_err_null(
228*15b97f5cSMasahiro Yamada                fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
229*15b97f5cSMasahiro Yamada        if isinstance(pdata, (int)):
230*15b97f5cSMasahiro Yamada            return pdata
231*15b97f5cSMasahiro Yamada        return Property(pdata[0], pdata[1])
232*15b97f5cSMasahiro Yamada
233*15b97f5cSMasahiro Yamada    def first_subnode(self, nodeoffset, quiet=()):
234*15b97f5cSMasahiro Yamada        """Find the first subnode of a parent node
235*15b97f5cSMasahiro Yamada
236*15b97f5cSMasahiro Yamada        Args:
237*15b97f5cSMasahiro Yamada            nodeoffset: Node offset of parent node
238*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
239*15b97f5cSMasahiro Yamada
240*15b97f5cSMasahiro Yamada        Returns:
241*15b97f5cSMasahiro Yamada            The offset of the first subnode, if any
242*15b97f5cSMasahiro Yamada
243*15b97f5cSMasahiro Yamada        Raises:
244*15b97f5cSMasahiro Yamada            FdtException if no subnode found or other error occurs
245*15b97f5cSMasahiro Yamada        """
246*15b97f5cSMasahiro Yamada        return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet)
247*15b97f5cSMasahiro Yamada
248*15b97f5cSMasahiro Yamada    def next_subnode(self, nodeoffset, quiet=()):
249*15b97f5cSMasahiro Yamada        """Find the next subnode
250*15b97f5cSMasahiro Yamada
251*15b97f5cSMasahiro Yamada        Args:
252*15b97f5cSMasahiro Yamada            nodeoffset: Node offset of previous subnode
253*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
254*15b97f5cSMasahiro Yamada
255*15b97f5cSMasahiro Yamada        Returns:
256*15b97f5cSMasahiro Yamada            The offset of the next subnode, if any
257*15b97f5cSMasahiro Yamada
258*15b97f5cSMasahiro Yamada        Raises:
259*15b97f5cSMasahiro Yamada            FdtException if no more subnode found or other error occurs
260*15b97f5cSMasahiro Yamada        """
261*15b97f5cSMasahiro Yamada        return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
262*15b97f5cSMasahiro Yamada
263*15b97f5cSMasahiro Yamada    def totalsize(self):
264*15b97f5cSMasahiro Yamada        """Return the total size of the device tree
265*15b97f5cSMasahiro Yamada
266*15b97f5cSMasahiro Yamada        Returns:
267*15b97f5cSMasahiro Yamada            Total tree size in bytes
268*15b97f5cSMasahiro Yamada        """
269*15b97f5cSMasahiro Yamada        return check_err(fdt_totalsize(self._fdt))
270*15b97f5cSMasahiro Yamada
271*15b97f5cSMasahiro Yamada    def off_dt_struct(self):
272*15b97f5cSMasahiro Yamada        """Return the start of the device tree struct area
273*15b97f5cSMasahiro Yamada
274*15b97f5cSMasahiro Yamada        Returns:
275*15b97f5cSMasahiro Yamada            Start offset of struct area
276*15b97f5cSMasahiro Yamada        """
277*15b97f5cSMasahiro Yamada        return check_err(fdt_off_dt_struct(self._fdt))
278*15b97f5cSMasahiro Yamada
279*15b97f5cSMasahiro Yamada    def pack(self, quiet=()):
280*15b97f5cSMasahiro Yamada        """Pack the device tree to remove unused space
281*15b97f5cSMasahiro Yamada
282*15b97f5cSMasahiro Yamada        This adjusts the tree in place.
283*15b97f5cSMasahiro Yamada
284*15b97f5cSMasahiro Yamada        Args:
285*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
286*15b97f5cSMasahiro Yamada
287*15b97f5cSMasahiro Yamada        Raises:
288*15b97f5cSMasahiro Yamada            FdtException if any error occurs
289*15b97f5cSMasahiro Yamada        """
290*15b97f5cSMasahiro Yamada        return check_err(fdt_pack(self._fdt), quiet)
291*15b97f5cSMasahiro Yamada
292*15b97f5cSMasahiro Yamada    def delprop(self, nodeoffset, prop_name):
293*15b97f5cSMasahiro Yamada        """Delete a property from a node
294*15b97f5cSMasahiro Yamada
295*15b97f5cSMasahiro Yamada        Args:
296*15b97f5cSMasahiro Yamada            nodeoffset: Node offset containing property to delete
297*15b97f5cSMasahiro Yamada            prop_name: Name of property to delete
298*15b97f5cSMasahiro Yamada
299*15b97f5cSMasahiro Yamada        Raises:
300*15b97f5cSMasahiro Yamada            FdtError if the property does not exist, or another error occurs
301*15b97f5cSMasahiro Yamada        """
302*15b97f5cSMasahiro Yamada        return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
303*15b97f5cSMasahiro Yamada
304*15b97f5cSMasahiro Yamada    def getprop(self, nodeoffset, prop_name, quiet=()):
305*15b97f5cSMasahiro Yamada        """Get a property from a node
306*15b97f5cSMasahiro Yamada
307*15b97f5cSMasahiro Yamada        Args:
308*15b97f5cSMasahiro Yamada            nodeoffset: Node offset containing property to get
309*15b97f5cSMasahiro Yamada            prop_name: Name of property to get
310*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
311*15b97f5cSMasahiro Yamada
312*15b97f5cSMasahiro Yamada        Returns:
313*15b97f5cSMasahiro Yamada            Value of property as a bytearray, or -ve error number
314*15b97f5cSMasahiro Yamada
315*15b97f5cSMasahiro Yamada        Raises:
316*15b97f5cSMasahiro Yamada            FdtError if any error occurs (e.g. the property is not found)
317*15b97f5cSMasahiro Yamada        """
318*15b97f5cSMasahiro Yamada        pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
319*15b97f5cSMasahiro Yamada                               quiet)
320*15b97f5cSMasahiro Yamada        if isinstance(pdata, (int)):
321*15b97f5cSMasahiro Yamada            return pdata
322*15b97f5cSMasahiro Yamada        return bytearray(pdata[0])
323*15b97f5cSMasahiro Yamada
324*15b97f5cSMasahiro Yamada    def get_phandle(self, nodeoffset):
325*15b97f5cSMasahiro Yamada        """Get the phandle of a node
326*15b97f5cSMasahiro Yamada
327*15b97f5cSMasahiro Yamada        Args:
328*15b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
329*15b97f5cSMasahiro Yamada
330*15b97f5cSMasahiro Yamada        Returns:
331*15b97f5cSMasahiro Yamada            phandle of node, or 0 if the node has no phandle or another error
332*15b97f5cSMasahiro Yamada            occurs
333*15b97f5cSMasahiro Yamada        """
334*15b97f5cSMasahiro Yamada        return fdt_get_phandle(self._fdt, nodeoffset)
335*15b97f5cSMasahiro Yamada
336*15b97f5cSMasahiro Yamada    def parent_offset(self, nodeoffset, quiet=()):
337*15b97f5cSMasahiro Yamada        """Get the offset of a node's parent
338*15b97f5cSMasahiro Yamada
339*15b97f5cSMasahiro Yamada        Args:
340*15b97f5cSMasahiro Yamada            nodeoffset: Node offset to check
341*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
342*15b97f5cSMasahiro Yamada
343*15b97f5cSMasahiro Yamada        Returns:
344*15b97f5cSMasahiro Yamada            The offset of the parent node, if any
345*15b97f5cSMasahiro Yamada
346*15b97f5cSMasahiro Yamada        Raises:
347*15b97f5cSMasahiro Yamada            FdtException if no parent found or other error occurs
348*15b97f5cSMasahiro Yamada        """
349*15b97f5cSMasahiro Yamada        return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
350*15b97f5cSMasahiro Yamada
351*15b97f5cSMasahiro Yamada    def node_offset_by_phandle(self, phandle, quiet=()):
352*15b97f5cSMasahiro Yamada        """Get the offset of a node with the given phandle
353*15b97f5cSMasahiro Yamada
354*15b97f5cSMasahiro Yamada        Args:
355*15b97f5cSMasahiro Yamada            phandle: Phandle to search for
356*15b97f5cSMasahiro Yamada            quiet: Errors to ignore (empty to raise on all errors)
357*15b97f5cSMasahiro Yamada
358*15b97f5cSMasahiro Yamada        Returns:
359*15b97f5cSMasahiro Yamada            The offset of node with that phandle, if any
360*15b97f5cSMasahiro Yamada
361*15b97f5cSMasahiro Yamada        Raises:
362*15b97f5cSMasahiro Yamada            FdtException if no node found or other error occurs
363*15b97f5cSMasahiro Yamada        """
364*15b97f5cSMasahiro Yamada        return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
365*15b97f5cSMasahiro Yamada
366*15b97f5cSMasahiro Yamadaclass Property:
367*15b97f5cSMasahiro Yamada    """Holds a device tree property name and value.
368*15b97f5cSMasahiro Yamada
369*15b97f5cSMasahiro Yamada    This holds a copy of a property taken from the device tree. It does not
370*15b97f5cSMasahiro Yamada    reference the device tree, so if anything changes in the device tree,
371*15b97f5cSMasahiro Yamada    a Property object will remain valid.
372*15b97f5cSMasahiro Yamada
373*15b97f5cSMasahiro Yamada    Properties:
374*15b97f5cSMasahiro Yamada        name: Property name
375*15b97f5cSMasahiro Yamada        value: Proper value as a bytearray
376*15b97f5cSMasahiro Yamada    """
377*15b97f5cSMasahiro Yamada    def __init__(self, name, value):
378*15b97f5cSMasahiro Yamada        self.name = name
379*15b97f5cSMasahiro Yamada        self.value = value
380*15b97f5cSMasahiro Yamada%}
381*15b97f5cSMasahiro Yamada
382*15b97f5cSMasahiro Yamada%rename(fdt_property) fdt_property_func;
383*15b97f5cSMasahiro Yamada
384*15b97f5cSMasahiro Yamadatypedef int fdt32_t;
385*15b97f5cSMasahiro Yamada
386*15b97f5cSMasahiro Yamada%include "libfdt/fdt.h"
387*15b97f5cSMasahiro Yamada
388*15b97f5cSMasahiro Yamada%include "typemaps.i"
389*15b97f5cSMasahiro Yamada
390*15b97f5cSMasahiro Yamada/* Most functions don't change the device tree, so use a const void * */
391*15b97f5cSMasahiro Yamada%typemap(in) (const void *)(const void *fdt) {
392*15b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
393*15b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
394*15b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
395*15b97f5cSMasahiro Yamada	}
396*15b97f5cSMasahiro Yamada	$1 = (void *)PyByteArray_AsString($input);
397*15b97f5cSMasahiro Yamada        fdt = $1;
398*15b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
399*15b97f5cSMasahiro Yamada}
400*15b97f5cSMasahiro Yamada
401*15b97f5cSMasahiro Yamada/* Some functions do change the device tree, so use void * */
402*15b97f5cSMasahiro Yamada%typemap(in) (void *)(const void *fdt) {
403*15b97f5cSMasahiro Yamada	if (!PyByteArray_Check($input)) {
404*15b97f5cSMasahiro Yamada		SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
405*15b97f5cSMasahiro Yamada			"', argument " "$argnum"" of type '" "$type""'");
406*15b97f5cSMasahiro Yamada	}
407*15b97f5cSMasahiro Yamada	$1 = PyByteArray_AsString($input);
408*15b97f5cSMasahiro Yamada        fdt = $1;
409*15b97f5cSMasahiro Yamada        fdt = fdt; /* avoid unused variable warning */
410*15b97f5cSMasahiro Yamada}
411*15b97f5cSMasahiro Yamada
412*15b97f5cSMasahiro Yamada%typemap(out) (struct fdt_property *) {
413*15b97f5cSMasahiro Yamada	PyObject *buff;
414*15b97f5cSMasahiro Yamada
415*15b97f5cSMasahiro Yamada	if ($1) {
416*15b97f5cSMasahiro Yamada		resultobj = PyString_FromString(
417*15b97f5cSMasahiro Yamada			fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
418*15b97f5cSMasahiro Yamada		buff = PyByteArray_FromStringAndSize(
419*15b97f5cSMasahiro Yamada			(const char *)($1 + 1), fdt32_to_cpu($1->len));
420*15b97f5cSMasahiro Yamada		resultobj = SWIG_Python_AppendOutput(resultobj, buff);
421*15b97f5cSMasahiro Yamada	}
422*15b97f5cSMasahiro Yamada}
423*15b97f5cSMasahiro Yamada
424*15b97f5cSMasahiro Yamada%apply int *OUTPUT { int *lenp };
425*15b97f5cSMasahiro Yamada
426*15b97f5cSMasahiro Yamada/* typemap used for fdt_getprop() */
427*15b97f5cSMasahiro Yamada%typemap(out) (const void *) {
428*15b97f5cSMasahiro Yamada	if (!$1)
429*15b97f5cSMasahiro Yamada		$result = Py_None;
430*15b97f5cSMasahiro Yamada	else
431*15b97f5cSMasahiro Yamada		$result = Py_BuildValue("s#", $1, *arg4);
432*15b97f5cSMasahiro Yamada}
433*15b97f5cSMasahiro Yamada
434*15b97f5cSMasahiro Yamada/* We have both struct fdt_property and a function fdt_property() */
435*15b97f5cSMasahiro Yamada%warnfilter(302) fdt_property;
436*15b97f5cSMasahiro Yamada
437*15b97f5cSMasahiro Yamada/* These are macros in the header so have to be redefined here */
438*15b97f5cSMasahiro Yamadaint fdt_magic(const void *fdt);
439*15b97f5cSMasahiro Yamadaint fdt_totalsize(const void *fdt);
440*15b97f5cSMasahiro Yamadaint fdt_off_dt_struct(const void *fdt);
441*15b97f5cSMasahiro Yamadaint fdt_off_dt_strings(const void *fdt);
442*15b97f5cSMasahiro Yamadaint fdt_off_mem_rsvmap(const void *fdt);
443*15b97f5cSMasahiro Yamadaint fdt_version(const void *fdt);
444*15b97f5cSMasahiro Yamadaint fdt_last_comp_version(const void *fdt);
445*15b97f5cSMasahiro Yamadaint fdt_boot_cpuid_phys(const void *fdt);
446*15b97f5cSMasahiro Yamadaint fdt_size_dt_strings(const void *fdt);
447*15b97f5cSMasahiro Yamadaint fdt_size_dt_struct(const void *fdt);
448*15b97f5cSMasahiro Yamada
449*15b97f5cSMasahiro Yamada%include <../libfdt/libfdt.h>
450