mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
binman: Add support for selecting firmware to use with split-elf
In some cases it is desired for SPL to start TF-A instead of U-Boot proper. Add support for a new property fit,firmware that picks a valid entry and prepends the remaining valid entries to the loadables list generated by the split-elf generator. Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
99e3a2cd4e
commit
f584d44c23
4 changed files with 205 additions and 13 deletions
|
@ -721,6 +721,12 @@ split-elf
|
|||
fit,data
|
||||
Generates a `data = <...>` property with the contents of the segment
|
||||
|
||||
fit,firmware
|
||||
Generates a `firmware = <...>` property. Provides a list of possible
|
||||
nodes to be used as the `firmware` property value. The first valid
|
||||
node is picked as the firmware. Any remaining valid nodes is
|
||||
prepended to the `loadable` property generated by `fit,loadables`
|
||||
|
||||
fit,loadables
|
||||
Generates a `loadable = <...>` property with a list of the generated
|
||||
nodes (including all nodes if this operation is used multiple times)
|
||||
|
@ -791,7 +797,7 @@ Here is an example showing ATF, TEE and a device tree all combined::
|
|||
@config-SEQ {
|
||||
description = "conf-NAME.dtb";
|
||||
fdt = "fdt-SEQ";
|
||||
firmware = "u-boot";
|
||||
fit,firmware = "atf-1", "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
};
|
||||
|
@ -846,15 +852,15 @@ is::
|
|||
configurations {
|
||||
default = "config-1";
|
||||
config-1 {
|
||||
loadables = "atf-1", "atf-2", "atf-3", "tee-1", "tee-2";
|
||||
loadables = "u-boot", "atf-2", "atf-3", "tee-1", "tee-2";
|
||||
description = "rk3399-firefly.dtb";
|
||||
fdt = "fdt-1";
|
||||
firmware = "u-boot";
|
||||
firmware = "atf-1";
|
||||
};
|
||||
};
|
||||
|
||||
U-Boot SPL can then load the firmware (U-Boot proper) and all the loadables
|
||||
(ATF and TEE), then proceed with the boot.
|
||||
U-Boot SPL can then load the firmware (ATF) and all the loadables (U-Boot
|
||||
proper, ATF and TEE), then proceed with the boot.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -187,6 +187,12 @@ class Entry_fit(Entry_section):
|
|||
fit,data
|
||||
Generates a `data = <...>` property with the contents of the segment
|
||||
|
||||
fit,firmware
|
||||
Generates a `firmware = <...>` property. Provides a list of possible
|
||||
nodes to be used as the `firmware` property value. The first valid
|
||||
node is picked as the firmware. Any remaining valid nodes is
|
||||
prepended to the `loadable` property generated by `fit,loadables`
|
||||
|
||||
fit,loadables
|
||||
Generates a `loadable = <...>` property with a list of the generated
|
||||
nodes (including all nodes if this operation is used multiple times)
|
||||
|
@ -257,7 +263,7 @@ class Entry_fit(Entry_section):
|
|||
@config-SEQ {
|
||||
description = "conf-NAME.dtb";
|
||||
fdt = "fdt-SEQ";
|
||||
firmware = "u-boot";
|
||||
fit,firmware = "atf-1", "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
};
|
||||
|
@ -312,15 +318,15 @@ class Entry_fit(Entry_section):
|
|||
configurations {
|
||||
default = "config-1";
|
||||
config-1 {
|
||||
loadables = "atf-1", "atf-2", "atf-3", "tee-1", "tee-2";
|
||||
loadables = "u-boot", "atf-2", "atf-3", "tee-1", "tee-2";
|
||||
description = "rk3399-firefly.dtb";
|
||||
fdt = "fdt-1";
|
||||
firmware = "u-boot";
|
||||
firmware = "atf-1";
|
||||
};
|
||||
};
|
||||
|
||||
U-Boot SPL can then load the firmware (U-Boot proper) and all the loadables
|
||||
(ATF and TEE), then proceed with the boot.
|
||||
U-Boot SPL can then load the firmware (ATF) and all the loadables (U-Boot
|
||||
proper, ATF and TEE), then proceed with the boot.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
"""
|
||||
|
@ -510,6 +516,42 @@ class Entry_fit(Entry_section):
|
|||
return
|
||||
fsw.property(pname, prop.bytes)
|
||||
|
||||
def _process_firmware_prop(node):
|
||||
"""Process optional fit,firmware property
|
||||
|
||||
Picks the first valid entry for use as the firmware, remaining valid
|
||||
entries is prepended to loadables
|
||||
|
||||
Args:
|
||||
node (Node): Generator node to process
|
||||
|
||||
Returns:
|
||||
firmware (str): Firmware or None
|
||||
result (list): List of remaining loadables
|
||||
"""
|
||||
val = fdt_util.GetStringList(node, 'fit,firmware')
|
||||
if val is None:
|
||||
return None, self._loadables
|
||||
valid_entries = list(self._loadables)
|
||||
for name, entry in self.GetEntries().items():
|
||||
missing = []
|
||||
entry.CheckMissing(missing)
|
||||
entry.CheckOptional(missing)
|
||||
if not missing:
|
||||
valid_entries.append(name)
|
||||
firmware = None
|
||||
result = []
|
||||
for name in val:
|
||||
if name in valid_entries:
|
||||
if not firmware:
|
||||
firmware = name
|
||||
elif name not in result:
|
||||
result.append(name)
|
||||
for name in self._loadables:
|
||||
if name != firmware and name not in result:
|
||||
result.append(name)
|
||||
return firmware, result
|
||||
|
||||
def _gen_fdt_nodes(base_node, node, depth, in_images):
|
||||
"""Generate FDT nodes
|
||||
|
||||
|
@ -520,20 +562,24 @@ class Entry_fit(Entry_section):
|
|||
first.
|
||||
|
||||
Args:
|
||||
node (None): Generator node to process
|
||||
node (Node): Generator node to process
|
||||
depth: Current node depth (0 is the base 'fit' node)
|
||||
in_images: True if this is inside the 'images' node, so that
|
||||
'data' properties should be generated
|
||||
"""
|
||||
if self._fdts:
|
||||
firmware, fit_loadables = _process_firmware_prop(node)
|
||||
# Generate nodes for each FDT
|
||||
for seq, fdt_fname in enumerate(self._fdts):
|
||||
node_name = node.name[1:].replace('SEQ', str(seq + 1))
|
||||
fname = tools.get_input_filename(fdt_fname + '.dtb')
|
||||
with fsw.add_node(node_name):
|
||||
for pname, prop in node.props.items():
|
||||
if pname == 'fit,loadables':
|
||||
val = '\0'.join(self._loadables) + '\0'
|
||||
if pname == 'fit,firmware':
|
||||
if firmware:
|
||||
fsw.property_string('firmware', firmware)
|
||||
elif pname == 'fit,loadables':
|
||||
val = '\0'.join(fit_loadables) + '\0'
|
||||
fsw.property('loadables', val.encode('utf-8'))
|
||||
elif pname == 'fit,operation':
|
||||
pass
|
||||
|
|
|
@ -6337,6 +6337,50 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
|
|||
}
|
||||
self.assertEqual(expected, props)
|
||||
|
||||
def testFitFirmwareLoadables(self):
|
||||
"""Test an image with an FIT that use fit,firmware"""
|
||||
if not elf.ELF_TOOLS:
|
||||
self.skipTest('Python elftools not available')
|
||||
entry_args = {
|
||||
'of-list': 'test-fdt1',
|
||||
'default-dt': 'test-fdt1',
|
||||
'atf-bl31-path': 'bl31.elf',
|
||||
'tee-os-path': 'missing.bin',
|
||||
}
|
||||
test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
|
||||
data = self._DoReadFileDtb(
|
||||
'276_fit_firmware_loadables.dts',
|
||||
entry_args=entry_args,
|
||||
extra_indirs=[test_subdir])[0]
|
||||
|
||||
dtb = fdt.Fdt.FromData(data)
|
||||
dtb.Scan()
|
||||
|
||||
node = dtb.GetNode('/configurations/conf-uboot-1')
|
||||
self.assertEqual('u-boot', node.props['firmware'].value)
|
||||
self.assertEqual(['atf-1', 'atf-2'],
|
||||
fdt_util.GetStringList(node, 'loadables'))
|
||||
|
||||
node = dtb.GetNode('/configurations/conf-atf-1')
|
||||
self.assertEqual('atf-1', node.props['firmware'].value)
|
||||
self.assertEqual(['u-boot', 'atf-2'],
|
||||
fdt_util.GetStringList(node, 'loadables'))
|
||||
|
||||
node = dtb.GetNode('/configurations/conf-missing-uboot-1')
|
||||
self.assertEqual('u-boot', node.props['firmware'].value)
|
||||
self.assertEqual(['atf-1', 'atf-2'],
|
||||
fdt_util.GetStringList(node, 'loadables'))
|
||||
|
||||
node = dtb.GetNode('/configurations/conf-missing-atf-1')
|
||||
self.assertEqual('atf-1', node.props['firmware'].value)
|
||||
self.assertEqual(['u-boot', 'atf-2'],
|
||||
fdt_util.GetStringList(node, 'loadables'))
|
||||
|
||||
node = dtb.GetNode('/configurations/conf-missing-tee-1')
|
||||
self.assertEqual('atf-1', node.props['firmware'].value)
|
||||
self.assertEqual(['u-boot', 'atf-2'],
|
||||
fdt_util.GetStringList(node, 'loadables'))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
96
tools/binman/test/276_fit_firmware_loadables.dts
Normal file
96
tools/binman/test/276_fit_firmware_loadables.dts
Normal file
|
@ -0,0 +1,96 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
fit {
|
||||
description = "test desc";
|
||||
#address-cells = <1>;
|
||||
fit,fdt-list = "of-list";
|
||||
|
||||
images {
|
||||
u-boot {
|
||||
description = "test u-boot";
|
||||
type = "standalone";
|
||||
arch = "arm64";
|
||||
os = "u-boot";
|
||||
compression = "none";
|
||||
load = <0x00000000>;
|
||||
entry = <0x00000000>;
|
||||
|
||||
u-boot-nodtb {
|
||||
};
|
||||
};
|
||||
tee {
|
||||
description = "test tee";
|
||||
type = "tee";
|
||||
arch = "arm64";
|
||||
os = "tee";
|
||||
compression = "none";
|
||||
load = <0x00200000>;
|
||||
|
||||
tee-os {
|
||||
optional;
|
||||
};
|
||||
};
|
||||
@atf-SEQ {
|
||||
fit,operation = "split-elf";
|
||||
description = "test tf-a";
|
||||
type = "firmware";
|
||||
arch = "arm64";
|
||||
os = "arm-trusted-firmware";
|
||||
compression = "none";
|
||||
fit,load;
|
||||
fit,entry;
|
||||
fit,data;
|
||||
|
||||
atf-bl31 {
|
||||
};
|
||||
};
|
||||
@fdt-SEQ {
|
||||
description = "test fdt";
|
||||
type = "flat_dt";
|
||||
compression = "none";
|
||||
};
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "@conf-uboot-DEFAULT-SEQ";
|
||||
@conf-uboot-SEQ {
|
||||
description = "uboot config";
|
||||
fdt = "fdt-SEQ";
|
||||
fit,firmware = "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
@conf-atf-SEQ {
|
||||
description = "atf config";
|
||||
fdt = "fdt-SEQ";
|
||||
fit,firmware = "atf-1", "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
@conf-missing-uboot-SEQ {
|
||||
description = "missing uboot config";
|
||||
fdt = "fdt-SEQ";
|
||||
fit,firmware = "missing-1", "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
@conf-missing-atf-SEQ {
|
||||
description = "missing atf config";
|
||||
fdt = "fdt-SEQ";
|
||||
fit,firmware = "missing-1", "atf-1", "u-boot";
|
||||
fit,loadables;
|
||||
};
|
||||
@conf-missing-tee-SEQ {
|
||||
description = "missing tee config";
|
||||
fdt = "fdt-SEQ";
|
||||
fit,firmware = "atf-1", "u-boot", "tee";
|
||||
fit,loadables;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
Loading…
Reference in a new issue