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