xref: /rk3399_rockchip-uboot/tools/dtoc/fdt.py (revision bc1dea3656e55d91f7a3c1339d53fc9def3bbf31)
1#!/usr/bin/python
2#
3# Copyright (C) 2016 Google, Inc
4# Written by Simon Glass <sjg@chromium.org>
5#
6# SPDX-License-Identifier:      GPL-2.0+
7#
8
9import struct
10import sys
11
12import fdt_util
13
14# This deals with a device tree, presenting it as an assortment of Node and
15# Prop objects, representing nodes and properties, respectively. This file
16# contains the base classes and defines the high-level API. Most of the
17# implementation is in the FdtFallback and FdtNormal subclasses. See
18# fdt_select.py for how to create an Fdt object.
19
20# A list of types we support
21(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4)
22
23def CheckErr(errnum, msg):
24    if errnum:
25        raise ValueError('Error %d: %s: %s' %
26            (errnum, libfdt.fdt_strerror(errnum), msg))
27
28class PropBase:
29    """A device tree property
30
31    Properties:
32        name: Property name (as per the device tree)
33        value: Property value as a string of bytes, or a list of strings of
34            bytes
35        type: Value type
36    """
37    def __init__(self, node, offset, name):
38        self._node = node
39        self._offset = offset
40        self.name = name
41        self.value = None
42
43    def BytesToValue(self, bytes):
44        """Converts a string of bytes into a type and value
45
46        Args:
47            A string containing bytes
48
49        Return:
50            A tuple:
51                Type of data
52                Data, either a single element or a list of elements. Each element
53                is one of:
54                    TYPE_STRING: string value from the property
55                    TYPE_INT: a byte-swapped integer stored as a 4-byte string
56                    TYPE_BYTE: a byte stored as a single-byte string
57        """
58        size = len(bytes)
59        strings = bytes.split('\0')
60        is_string = True
61        count = len(strings) - 1
62        if count > 0 and not strings[-1]:
63            for string in strings[:-1]:
64                if not string:
65                    is_string = False
66                    break
67                for ch in string:
68                    if ch < ' ' or ch > '~':
69                        is_string = False
70                        break
71        else:
72            is_string = False
73        if is_string:
74            if count == 1:
75                return TYPE_STRING, strings[0]
76            else:
77                return TYPE_STRING, strings[:-1]
78        if size % 4:
79            if size == 1:
80                return TYPE_BYTE, bytes[0]
81            else:
82                return TYPE_BYTE, list(bytes)
83        val = []
84        for i in range(0, size, 4):
85            val.append(bytes[i:i + 4])
86        if size == 4:
87            return TYPE_INT, val[0]
88        else:
89            return TYPE_INT, val
90
91    def GetEmpty(self, type):
92        """Get an empty / zero value of the given type
93
94        Returns:
95            A single value of the given type
96        """
97        if type == TYPE_BYTE:
98            return chr(0)
99        elif type == TYPE_INT:
100            return struct.pack('<I', 0);
101        elif type == TYPE_STRING:
102            return ''
103        else:
104            return True
105
106class NodeBase:
107    """A device tree node
108
109    Properties:
110        offset: Integer offset in the device tree
111        name: Device tree node tname
112        path: Full path to node, along with the node name itself
113        _fdt: Device tree object
114        subnodes: A list of subnodes for this node, each a Node object
115        props: A dict of properties for this node, each a Prop object.
116            Keyed by property name
117    """
118    def __init__(self, fdt, offset, name, path):
119        self._fdt = fdt
120        self._offset = offset
121        self.name = name
122        self.path = path
123        self.subnodes = []
124        self.props = {}
125
126class Fdt:
127    """Provides simple access to a flat device tree blob.
128
129    Properties:
130      fname: Filename of fdt
131      _root: Root of device tree (a Node object)
132    """
133    def __init__(self, fname):
134        self._fname = fname
135