Skip to content
Snippets Groups Projects
fdt_fallback.py 5.51 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/python
    #
    # Copyright (C) 2016 Google, Inc
    # Written by Simon Glass <sjg@chromium.org>
    #
    # SPDX-License-Identifier:      GPL-2.0+
    #
    
    import command
    
    import fdt
    from fdt import Fdt, NodeBase, PropBase
    
    import fdt_util
    import sys
    
    # This deals with a device tree, presenting it as a list of Node and Prop
    # objects, representing nodes and properties, respectively.
    #
    # This implementation uses the fdtget tool to access the device tree, so it
    # is not very efficient for larger trees. The tool is called once for each
    # node and property in the tree.
    
    
    class Prop(PropBase):
    
        """A device tree property
    
        Properties:
            name: Property name (as per the device tree)
            value: Property value as a string of bytes, or a list of strings of
                bytes
            type: Value type
        """
    
        def __init__(self, node, name, byte_list_str):
            PropBase.__init__(self, node, 0, name)
    
            if not byte_list_str.strip():
    
                self.type = fdt.TYPE_BOOL
    
            self.bytes = [chr(int(byte, 16))
                          for byte in byte_list_str.strip().split(' ')]
    
            self.type, self.value = self.BytesToValue(''.join(self.bytes))
    
    class Node(NodeBase):
    
        """A device tree node
    
        Properties:
            name: Device tree node tname
            path: Full path to node, along with the node name itself
            _fdt: Device tree object
            subnodes: A list of subnodes for this node, each a Node object
            props: A dict of properties for this node, each a Prop object.
                Keyed by property name
        """
    
        def __init__(self, fdt, offset, name, path):
            NodeBase.__init__(self, fdt, offset, name, path)
    
    
        def Scan(self):
            """Scan a node's properties and subnodes
    
            This fills in the props and subnodes properties, recursively
            searching into subnodes so that the entire tree is built.
            """
            for name, byte_list_str in self._fdt.GetProps(self.path).iteritems():
    
                prop = Prop(self, name, byte_list_str)
    
                self.props[name] = prop
    
            for name in self._fdt.GetSubNodes(self.path):
                sep = '' if self.path[-1] == '/' else '/'
                path = self.path + sep + name
    
                node = Node(self._fdt, 0, name, path)
    
                self.subnodes.append(node)
    
                node.Scan()
    
    
        def DeleteProp(self, prop_name):
            """Delete a property of a node
    
            The property is deleted using fdtput.
    
            Args:
                prop_name: Name of the property to delete
            Raises:
                CommandError if the property does not exist
            """
            args = [self._fdt._fname, '-d', self.path, prop_name]
            command.Output('fdtput', *args)
            del self.props[prop_name]
    
    class FdtFallback(Fdt):
        """Provides simple access to a flat device tree blob using fdtget/fdtput
    
            See superclass
    
        """
    
        def __init__(self, fname):
    
            Fdt.__init__(self, fname)
    
            if self._fname:
                self._fname = fdt_util.EnsureCompiled(self._fname)
    
    
        def GetSubNodes(self, node):
            """Returns a list of sub-nodes of a given node
    
            Args:
                node: Node name to return children from
    
            Returns:
                List of children in the node (each a string node name)
    
            Raises:
                CmdError: if the node does not exist.
            """
    
            out = command.Output('fdtget', self._fname, '-l', node)
    
            return out.strip().splitlines()
    
    
        def GetProps(self, node):
    
            """Get all properties from a node
    
            Args:
                node: full path to node name to look in
    
            Returns:
                A dictionary containing all the properties, indexed by node name.
                The entries are simply strings - no decoding of lists or numbers
                is done.
    
            Raises:
                CmdError: if the node does not exist.
            """
    
            out = command.Output('fdtget', self._fname, node, '-p')
    
            props = out.strip().splitlines()
            props_dict = {}
            for prop in props:
                name = prop
                props_dict[prop] = self.GetProp(node, name)
            return props_dict
    
        def GetProp(self, node, prop, default=None, typespec=None):
            """Get a property from a device tree.
    
            This looks up the given node and property, and returns the value as a
            string,
    
            If the node or property does not exist, this will return the default
            value.
    
            Args:
                node: Full path to node to look up.
                prop: Property name to look up.
                default: Default value to return if nothing is present in the fdt,
                    or None to raise in this case. This will be converted to a
                    string.
                typespec: Type character to use (None for default, 's' for string)
    
            Returns:
                string containing the property value.
    
            Raises:
                CmdError: if the property does not exist and no default is provided.
            """
    
            args = [self._fname, node, prop, '-t', 'bx']
    
            if default is not None:
              args += ['-d', str(default)]
            if typespec is not None:
              args += ['-t%s' % typespec]
            out = command.Output('fdtget', *args)
            return out.strip()
    
    
        @classmethod
        def Node(self, fdt, offset, name, path):
            """Create a new node
    
            This is used by Fdt.Scan() to create a new node using the correct
            class.
    
            Args:
                fdt: Fdt object
                offset: Offset of node
                name: Node name
                path: Full path to node
            """
            node = Node(fdt, offset, name, path)
            return node