123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- /*
- * pylibfdt - Flat Device Tree manipulation in Python
- * Copyright (C) 2017 Google, Inc.
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
- */
- %module libfdt
- %include <stdint.i>
- %{
- #define SWIG_FILE_WITH_INIT
- #include "libfdt.h"
- %}
- %pythoncode %{
- import struct
- # Error codes, corresponding to FDT_ERR_... in libfdt.h
- (NOTFOUND,
- EXISTS,
- NOSPACE,
- BADOFFSET,
- BADPATH,
- BADPHANDLE,
- BADSTATE,
- TRUNCATED,
- BADMAGIC,
- BADVERSION,
- BADSTRUCTURE,
- BADLAYOUT,
- INTERNAL,
- BADNCELLS,
- BADVALUE,
- BADOVERLAY,
- NOPHANDLES) = QUIET_ALL = range(1, 18)
- # QUIET_ALL can be passed as the 'quiet' parameter to avoid exceptions
- # altogether. All # functions passed this value will return an error instead
- # of raising an exception.
- # Pass this as the 'quiet' parameter to return -ENOTFOUND on NOTFOUND errors,
- # instead of raising an exception.
- QUIET_NOTFOUND = (NOTFOUND,)
- class FdtException(Exception):
- """An exception caused by an error such as one of the codes above"""
- def __init__(self, err):
- self.err = err
- def __str__(self):
- return 'pylibfdt error %d: %s' % (self.err, fdt_strerror(self.err))
- def strerror(fdt_err):
- """Get the string for an error number
- Args:
- fdt_err: Error number (-ve)
- Returns:
- String containing the associated error
- """
- return fdt_strerror(fdt_err)
- def check_err(val, quiet=()):
- """Raise an error if the return value is -ve
- This is used to check for errors returned by libfdt C functions.
- Args:
- val: Return value from a libfdt function
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- val if val >= 0
- Raises
- FdtException if val < 0
- """
- if val < 0:
- if -val not in quiet:
- raise FdtException(val)
- return val
- def check_err_null(val, quiet=()):
- """Raise an error if the return value is NULL
- This is used to check for a NULL return value from certain libfdt C
- functions
- Args:
- val: Return value from a libfdt function
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- val if val is a list, None if not
- Raises
- FdtException if val indicates an error was reported and the error
- is not in @quiet.
- """
- # Normally a list is returned which contains the data and its length.
- # If we get just an integer error code, it means the function failed.
- if not isinstance(val, list):
- if -val not in quiet:
- raise FdtException(val)
- return val
- class Fdt:
- """Device tree class, supporting all operations
- The Fdt object is created is created from a device tree binary file,
- e.g. with something like:
- fdt = Fdt(open("filename.dtb").read())
- Operations can then be performed using the methods in this class. Each
- method xxx(args...) corresponds to a libfdt function fdt_xxx(fdt, args...).
- All methods raise an FdtException if an error occurs. To avoid this
- behaviour a 'quiet' parameter is provided for some functions. This
- defaults to empty, but you can pass a list of errors that you expect.
- If one of these errors occurs, the function will return an error number
- (e.g. -NOTFOUND).
- """
- def __init__(self, data):
- self._fdt = bytearray(data)
- check_err(fdt_check_header(self._fdt));
- def subnode_offset(self, parentoffset, name, quiet=()):
- """Get the offset of a named subnode
- Args:
- parentoffset: Offset of the parent node to check
- name: Name of the required subnode, e.g. 'subnode@1'
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- The node offset of the found node, if any
- Raises
- FdtException if there is no node with that name, or other error
- """
- return check_err(fdt_subnode_offset(self._fdt, parentoffset, name),
- quiet)
- def path_offset(self, path, quiet=()):
- """Get the offset for a given path
- Args:
- path: Path to the required node, e.g. '/node@3/subnode@1'
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- Node offset
- Raises
- FdtException if the path is not valid or not found
- """
- return check_err(fdt_path_offset(self._fdt, path), quiet)
- def first_property_offset(self, nodeoffset, quiet=()):
- """Get the offset of the first property in a node offset
- Args:
- nodeoffset: Offset to the node to check
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- Offset of the first property
- Raises
- FdtException if the associated node has no properties, or some
- other error occurred
- """
- return check_err(fdt_first_property_offset(self._fdt, nodeoffset),
- quiet)
- def next_property_offset(self, prop_offset, quiet=()):
- """Get the next property in a node
- Args:
- prop_offset: Offset of the previous property
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- Offset of the next property
- Raises:
- FdtException if the associated node has no more properties, or
- some other error occurred
- """
- return check_err(fdt_next_property_offset(self._fdt, prop_offset),
- quiet)
- def get_name(self, nodeoffset):
- """Get the name of a node
- Args:
- nodeoffset: Offset of node to check
- Returns:
- Node name
- Raises:
- FdtException on error (e.g. nodeoffset is invalid)
- """
- return check_err_null(fdt_get_name(self._fdt, nodeoffset))[0]
- def get_property_by_offset(self, prop_offset, quiet=()):
- """Obtains a property that can be examined
- Args:
- prop_offset: Offset of property (e.g. from first_property_offset())
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- Property object, or None if not found
- Raises:
- FdtException on error (e.g. invalid prop_offset or device
- tree format)
- """
- pdata = check_err_null(
- fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
- if isinstance(pdata, (int)):
- return pdata
- return Property(pdata[0], pdata[1])
- def first_subnode(self, nodeoffset, quiet=()):
- """Find the first subnode of a parent node
- Args:
- nodeoffset: Node offset of parent node
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- The offset of the first subnode, if any
- Raises:
- FdtException if no subnode found or other error occurs
- """
- return check_err(fdt_first_subnode(self._fdt, nodeoffset), quiet)
- def next_subnode(self, nodeoffset, quiet=()):
- """Find the next subnode
- Args:
- nodeoffset: Node offset of previous subnode
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- The offset of the next subnode, if any
- Raises:
- FdtException if no more subnode found or other error occurs
- """
- return check_err(fdt_next_subnode(self._fdt, nodeoffset), quiet)
- def totalsize(self):
- """Return the total size of the device tree
- Returns:
- Total tree size in bytes
- """
- return check_err(fdt_totalsize(self._fdt))
- def off_dt_struct(self):
- """Return the start of the device tree struct area
- Returns:
- Start offset of struct area
- """
- return check_err(fdt_off_dt_struct(self._fdt))
- def pack(self, quiet=()):
- """Pack the device tree to remove unused space
- This adjusts the tree in place.
- Args:
- quiet: Errors to ignore (empty to raise on all errors)
- Raises:
- FdtException if any error occurs
- """
- return check_err(fdt_pack(self._fdt), quiet)
- def delprop(self, nodeoffset, prop_name):
- """Delete a property from a node
- Args:
- nodeoffset: Node offset containing property to delete
- prop_name: Name of property to delete
- Raises:
- FdtError if the property does not exist, or another error occurs
- """
- return check_err(fdt_delprop(self._fdt, nodeoffset, prop_name))
- def getprop(self, nodeoffset, prop_name, quiet=()):
- """Get a property from a node
- Args:
- nodeoffset: Node offset containing property to get
- prop_name: Name of property to get
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- Value of property as a bytearray, or -ve error number
- Raises:
- FdtError if any error occurs (e.g. the property is not found)
- """
- pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
- quiet)
- if isinstance(pdata, (int)):
- return pdata
- return bytearray(pdata[0])
- def get_phandle(self, nodeoffset):
- """Get the phandle of a node
- Args:
- nodeoffset: Node offset to check
- Returns:
- phandle of node, or 0 if the node has no phandle or another error
- occurs
- """
- return fdt_get_phandle(self._fdt, nodeoffset)
- def parent_offset(self, nodeoffset, quiet=()):
- """Get the offset of a node's parent
- Args:
- nodeoffset: Node offset to check
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- The offset of the parent node, if any
- Raises:
- FdtException if no parent found or other error occurs
- """
- return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet)
- def node_offset_by_phandle(self, phandle, quiet=()):
- """Get the offset of a node with the given phandle
- Args:
- phandle: Phandle to search for
- quiet: Errors to ignore (empty to raise on all errors)
- Returns:
- The offset of node with that phandle, if any
- Raises:
- FdtException if no node found or other error occurs
- """
- return check_err(fdt_node_offset_by_phandle(self._fdt, phandle), quiet)
- class Property:
- """Holds a device tree property name and value.
- This holds a copy of a property taken from the device tree. It does not
- reference the device tree, so if anything changes in the device tree,
- a Property object will remain valid.
- Properties:
- name: Property name
- value: Proper value as a bytearray
- """
- def __init__(self, name, value):
- self.name = name
- self.value = value
- %}
- %rename(fdt_property) fdt_property_func;
- typedef int fdt32_t;
- %include "libfdt/fdt.h"
- %include "typemaps.i"
- /* Most functions don't change the device tree, so use a const void * */
- %typemap(in) (const void *)(const void *fdt) {
- if (!PyByteArray_Check($input)) {
- SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
- "', argument " "$argnum"" of type '" "$type""'");
- }
- $1 = (void *)PyByteArray_AsString($input);
- fdt = $1;
- fdt = fdt; /* avoid unused variable warning */
- }
- /* Some functions do change the device tree, so use void * */
- %typemap(in) (void *)(const void *fdt) {
- if (!PyByteArray_Check($input)) {
- SWIG_exception_fail(SWIG_TypeError, "in method '" "$symname"
- "', argument " "$argnum"" of type '" "$type""'");
- }
- $1 = PyByteArray_AsString($input);
- fdt = $1;
- fdt = fdt; /* avoid unused variable warning */
- }
- %typemap(out) (struct fdt_property *) {
- PyObject *buff;
- if ($1) {
- resultobj = PyString_FromString(
- fdt_string(fdt1, fdt32_to_cpu($1->nameoff)));
- buff = PyByteArray_FromStringAndSize(
- (const char *)($1 + 1), fdt32_to_cpu($1->len));
- resultobj = SWIG_Python_AppendOutput(resultobj, buff);
- }
- }
- %apply int *OUTPUT { int *lenp };
- /* typemap used for fdt_getprop() */
- %typemap(out) (const void *) {
- if (!$1)
- $result = Py_None;
- else
- $result = Py_BuildValue("s#", $1, *arg4);
- }
- /* We have both struct fdt_property and a function fdt_property() */
- %warnfilter(302) fdt_property;
- /* These are macros in the header so have to be redefined here */
- int fdt_magic(const void *fdt);
- int fdt_totalsize(const void *fdt);
- int fdt_off_dt_struct(const void *fdt);
- int fdt_off_dt_strings(const void *fdt);
- int fdt_off_mem_rsvmap(const void *fdt);
- int fdt_version(const void *fdt);
- int fdt_last_comp_version(const void *fdt);
- int fdt_boot_cpuid_phys(const void *fdt);
- int fdt_size_dt_strings(const void *fdt);
- int fdt_size_dt_struct(const void *fdt);
- %include <../libfdt/libfdt.h>
|