mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-15 01:17:39 +00:00
3af8e49cef
It is sometimes useful to have an area of the image which is all zeroes, or all 0xff. This can often be achieved by padding the size of an an existing entry and setting the pad byte for an entry or image. But it is useful to have an explicit means of adding blocks of repeating data to the image. Add a 'fill' entry type to handle this. Signed-off-by: Simon Glass <sjg@chromium.org>
193 lines
5.5 KiB
Python
193 lines
5.5 KiB
Python
#!/usr/bin/python
|
|
# SPDX-License-Identifier: GPL-2.0+
|
|
#
|
|
# Copyright (C) 2016 Google, Inc
|
|
# Written by Simon Glass <sjg@chromium.org>
|
|
#
|
|
|
|
# Utility functions for reading from a device tree. Once the upstream pylibfdt
|
|
# implementation advances far enough, we should be able to drop these.
|
|
|
|
import os
|
|
import struct
|
|
import sys
|
|
import tempfile
|
|
|
|
import command
|
|
import tools
|
|
|
|
VERSION3 = sys.version_info > (3, 0)
|
|
|
|
def get_plain_bytes(val):
|
|
"""Handle Python 3 strings"""
|
|
if isinstance(val, bytes):
|
|
val = val.decode('utf-8')
|
|
return val.encode('raw_unicode_escape')
|
|
|
|
def fdt32_to_cpu(val):
|
|
"""Convert a device tree cell to an integer
|
|
|
|
Args:
|
|
Value to convert (4-character string representing the cell value)
|
|
|
|
Return:
|
|
A native-endian integer value
|
|
"""
|
|
if VERSION3:
|
|
# This code is not reached in Python 2
|
|
val = get_plain_bytes(val) # pragma: no cover
|
|
return struct.unpack('>I', val)[0]
|
|
|
|
def fdt_cells_to_cpu(val, cells):
|
|
"""Convert one or two cells to a long integer
|
|
|
|
Args:
|
|
Value to convert (array of one or more 4-character strings)
|
|
|
|
Return:
|
|
A native-endian long value
|
|
"""
|
|
if not cells:
|
|
return 0
|
|
out = long(fdt32_to_cpu(val[0]))
|
|
if cells == 2:
|
|
out = out << 32 | fdt32_to_cpu(val[1])
|
|
return out
|
|
|
|
def EnsureCompiled(fname, capture_stderr=False):
|
|
"""Compile an fdt .dts source file into a .dtb binary blob if needed.
|
|
|
|
Args:
|
|
fname: Filename (if .dts it will be compiled). It not it will be
|
|
left alone
|
|
|
|
Returns:
|
|
Filename of resulting .dtb file
|
|
"""
|
|
_, ext = os.path.splitext(fname)
|
|
if ext != '.dts':
|
|
return fname
|
|
|
|
dts_input = tools.GetOutputFilename('source.dts')
|
|
dtb_output = tools.GetOutputFilename('source.dtb')
|
|
|
|
search_paths = [os.path.join(os.getcwd(), 'include')]
|
|
root, _ = os.path.splitext(fname)
|
|
args = ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
|
|
args += ['-Ulinux']
|
|
for path in search_paths:
|
|
args.extend(['-I', path])
|
|
args += ['-o', dts_input, fname]
|
|
command.Run('cc', *args)
|
|
|
|
# If we don't have a directory, put it in the tools tempdir
|
|
search_list = []
|
|
for path in search_paths:
|
|
search_list.extend(['-i', path])
|
|
args = ['-I', 'dts', '-o', dtb_output, '-O', 'dtb',
|
|
'-W', 'no-unit_address_vs_reg']
|
|
args.extend(search_list)
|
|
args.append(dts_input)
|
|
dtc = os.environ.get('DTC') or 'dtc'
|
|
command.Run(dtc, *args, capture_stderr=capture_stderr)
|
|
return dtb_output
|
|
|
|
def GetInt(node, propname, default=None):
|
|
"""Get an integer from a property
|
|
|
|
Args:
|
|
node: Node object to read from
|
|
propname: property name to read
|
|
default: Default value to use if the node/property do not exist
|
|
|
|
Returns:
|
|
Integer value read, or default if none
|
|
"""
|
|
prop = node.props.get(propname)
|
|
if not prop:
|
|
return default
|
|
if isinstance(prop.value, list):
|
|
raise ValueError("Node '%s' property '%s' has list value: expecting "
|
|
"a single integer" % (node.name, propname))
|
|
value = fdt32_to_cpu(prop.value)
|
|
return value
|
|
|
|
def GetString(node, propname, default=None):
|
|
"""Get a string from a property
|
|
|
|
Args:
|
|
node: Node object to read from
|
|
propname: property name to read
|
|
default: Default value to use if the node/property do not exist
|
|
|
|
Returns:
|
|
String value read, or default if none
|
|
"""
|
|
prop = node.props.get(propname)
|
|
if not prop:
|
|
return default
|
|
value = prop.value
|
|
if isinstance(value, list):
|
|
raise ValueError("Node '%s' property '%s' has list value: expecting "
|
|
"a single string" % (node.name, propname))
|
|
return value
|
|
|
|
def GetBool(node, propname, default=False):
|
|
"""Get an boolean from a property
|
|
|
|
Args:
|
|
node: Node object to read from
|
|
propname: property name to read
|
|
default: Default value to use if the node/property do not exist
|
|
|
|
Returns:
|
|
Boolean value read, or default if none (if you set this to True the
|
|
function will always return True)
|
|
"""
|
|
if propname in node.props:
|
|
return True
|
|
return default
|
|
|
|
def GetByte(node, propname, default=None):
|
|
"""Get an byte from a property
|
|
|
|
Args:
|
|
node: Node object to read from
|
|
propname: property name to read
|
|
default: Default value to use if the node/property do not exist
|
|
|
|
Returns:
|
|
Byte value read, or default if none
|
|
"""
|
|
prop = node.props.get(propname)
|
|
if not prop:
|
|
return default
|
|
value = prop.value
|
|
if isinstance(value, list):
|
|
raise ValueError("Node '%s' property '%s' has list value: expecting "
|
|
"a single byte" % (node.name, propname))
|
|
if len(value) != 1:
|
|
raise ValueError("Node '%s' property '%s' has length %d, expecting %d" %
|
|
(node.name, propname, len(value), 1))
|
|
return ord(value[0])
|
|
|
|
def GetDatatype(node, propname, datatype):
|
|
"""Get a value of a given type from a property
|
|
|
|
Args:
|
|
node: Node object to read from
|
|
propname: property name to read
|
|
datatype: Type to read (str or int)
|
|
|
|
Returns:
|
|
value read, or None if none
|
|
|
|
Raises:
|
|
ValueError if datatype is not str or int
|
|
"""
|
|
if datatype == str:
|
|
return GetString(node, propname)
|
|
elif datatype == int:
|
|
return GetInt(node, propname)
|
|
raise ValueError("fdt_util internal error: Unknown data type '%s'" %
|
|
datatype)
|