mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
binman enhancements:
- Dropping some test Elf files and building them from source instead - Refactoring of x86 16-bit entries - Support for SPL symbols within sections - Handle the 'notes' sections and hidden symbols in recent binutils - Improved error reporting with a tool fails libfdt and documentation fixes vboot required-key test driver model power-domain controls patman Message-Id enhancement -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAl2l20YACgkQfxc6PpAI reZQQQgA0zxySnZR6IuTr+MXJP019SjU0T/rj2Ob77ODhLTtLtE3aFYgBIsyyOyr /NZ6V7wPhCfGGBGWdPzYdOUIkG5L4O+1zrwWGgVJCAAaCaDlJVIXmljJ667SE9ps 9jfJW/nkzgsa/cOweOUJF3vBUKnDN1pv9aTXwAXttzv/OqaZ1AaUObnmeZ9fzr65 mXjR7/eLYx26KQ8IEo8hhgdFhN/d/aUtSCYPWASqtcI9TLg8A5gmtNxy83+w8gzC kFIr7c0QjZ3EQHLyD4/MAcGvhZZMBPbV6dyIO19hUS80S1l1yMTd72iTYuvG8bAt 5TzlQCSqvGryF6TRxVn8GPr2/T0v/A== =Oo/D -----END PGP SIGNATURE----- Merge tag 'dm-pull-15oct19' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm binman enhancements: - Dropping some test Elf files and building them from source instead - Refactoring of x86 16-bit entries - Support for SPL symbols within sections - Handle the 'notes' sections and hidden symbols in recent binutils - Improved error reporting with a tool fails libfdt and documentation fixes vboot required-key test driver model power-domain controls patman Message-Id enhancement
This commit is contained in:
commit
c83b1bb923
98 changed files with 1300 additions and 285 deletions
10
Makefile
10
Makefile
|
@ -1458,14 +1458,18 @@ quiet_cmd_ldr = LD $@
|
|||
cmd_ldr = $(LD) $(LDFLAGS_$(@F)) \
|
||||
$(filter-out FORCE,$^) -o $@
|
||||
|
||||
u-boot.rom: u-boot-x86-16bit.bin u-boot.bin \
|
||||
u-boot.rom: u-boot-x86-start16.bin u-boot-x86-reset16.bin u-boot.bin \
|
||||
$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
|
||||
$(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin) \
|
||||
$(if $(CONFIG_HAVE_REFCODE),refcode.bin) FORCE
|
||||
$(call if_changed,binman)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec
|
||||
u-boot-x86-16bit.bin: u-boot FORCE
|
||||
OBJCOPYFLAGS_u-boot-x86-start16.bin := -O binary -j .start16
|
||||
u-boot-x86-start16.bin: u-boot FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-reset16.bin := -O binary -j .resetvec
|
||||
u-boot-x86-reset16.bin: u-boot FORCE
|
||||
$(call if_changed,objcopy)
|
||||
endif
|
||||
|
||||
|
|
|
@ -393,19 +393,21 @@
|
|||
mbox-names = "other", "test";
|
||||
};
|
||||
|
||||
cpu-test1 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
cpus {
|
||||
cpu-test1 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
cpu-test2 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
cpu-test2 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
cpu-test3 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
cpu-test3 {
|
||||
compatible = "sandbox,cpu_sandbox";
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
};
|
||||
|
||||
i2s: i2s {
|
||||
|
|
|
@ -26,6 +26,8 @@ int cleanup_before_linux(void);
|
|||
/* drivers/video/sandbox_sdl.c */
|
||||
int sandbox_lcd_sdl_early_init(void);
|
||||
|
||||
struct udevice;
|
||||
|
||||
/**
|
||||
* pci_map_physmem() - map a PCI device into memory
|
||||
*
|
||||
|
|
|
@ -120,14 +120,23 @@
|
|||
x86-start16-tpl {
|
||||
offset = <CONFIG_SYS_X86_START16>;
|
||||
};
|
||||
x86-reset16-tpl {
|
||||
offset = <CONFIG_RESET_VEC_LOC>;
|
||||
};
|
||||
#elif defined(CONFIG_SPL)
|
||||
x86-start16-spl {
|
||||
offset = <CONFIG_SYS_X86_START16>;
|
||||
};
|
||||
x86-reset16-spl {
|
||||
offset = <CONFIG_RESET_VEC_LOC>;
|
||||
};
|
||||
#else
|
||||
x86-start16 {
|
||||
offset = <CONFIG_SYS_X86_START16>;
|
||||
};
|
||||
x86-reset16 {
|
||||
offset = <CONFIG_RESET_VEC_LOC>;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
|
14
cmd/aes.c
14
cmd/aes.c
|
@ -11,6 +11,7 @@
|
|||
#include <malloc.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <mapmem.h>
|
||||
|
||||
/**
|
||||
* do_aes() - Handle the "aes" command-line command
|
||||
|
@ -46,10 +47,10 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
dst_addr = simple_strtoul(argv[5], NULL, 16);
|
||||
len = simple_strtoul(argv[6], NULL, 16);
|
||||
|
||||
key_ptr = (uint8_t *)key_addr;
|
||||
iv_ptr = (uint8_t *)iv_addr;
|
||||
src_ptr = (uint8_t *)src_addr;
|
||||
dst_ptr = (uint8_t *)dst_addr;
|
||||
key_ptr = (uint8_t *)map_sysmem(key_addr, 128 / 8);
|
||||
iv_ptr = (uint8_t *)map_sysmem(iv_addr, 128 / 8);
|
||||
src_ptr = (uint8_t *)map_sysmem(src_addr, len);
|
||||
dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
|
||||
|
||||
/* First we expand the key. */
|
||||
aes_expand_key(key_ptr, key_exp);
|
||||
|
@ -64,6 +65,11 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
aes_cbc_decrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr,
|
||||
aes_blocks);
|
||||
|
||||
unmap_sysmem(key_ptr);
|
||||
unmap_sysmem(iv_ptr);
|
||||
unmap_sysmem(src_ptr);
|
||||
unmap_sysmem(dst_ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ CONFIG_CMD_QFW=y
|
|||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_CMD_AES=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_TPM_TEST=y
|
||||
CONFIG_CMD_BTRFS=y
|
||||
|
|
|
@ -67,6 +67,7 @@ CONFIG_CMD_QFW=y
|
|||
CONFIG_CMD_BOOTSTAGE=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
CONFIG_CMD_AES=y
|
||||
CONFIG_CMD_TPM=y
|
||||
CONFIG_CMD_TPM_TEST=y
|
||||
CONFIG_CMD_BTRFS=y
|
||||
|
|
|
@ -650,7 +650,7 @@ Prepare patches and send them to the mailing lists
|
|||
--------------------------------------------------
|
||||
|
||||
You can use 'tools/patman/patman' to prepare, check and send patches for
|
||||
your work. See the README for details.
|
||||
your work. See tools/patman/README for details.
|
||||
|
||||
A little note about SPI uclass features
|
||||
---------------------------------------
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <dm/uclass.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/util.h>
|
||||
#include <power-domain.h>
|
||||
|
||||
int device_chld_unbind(struct udevice *dev, struct driver *drv)
|
||||
{
|
||||
|
@ -192,6 +193,10 @@ int device_remove(struct udevice *dev, uint flags)
|
|||
}
|
||||
}
|
||||
|
||||
if (!(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF) &&
|
||||
(dev != gd->cur_serial_dev))
|
||||
dev_power_domain_off(dev);
|
||||
|
||||
if (flags_remove(flags, drv->flags)) {
|
||||
device_free(dev);
|
||||
|
||||
|
|
|
@ -82,6 +82,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
|
|||
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
|
||||
if (uc->uc_drv->name && ofnode_valid(node))
|
||||
dev_read_alias_seq(dev, &dev->req_seq);
|
||||
#if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
|
||||
if (dev->req_seq == -1)
|
||||
dev->req_seq =
|
||||
uclass_find_next_free_req_seq(drv->id);
|
||||
#endif
|
||||
} else {
|
||||
dev->req_seq = uclass_find_next_free_req_seq(drv->id);
|
||||
}
|
||||
|
@ -307,7 +312,6 @@ static void *alloc_priv(int size, uint flags)
|
|||
|
||||
int device_probe(struct udevice *dev)
|
||||
{
|
||||
struct power_domain pd;
|
||||
const struct driver *drv;
|
||||
int size = 0;
|
||||
int ret;
|
||||
|
@ -389,9 +393,11 @@ int device_probe(struct udevice *dev)
|
|||
pinctrl_select_state(dev, "default");
|
||||
|
||||
if (CONFIG_IS_ENABLED(POWER_DOMAIN) && dev->parent &&
|
||||
device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) {
|
||||
if (!power_domain_get(dev, &pd))
|
||||
power_domain_on(&pd);
|
||||
(device_get_uclass_id(dev) != UCLASS_POWER_DOMAIN) &&
|
||||
!(drv->flags & DM_FLAG_DEFAULT_PD_CTRL_OFF)) {
|
||||
ret = dev_power_domain_on(dev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = uclass_pre_probe_device(dev);
|
||||
|
|
|
@ -16,7 +16,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
|
|||
struct udevice *child;
|
||||
|
||||
/* print the first 20 characters to not break the tree-format. */
|
||||
printf(" %-10.10s %2d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
|
||||
printf(" %-10.10s %3d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
|
||||
dev_get_uclass_index(dev, NULL),
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
|
||||
|
||||
|
@ -64,7 +64,7 @@ void dm_dump_all(void)
|
|||
*/
|
||||
static void dm_display_line(struct udevice *dev, int index)
|
||||
{
|
||||
printf("%i %c %s @ %08lx", index,
|
||||
printf("%-3i %c %s @ %08lx", index,
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
|
||||
dev->name, (ulong)map_to_sysmem(dev));
|
||||
if (dev->seq != -1 || dev->req_seq != -1)
|
||||
|
|
|
@ -269,7 +269,9 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
#if !CONFIG_IS_ENABLED(OF_CONTROL) || \
|
||||
CONFIG_IS_ENABLED(OF_PLATDATA) || \
|
||||
CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
|
||||
int uclass_find_next_free_req_seq(enum uclass_id id)
|
||||
{
|
||||
struct uclass *uc;
|
||||
|
|
|
@ -59,6 +59,38 @@ config PINCONF
|
|||
This option enables pin configuration through the generic pinctrl
|
||||
framework.
|
||||
|
||||
config PINCONF_RECURSIVE
|
||||
bool "Support recursive binding for pin configuration nodes"
|
||||
depends on PINCTRL_FULL
|
||||
default n if ARCH_STM32MP
|
||||
default y
|
||||
help
|
||||
In the Linux pinctrl binding, the pin configuration nodes need not be
|
||||
direct children of the pin controller device (may be grandchildren for
|
||||
example). It is define is each individual pin controller device.
|
||||
Say Y here if you want to keep this behavior with the pinconfig
|
||||
u-class: all sub are recursivelly bounded.
|
||||
If the option is disabled, this behavior is deactivated and only
|
||||
the direct children of pin controller will be assumed as pin
|
||||
configuration; you can save memory footprint when this feature is
|
||||
no needed.
|
||||
|
||||
config PINCONF_RECURSIVE
|
||||
bool "Support recursive binding for pin configuration nodes"
|
||||
depends on PINCTRL_FULL
|
||||
default n if ARCH_STM32MP
|
||||
default y
|
||||
help
|
||||
In the Linux pinctrl binding, the pin configuration nodes need not be
|
||||
direct children of the pin controller device (may be grandchildren for
|
||||
example). It is define is each individual pin controller device.
|
||||
Say Y here if you want to keep this behavior with the pinconfig
|
||||
u-class: all sub are recursivelly bounded.
|
||||
If the option is disabled, this behavior is deactivated and only
|
||||
the direct children of pin controller will be assumed as pin
|
||||
configuration; you can save memory footprint when this feature is
|
||||
no needed.
|
||||
|
||||
config SPL_PINCTRL
|
||||
bool "Support pin controllers in SPL"
|
||||
depends on SPL && SPL_DM
|
||||
|
@ -104,6 +136,24 @@ config SPL_PINCONF
|
|||
This option is an SPL-variant of the PINCONF option.
|
||||
See the help of PINCONF for details.
|
||||
|
||||
config SPL_PINCONF_RECURSIVE
|
||||
bool "Support recursive binding for pin configuration nodes in SPL"
|
||||
depends on SPL_PINCTRL_FULL
|
||||
default n if ARCH_STM32MP
|
||||
default y
|
||||
help
|
||||
This option is an SPL-variant of the PINCONF_RECURSIVE option.
|
||||
See the help of PINCONF_RECURSIVE for details.
|
||||
|
||||
config SPL_PINCONF_RECURSIVE
|
||||
bool "Support recursive binding for pin configuration nodes in SPL"
|
||||
depends on SPL_PINCTRL_FULL
|
||||
default n if ARCH_STM32MP
|
||||
default y
|
||||
help
|
||||
This option is an SPL-variant of the PINCONF_RECURSIVE option.
|
||||
See the help of PINCONF_RECURSIVE for details.
|
||||
|
||||
if PINCTRL || SPL_PINCTRL
|
||||
|
||||
config PINCTRL_AR933X
|
||||
|
|
|
@ -91,12 +91,18 @@ static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
|
|||
phandle = fdt32_to_cpu(*list++);
|
||||
ret = uclass_get_device_by_phandle_id(UCLASS_PINCONFIG, phandle,
|
||||
&config);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
dev_warn(dev, "%s: uclass_get_device_by_phandle_id: err=%d\n",
|
||||
__func__, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = pinctrl_config_one(config);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret) {
|
||||
dev_warn(dev, "%s: pinctrl_config_one: err=%d\n",
|
||||
__func__, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -151,7 +157,9 @@ static int pinconfig_post_bind(struct udevice *dev)
|
|||
|
||||
UCLASS_DRIVER(pinconfig) = {
|
||||
.id = UCLASS_PINCONFIG,
|
||||
#if CONFIG_IS_ENABLED(PINCONFIG_RECURSIVE)
|
||||
.post_bind = pinconfig_post_bind,
|
||||
#endif
|
||||
.name = "pinconfig",
|
||||
};
|
||||
|
||||
|
@ -395,7 +403,7 @@ int pinctrl_get_pin_muxing(struct udevice *dev, int selector, char *buf,
|
|||
* @dev: pinctrl device
|
||||
* @return: 0 on success, or negative error code on failure
|
||||
*/
|
||||
static int pinctrl_post_bind(struct udevice *dev)
|
||||
static int __maybe_unused pinctrl_post_bind(struct udevice *dev)
|
||||
{
|
||||
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
|
||||
|
||||
|
@ -418,7 +426,9 @@ static int pinctrl_post_bind(struct udevice *dev)
|
|||
|
||||
UCLASS_DRIVER(pinctrl) = {
|
||||
.id = UCLASS_PINCTRL,
|
||||
#if CONFIG_IS_ENABLED(PINCONF_RECURSIVE)
|
||||
.post_bind = pinctrl_post_bind,
|
||||
#endif
|
||||
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||
.name = "pinctrl",
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <dm.h>
|
||||
#include <power-domain.h>
|
||||
#include <power-domain-uclass.h>
|
||||
#include <dm/device-internal.h>
|
||||
|
||||
static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev)
|
||||
{
|
||||
|
@ -107,6 +108,47 @@ int power_domain_off(struct power_domain *power_domain)
|
|||
return ops->off(power_domain);
|
||||
}
|
||||
|
||||
#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
|
||||
static int dev_power_domain_ctrl(struct udevice *dev, bool on)
|
||||
{
|
||||
struct power_domain pd;
|
||||
int i, count, ret = 0;
|
||||
|
||||
count = dev_count_phandle_with_args(dev, "power-domains",
|
||||
"#power-domain-cells");
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = power_domain_get_by_index(dev, &pd, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (on)
|
||||
ret = power_domain_on(&pd);
|
||||
else
|
||||
ret = power_domain_off(&pd);
|
||||
}
|
||||
|
||||
/*
|
||||
* power_domain_get() bound the device, thus
|
||||
* we must remove it again to prevent unbinding
|
||||
* active devices (which would result in unbind
|
||||
* error).
|
||||
*/
|
||||
if (count > 0 && !on)
|
||||
device_remove(pd.dev, DM_REMOVE_NORMAL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dev_power_domain_on(struct udevice *dev)
|
||||
{
|
||||
return dev_power_domain_ctrl(dev, true);
|
||||
}
|
||||
|
||||
int dev_power_domain_off(struct udevice *dev)
|
||||
{
|
||||
return dev_power_domain_ctrl(dev, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
UCLASS_DRIVER(power_domain) = {
|
||||
.id = UCLASS_POWER_DOMAIN,
|
||||
.name = "power_domain",
|
||||
|
|
|
@ -225,4 +225,5 @@ U_BOOT_DRIVER(k3_arm64) = {
|
|||
.ops = &k3_arm64_ops,
|
||||
.probe = k3_arm64_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct k3_arm64_privdata),
|
||||
.flags = DM_FLAG_DEFAULT_PD_CTRL_OFF,
|
||||
};
|
||||
|
|
|
@ -299,7 +299,7 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
|
|||
bool created = false;
|
||||
int ret;
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA) || CONFIG_IS_ENABLED(OF_PRIOR_STAGE)
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
ret = uclass_first_device_err(UCLASS_SPI, &bus);
|
||||
#else
|
||||
ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
|
||||
|
|
|
@ -596,9 +596,9 @@ static int tpm_tis_spi_probe(struct udevice *dev)
|
|||
log(LOGC_NONE, LOGL_NOTICE, "%s: missing reset GPIO\n",
|
||||
__func__);
|
||||
} else {
|
||||
dm_gpio_set_value(&reset_gpio, 0);
|
||||
mdelay(1);
|
||||
dm_gpio_set_value(&reset_gpio, 1);
|
||||
mdelay(1);
|
||||
dm_gpio_set_value(&reset_gpio, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@ struct driver_info;
|
|||
*/
|
||||
#define DM_FLAG_OS_PREPARE (1 << 10)
|
||||
|
||||
/* DM does not enable/disable the power domains corresponding to this device */
|
||||
#define DM_FLAG_DEFAULT_PD_CTRL_OFF (1 << 11)
|
||||
|
||||
/*
|
||||
* One or multiple of these flags are passed to device_remove() so that
|
||||
* a selective device removal as specified by the remove-stage and the
|
||||
|
@ -945,8 +948,8 @@ static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp)
|
|||
return kzalloc(size, gfp);
|
||||
}
|
||||
|
||||
static inline void *devm_kmaloc_array(struct udevice *dev,
|
||||
size_t n, size_t size, gfp_t flags)
|
||||
static inline void *devm_kmalloc_array(struct udevice *dev,
|
||||
size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
/* TODO: add kmalloc_array() to linux/compat.h */
|
||||
if (size != 0 && n > SIZE_MAX / size)
|
||||
|
|
|
@ -111,7 +111,7 @@ static inline const char *of_node_full_name(const struct device_node *np)
|
|||
|
||||
/* Default #address and #size cells */
|
||||
#if !defined(OF_ROOT_NODE_ADDR_CELLS_DEFAULT)
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1
|
||||
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
|
||||
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -155,4 +155,38 @@ static inline int power_domain_off(struct power_domain *power_domain)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dev_power_domain_on - Enable power domains for a device .
|
||||
*
|
||||
* @dev: The client device.
|
||||
*
|
||||
* @return 0 if OK, or a negative error code.
|
||||
*/
|
||||
#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
|
||||
CONFIG_IS_ENABLED(POWER_DOMAIN)
|
||||
int dev_power_domain_on(struct udevice *dev);
|
||||
#else
|
||||
static inline int dev_power_domain_on(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dev_power_domain_off - Disable power domains for a device .
|
||||
*
|
||||
* @dev: The client device.
|
||||
*
|
||||
* @return 0 if OK, or a negative error code.
|
||||
*/
|
||||
#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
|
||||
CONFIG_IS_ENABLED(POWER_DOMAIN)
|
||||
int dev_power_domain_off(struct udevice *dev);
|
||||
#else
|
||||
static inline int dev_power_domain_off(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -437,8 +437,7 @@ int rsa_verify(struct image_sign_info *info,
|
|||
if (info->required_keynode != -1) {
|
||||
ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
|
||||
info->required_keynode);
|
||||
if (!ret)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Look for a key that matches our hint */
|
||||
|
|
|
@ -229,9 +229,11 @@ ALL-y += $(obj)/boot.bin
|
|||
endif
|
||||
|
||||
ifdef CONFIG_TPL_BUILD
|
||||
ALL-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-tpl.bin
|
||||
ALL-$(CONFIG_TPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-tpl.bin \
|
||||
$(obj)/u-boot-x86-reset16-tpl.bin
|
||||
else
|
||||
ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-spl.bin
|
||||
ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-start16-spl.bin \
|
||||
$(obj)/u-boot-x86-reset16-spl.bin
|
||||
endif
|
||||
|
||||
ALL-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin
|
||||
|
@ -337,12 +339,20 @@ OBJCOPYFLAGS_$(SPL_BIN)-nodtb.bin = $(SPL_OBJCFLAGS) -O binary \
|
|||
$(obj)/$(SPL_BIN)-nodtb.bin: $(obj)/$(SPL_BIN) FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-16bit-spl.bin := -O binary -j .start16 -j .resetvec
|
||||
$(obj)/u-boot-x86-16bit-spl.bin: $(obj)/u-boot-spl FORCE
|
||||
OBJCOPYFLAGS_u-boot-x86-start16-spl.bin := -O binary -j .start16
|
||||
$(obj)/u-boot-x86-start16-spl.bin: $(obj)/u-boot-spl FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-16bit-tpl.bin := -O binary -j .start16 -j .resetvec
|
||||
$(obj)/u-boot-x86-16bit-tpl.bin: $(obj)/u-boot-tpl FORCE
|
||||
OBJCOPYFLAGS_u-boot-x86-start16-tpl.bin := -O binary -j .start16
|
||||
$(obj)/u-boot-x86-start16-tpl.bin: $(obj)/u-boot-tpl FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-reset16-spl.bin := -O binary -j .resetvec
|
||||
$(obj)/u-boot-x86-reset16-spl.bin: $(obj)/u-boot-spl FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
OBJCOPYFLAGS_u-boot-x86-reset16-tpl.bin := -O binary -j .resetvec
|
||||
$(obj)/u-boot-x86-reset16-tpl.bin: $(obj)/u-boot-tpl FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* libfdt - Flat Device Tree manipulation
|
||||
* Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
|
||||
* Copyright (C) 2018 embedded brains GmbH
|
||||
*
|
||||
* libfdt is dual licensed: you can use it either under the terms of
|
||||
* the GPL, or the BSD license, at your option.
|
||||
|
@ -55,42 +56,44 @@
|
|||
|
||||
#include "libfdt_internal.h"
|
||||
|
||||
int fdt_address_cells(const void *fdt, int nodeoffset)
|
||||
static int fdt_cells(const void *fdt, int nodeoffset, const char *name)
|
||||
{
|
||||
const fdt32_t *ac;
|
||||
int val;
|
||||
const fdt32_t *c;
|
||||
uint32_t val;
|
||||
int len;
|
||||
|
||||
ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
|
||||
if (!ac)
|
||||
c = fdt_getprop(fdt, nodeoffset, name, &len);
|
||||
if (!c)
|
||||
return len;
|
||||
|
||||
if (len != sizeof(*c))
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
val = fdt32_to_cpu(*c);
|
||||
if (val > FDT_MAX_NCELLS)
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
int fdt_address_cells(const void *fdt, int nodeoffset)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = fdt_cells(fdt, nodeoffset, "#address-cells");
|
||||
if (val == 0)
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
if (val == -FDT_ERR_NOTFOUND)
|
||||
return 2;
|
||||
|
||||
if (len != sizeof(*ac))
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
val = fdt32_to_cpu(*ac);
|
||||
if ((val <= 0) || (val > FDT_MAX_NCELLS))
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int fdt_size_cells(const void *fdt, int nodeoffset)
|
||||
{
|
||||
const fdt32_t *sc;
|
||||
int val;
|
||||
int len;
|
||||
|
||||
sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
|
||||
if (!sc)
|
||||
return 2;
|
||||
|
||||
if (len != sizeof(*sc))
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
val = fdt32_to_cpu(*sc);
|
||||
if ((val < 0) || (val > FDT_MAX_NCELLS))
|
||||
return -FDT_ERR_BADNCELLS;
|
||||
|
||||
val = fdt_cells(fdt, nodeoffset, "#size-cells");
|
||||
if (val == -FDT_ERR_NOTFOUND)
|
||||
return 1;
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -734,7 +734,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
|
|||
/**
|
||||
* fdt_get_alias_namelen - get alias based on substring
|
||||
* @fdt: pointer to the device tree blob
|
||||
* @name: name of the alias th look up
|
||||
* @name: name of the alias to look up
|
||||
* @namelen: number of characters of name to consider
|
||||
*
|
||||
* Identical to fdt_get_alias(), but only examine the first namelen
|
||||
|
@ -1109,7 +1109,7 @@ int fdt_address_cells(const void *fdt, int nodeoffset);
|
|||
*
|
||||
* returns:
|
||||
* 0 <= n < FDT_MAX_NCELLS, on success
|
||||
* 2, if the node has no #address-cells property
|
||||
* 1, if the node has no #size-cells property
|
||||
* -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
|
||||
* #size-cells property
|
||||
* -FDT_ERR_BADMAGIC,
|
||||
|
|
|
@ -13,7 +13,7 @@ def in_tree(response, name, uclass, drv, depth, last_child):
|
|||
else:
|
||||
leaf = leaf + '`'
|
||||
leaf = leaf + '-- ' + name
|
||||
line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'
|
||||
line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'
|
||||
.format(uclass, drv, leaf))
|
||||
prog = re.compile(line)
|
||||
for l in lines:
|
||||
|
|
|
@ -80,6 +80,8 @@ def test_vboot(u_boot_console):
|
|||
assert(expect_string in ''.join(output))
|
||||
if boots:
|
||||
assert('sandbox: continuing, as we cannot run' in ''.join(output))
|
||||
else:
|
||||
assert('sandbox: continuing, as we cannot run' not in ''.join(output))
|
||||
|
||||
def make_fit(its):
|
||||
"""Make a new FIT from the .its source file.
|
||||
|
@ -106,6 +108,20 @@ def test_vboot(u_boot_console):
|
|||
util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
|
||||
'-r', fit])
|
||||
|
||||
def sign_fit_norequire(sha_algo):
|
||||
"""Sign the FIT
|
||||
|
||||
Signs the FIT and writes the signature into it. It also writes the
|
||||
public key into the dtb.
|
||||
|
||||
Args:
|
||||
sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
|
||||
use.
|
||||
"""
|
||||
cons.log.action('%s: Sign images' % sha_algo)
|
||||
util.run_and_log(cons, [mkimage, '-F', '-k', tmpdir, '-K', dtb,
|
||||
fit])
|
||||
|
||||
def replace_fit_totalsize(size):
|
||||
"""Replace FIT header's totalsize with something greater.
|
||||
|
||||
|
@ -195,6 +211,35 @@ def test_vboot(u_boot_console):
|
|||
util.run_and_log_expect_exception(cons, [fit_check_sign, '-f', fit,
|
||||
'-k', dtb], 1, 'Failed to verify required signature')
|
||||
|
||||
def test_required_key(sha_algo, padding):
|
||||
"""Test verified boot with the given hash algorithm.
|
||||
|
||||
This function test if u-boot reject an image when a required
|
||||
key isn't used to sign a FIT.
|
||||
|
||||
Args:
|
||||
sha_algo: Either 'sha1' or 'sha256', to select the algorithm to
|
||||
use.
|
||||
"""
|
||||
# Compile our device tree files for kernel and U-Boot. These are
|
||||
# regenerated here since mkimage will modify them (by adding a
|
||||
# public key) below.
|
||||
dtc('sandbox-kernel.dts')
|
||||
dtc('sandbox-u-boot.dts')
|
||||
|
||||
# Build the FIT with prod key (keys required)
|
||||
# Build the FIT with dev key (keys NOT required)
|
||||
# The dtb contain the key prod and dev and the key prod are set as required.
|
||||
# Then try to boot the FIT with dev key
|
||||
# This FIT should not be accepted by u-boot because the key prod is required
|
||||
cons.log.action('%s: Test FIT with configs images' % sha_algo)
|
||||
make_fit('sign-configs-%s%s-prod.its' % (sha_algo , padding))
|
||||
sign_fit(sha_algo)
|
||||
make_fit('sign-configs-%s%s.its' % (sha_algo , padding))
|
||||
sign_fit(sha_algo)
|
||||
|
||||
run_bootm(sha_algo, 'signed configs', '', False)
|
||||
|
||||
cons = u_boot_console
|
||||
tmpdir = cons.config.result_dir + '/'
|
||||
tmp = tmpdir + 'vboot.tmp'
|
||||
|
@ -217,6 +262,17 @@ def test_vboot(u_boot_console):
|
|||
util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sdev.key -out '
|
||||
'%sdev.crt' % (tmpdir, tmpdir))
|
||||
|
||||
# Create an RSA key pair (prod)
|
||||
public_exponent = 65537
|
||||
util.run_and_log(cons, 'openssl genpkey -algorithm RSA -out %sprod.key '
|
||||
'-pkeyopt rsa_keygen_bits:2048 '
|
||||
'-pkeyopt rsa_keygen_pubexp:%d' %
|
||||
(tmpdir, public_exponent))
|
||||
|
||||
# Create a certificate containing the public key (prod)
|
||||
util.run_and_log(cons, 'openssl req -batch -new -x509 -key %sprod.key -out '
|
||||
'%sprod.crt' % (tmpdir, tmpdir))
|
||||
|
||||
# Create a number kernel image with zeroes
|
||||
with open('%stest-kernel.bin' % tmpdir, 'w') as fd:
|
||||
fd.write(5000 * chr(0))
|
||||
|
@ -230,6 +286,7 @@ def test_vboot(u_boot_console):
|
|||
test_with_algo('sha1','-pss')
|
||||
test_with_algo('sha256','')
|
||||
test_with_algo('sha256','-pss')
|
||||
test_required_key('sha256','-pss')
|
||||
finally:
|
||||
# Go back to the original U-Boot with the correct dtb.
|
||||
cons.config.dtb = old_dtb
|
||||
|
|
46
test/py/tests/vboot/sign-configs-sha256-pss-prod.its
Normal file
46
test/py/tests/vboot/sign-configs-sha256-pss-prod.its
Normal file
|
@ -0,0 +1,46 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "Chrome OS kernel image with one or more FDT blobs";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
kernel {
|
||||
data = /incbin/("test-kernel.bin");
|
||||
type = "kernel_noload";
|
||||
arch = "sandbox";
|
||||
os = "linux";
|
||||
compression = "none";
|
||||
load = <0x4>;
|
||||
entry = <0x8>;
|
||||
kernel-version = <1>;
|
||||
hash-1 {
|
||||
algo = "sha256";
|
||||
};
|
||||
};
|
||||
fdt-1 {
|
||||
description = "snow";
|
||||
data = /incbin/("sandbox-kernel.dtb");
|
||||
type = "flat_dt";
|
||||
arch = "sandbox";
|
||||
compression = "none";
|
||||
fdt-version = <1>;
|
||||
hash-1 {
|
||||
algo = "sha256";
|
||||
};
|
||||
};
|
||||
};
|
||||
configurations {
|
||||
default = "conf-1";
|
||||
conf-1 {
|
||||
kernel = "kernel";
|
||||
fdt = "fdt-1";
|
||||
signature {
|
||||
algo = "sha256,rsa2048";
|
||||
padding = "pss";
|
||||
key-name-hint = "prod";
|
||||
sign-images = "fdt", "kernel";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -391,6 +391,25 @@ See README.x86 for information about x86 binary blobs.
|
|||
|
||||
|
||||
|
||||
Entry: intel-fit: Intel Firmware Image Table (FIT)
|
||||
--------------------------------------------------
|
||||
|
||||
This entry contains a dummy FIT as required by recent Intel CPUs. The FIT
|
||||
contains information about the firmware and microcode available in the
|
||||
image.
|
||||
|
||||
At present binman only supports a basic FIT with no microcode.
|
||||
|
||||
|
||||
|
||||
Entry: intel-fit-ptr: Intel Firmware Image Table (FIT) pointer
|
||||
--------------------------------------------------------------
|
||||
|
||||
This entry contains a pointer to the FIT. It is required to be at address
|
||||
0xffffffc0 in the image.
|
||||
|
||||
|
||||
|
||||
Entry: intel-fsp: Entry containing an Intel Firmware Support Package (FSP) file
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -408,6 +427,23 @@ See README.x86 for information about x86 binary blobs.
|
|||
|
||||
|
||||
|
||||
Entry: intel-fsp-m: Entry containing Intel Firmware Support Package (FSP) memory init
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of file to read into entry
|
||||
|
||||
This file contains a binary blob which is used on some devices to set up
|
||||
SDRAM. U-Boot executes this code in SPL so that it can make full use of
|
||||
memory. Documentation is typically not available in sufficient detail to
|
||||
allow U-Boot do this this itself..
|
||||
|
||||
An example filename is 'fsp_m.bin'
|
||||
|
||||
See README.x86 for information about x86 binary blobs.
|
||||
|
||||
|
||||
|
||||
Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
@ -432,6 +468,12 @@ The contents of the IFWI are specified by the subnodes of the IFWI node.
|
|||
Each subnode describes an entry which is placed into the IFWFI with a given
|
||||
sub-partition (and optional entry name).
|
||||
|
||||
Properties for subnodes:
|
||||
ifwi-subpart - sub-parition to put this entry into, e.g. "IBBP"
|
||||
ifwi-entry - entry name t use, e.g. "IBBL"
|
||||
ifwi-replace - if present, indicates that the item should be replaced
|
||||
in the IFWI. Otherwise it is added.
|
||||
|
||||
See README.x86 for information about x86 binary blobs.
|
||||
|
||||
|
||||
|
@ -931,18 +973,67 @@ and kernel are genuine.
|
|||
|
||||
|
||||
|
||||
Entry: x86-reset16: x86 16-bit reset code for U-Boot
|
||||
----------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 64-bit U-Boot, the 'x86_reset16_spl' entry type is used instead.
|
||||
|
||||
|
||||
|
||||
Entry: x86-reset16-spl: x86 16-bit reset code for U-Boot
|
||||
--------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 32-bit U-Boot, the 'x86_reset_spl' entry type is used instead.
|
||||
|
||||
|
||||
|
||||
Entry: x86-reset16-tpl: x86 16-bit reset code for U-Boot
|
||||
--------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 32-bit U-Boot, the 'x86_reset_tpl' entry type is used instead.
|
||||
|
||||
|
||||
|
||||
Entry: x86-start16: x86 16-bit start-up code for U-Boot
|
||||
-------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-16bit.bin (default
|
||||
'u-boot-x86-16bit.bin')
|
||||
- filename: Filename of u-boot-x86-start16.bin (default
|
||||
'u-boot-x86-start16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and jumping to U-Boot's entry point, which
|
||||
requires 32-bit mode (for 32-bit U-Boot).
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
For 64-bit U-Boot, the 'x86_start16_spl' entry type is used instead.
|
||||
|
||||
|
@ -952,16 +1043,17 @@ Entry: x86-start16-spl: x86 16-bit start-up code for SPL
|
|||
--------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of spl/u-boot-x86-16bit-spl.bin (default
|
||||
'spl/u-boot-x86-16bit-spl.bin')
|
||||
- filename: Filename of spl/u-boot-x86-start16-spl.bin (default
|
||||
'spl/u-boot-x86-start16-spl.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and starting SPL, which in turn changes to
|
||||
64-bit mode and jumps to U-Boot (for 64-bit U-Boot).
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
For 32-bit U-Boot, the 'x86_start16' entry type is used instead.
|
||||
For 32-bit U-Boot, the 'x86-start16' entry type is used instead.
|
||||
|
||||
|
||||
|
||||
|
@ -969,15 +1061,17 @@ Entry: x86-start16-tpl: x86 16-bit start-up code for TPL
|
|||
--------------------------------------------------------
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of tpl/u-boot-x86-16bit-tpl.bin (default
|
||||
'tpl/u-boot-x86-16bit-tpl.bin')
|
||||
- filename: Filename of tpl/u-boot-x86-start16-tpl.bin (default
|
||||
'tpl/u-boot-x86-start16-tpl.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and starting TPL, which in turn jumps to SPL.
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
If TPL is not being used, the 'x86_start16_spl or 'x86_start16' entry types
|
||||
If TPL is not being used, the 'x86-start16-spl or 'x86-start16' entry types
|
||||
may be used instead.
|
||||
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@ import tools
|
|||
import cbfs_util
|
||||
import command
|
||||
import elf
|
||||
from image import Image
|
||||
import state
|
||||
import tout
|
||||
|
||||
# List of images we plan to create
|
||||
|
@ -113,6 +111,9 @@ def ReadEntry(image_fname, entry_path, decomp=True):
|
|||
Returns:
|
||||
data extracted from the entry
|
||||
"""
|
||||
global Image
|
||||
from image import Image
|
||||
|
||||
image = Image.FromFile(image_fname)
|
||||
entry = image.FindEntryPath(entry_path)
|
||||
return entry.ReadData(decomp)
|
||||
|
@ -436,15 +437,16 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True,
|
|||
for dtb_item in state.GetAllFdts():
|
||||
dtb_item.Sync()
|
||||
dtb_item.Flush()
|
||||
image.WriteSymbols()
|
||||
sizes_ok = image.ProcessEntryContents()
|
||||
if sizes_ok:
|
||||
break
|
||||
image.ResetForPack()
|
||||
tout.Info('Pack completed after %d pass(es)' % (pack_pass + 1))
|
||||
if not sizes_ok:
|
||||
image.Raise('Entries changed size after packing (tried %s passes)' %
|
||||
passes)
|
||||
|
||||
image.WriteSymbols()
|
||||
image.BuildImage()
|
||||
if write_map:
|
||||
image.WriteMap()
|
||||
|
@ -459,6 +461,9 @@ def Binman(args):
|
|||
Args:
|
||||
args: Command line arguments Namespace object
|
||||
"""
|
||||
global Image
|
||||
global state
|
||||
|
||||
if args.full_help:
|
||||
pager = os.getenv('PAGER')
|
||||
if not pager:
|
||||
|
@ -468,6 +473,10 @@ def Binman(args):
|
|||
command.Run(pager, fname)
|
||||
return 0
|
||||
|
||||
# Put these here so that we can import this module without libfdt
|
||||
from image import Image
|
||||
import state
|
||||
|
||||
if args.cmd in ['ls', 'extract', 'replace']:
|
||||
try:
|
||||
tout.Init(args.verbosity)
|
||||
|
|
|
@ -49,7 +49,7 @@ def GetSymbols(fname, patterns):
|
|||
key: Name of symbol
|
||||
value: Hex value of symbol
|
||||
"""
|
||||
stdout = command.Output('objdump', '-t', fname, raise_on_error=False)
|
||||
stdout = tools.Run('objdump', '-t', fname)
|
||||
lines = stdout.splitlines()
|
||||
if patterns:
|
||||
re_syms = re.compile('|'.join(patterns))
|
||||
|
@ -72,7 +72,7 @@ def GetSymbols(fname, patterns):
|
|||
parts = rest[7:].split()
|
||||
section, size = parts[:2]
|
||||
if len(parts) > 2:
|
||||
name = parts[2]
|
||||
name = parts[2] if parts[2] != '.hidden' else parts[3]
|
||||
syms[name] = Symbol(section, int(value, 16), int(size,16),
|
||||
flags[1] == 'w')
|
||||
|
||||
|
@ -221,6 +221,9 @@ SECTIONS
|
|||
.empty : {
|
||||
*(.empty)
|
||||
} :empty
|
||||
/DISCARD/ : {
|
||||
*(.note.gnu.property)
|
||||
}
|
||||
.note : {
|
||||
*(.comment)
|
||||
} :note
|
||||
|
|
|
@ -50,20 +50,53 @@ class FakeSection:
|
|||
return self.sym_value
|
||||
|
||||
|
||||
def BuildElfTestFiles(target_dir):
|
||||
"""Build ELF files used for testing in binman
|
||||
|
||||
This compiles and links the test files into the specified directory. It the
|
||||
Makefile and source files in the binman test/ directory.
|
||||
|
||||
Args:
|
||||
target_dir: Directory to put the files into
|
||||
"""
|
||||
if not os.path.exists(target_dir):
|
||||
os.mkdir(target_dir)
|
||||
testdir = os.path.join(binman_dir, 'test')
|
||||
|
||||
# If binman is involved from the main U-Boot Makefile the -r and -R
|
||||
# flags are set in MAKEFLAGS. This prevents this Makefile from working
|
||||
# correctly. So drop any make flags here.
|
||||
if 'MAKEFLAGS' in os.environ:
|
||||
del os.environ['MAKEFLAGS']
|
||||
tools.Run('make', '-C', target_dir, '-f',
|
||||
os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
|
||||
|
||||
|
||||
class TestElf(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
def setUpClass(cls):
|
||||
cls._indir = tempfile.mkdtemp(prefix='elf.')
|
||||
tools.SetInputDirs(['.'])
|
||||
BuildElfTestFiles(cls._indir)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if cls._indir:
|
||||
shutil.rmtree(cls._indir)
|
||||
|
||||
@classmethod
|
||||
def ElfTestFile(cls, fname):
|
||||
return os.path.join(cls._indir, fname)
|
||||
|
||||
def testAllSymbols(self):
|
||||
"""Test that we can obtain a symbol from the ELF file"""
|
||||
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
|
||||
fname = self.ElfTestFile('u_boot_ucode_ptr')
|
||||
syms = elf.GetSymbols(fname, [])
|
||||
self.assertIn('.ucode', syms)
|
||||
|
||||
def testRegexSymbols(self):
|
||||
"""Test that we can obtain from the ELF file by regular expression"""
|
||||
fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
|
||||
fname = self.ElfTestFile('u_boot_ucode_ptr')
|
||||
syms = elf.GetSymbols(fname, ['ucode'])
|
||||
self.assertIn('.ucode', syms)
|
||||
syms = elf.GetSymbols(fname, ['missing'])
|
||||
|
@ -84,7 +117,7 @@ class TestElf(unittest.TestCase):
|
|||
"""Test a symbol which extends outside the entry area is detected"""
|
||||
entry = FakeEntry(10)
|
||||
section = FakeSection()
|
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
|
||||
elf_fname = self.ElfTestFile('u_boot_binman_syms')
|
||||
with self.assertRaises(ValueError) as e:
|
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
|
||||
self.assertIn('entry_path has offset 4 (size 8) but the contents size '
|
||||
|
@ -98,7 +131,7 @@ class TestElf(unittest.TestCase):
|
|||
"""
|
||||
entry = FakeEntry(10)
|
||||
section = FakeSection()
|
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad')
|
||||
elf_fname = self.ElfTestFile('u_boot_binman_syms_bad')
|
||||
self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, section),
|
||||
None)
|
||||
|
||||
|
@ -110,7 +143,7 @@ class TestElf(unittest.TestCase):
|
|||
"""
|
||||
entry = FakeEntry(10)
|
||||
section = FakeSection()
|
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size')
|
||||
elf_fname =self.ElfTestFile('u_boot_binman_syms_size')
|
||||
with self.assertRaises(ValueError) as e:
|
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
|
||||
self.assertIn('has size 1: only 4 and 8 are supported',
|
||||
|
@ -122,11 +155,11 @@ class TestElf(unittest.TestCase):
|
|||
This should produce -1 values for all thress symbols, taking up the
|
||||
first 16 bytes of the image.
|
||||
"""
|
||||
entry = FakeEntry(20)
|
||||
entry = FakeEntry(24)
|
||||
section = FakeSection(sym_value=None)
|
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
|
||||
elf_fname = self.ElfTestFile('u_boot_binman_syms')
|
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
|
||||
self.assertEqual(tools.GetBytes(255, 16) + tools.GetBytes(ord('a'), 4),
|
||||
self.assertEqual(tools.GetBytes(255, 20) + tools.GetBytes(ord('a'), 4),
|
||||
entry.data)
|
||||
|
||||
def testDebug(self):
|
||||
|
@ -135,7 +168,7 @@ class TestElf(unittest.TestCase):
|
|||
tout.Init(tout.DEBUG)
|
||||
entry = FakeEntry(20)
|
||||
section = FakeSection()
|
||||
elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
|
||||
elf_fname = self.ElfTestFile('u_boot_binman_syms')
|
||||
with test_util.capture_sys_output() as (stdout, stderr):
|
||||
syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
|
||||
self.assertTrue(len(stdout.getvalue()) > 0)
|
||||
|
@ -148,7 +181,7 @@ class TestElf(unittest.TestCase):
|
|||
expected_text = b'1234'
|
||||
expected_data = b'wxyz'
|
||||
elf_fname = os.path.join(outdir, 'elf')
|
||||
bin_fname = os.path.join(outdir, 'elf')
|
||||
bin_fname = os.path.join(outdir, 'bin')
|
||||
|
||||
# Make an Elf file and then convert it to a fkat binary file. This
|
||||
# should produce the original data.
|
||||
|
@ -178,7 +211,7 @@ class TestElf(unittest.TestCase):
|
|||
self.assertEqual(elf.ElfInfo(b'\0\0' + expected[2:],
|
||||
load, entry, len(expected)),
|
||||
elf.DecodeElf(data, load + 2))
|
||||
#shutil.rmtree(outdir)
|
||||
shutil.rmtree(outdir)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -21,7 +21,6 @@ import os
|
|||
import sys
|
||||
|
||||
import fdt_util
|
||||
import state
|
||||
import tools
|
||||
from tools import ToHex, ToHexSize
|
||||
import tout
|
||||
|
@ -71,6 +70,10 @@ class Entry(object):
|
|||
orig_size: Original size value read from node
|
||||
"""
|
||||
def __init__(self, section, etype, node, name_prefix=''):
|
||||
# Put this here to allow entry-docs and help to work without libfdt
|
||||
global state
|
||||
import state
|
||||
|
||||
self.section = section
|
||||
self.etype = etype
|
||||
self._node = node
|
||||
|
|
|
@ -97,6 +97,11 @@ class TestEntry(unittest.TestCase):
|
|||
base = entry.Entry.Create(None, self.GetNode(), 'blob-dtb')
|
||||
self.assertTrue(base.WriteChildData(base))
|
||||
|
||||
def testReadChildData(self):
|
||||
"""Test the ReadChildData() method of the base class"""
|
||||
base = entry.Entry.Create(None, self.GetNode(), 'blob-dtb')
|
||||
self.assertIsNone(base.ReadChildData(base))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
from entry import Entry
|
||||
import fdt_util
|
||||
import state
|
||||
import tools
|
||||
import tout
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
# Entry-type module for U-Boot device tree files
|
||||
#
|
||||
|
||||
import state
|
||||
|
||||
from entry import Entry
|
||||
from blob import Entry_blob
|
||||
|
||||
|
@ -18,6 +16,10 @@ class Entry_blob_dtb(Entry_blob):
|
|||
'state' module.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
# Put this here to allow entry-docs and help to work without libfdt
|
||||
global state
|
||||
import state
|
||||
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def ObtainContents(self):
|
||||
|
|
|
@ -11,7 +11,6 @@ import cbfs_util
|
|||
from cbfs_util import CbfsWriter
|
||||
from entry import Entry
|
||||
import fdt_util
|
||||
import state
|
||||
|
||||
class Entry_cbfs(Entry):
|
||||
"""Entry containing a Coreboot Filesystem (CBFS)
|
||||
|
@ -164,6 +163,10 @@ class Entry_cbfs(Entry):
|
|||
both of size 1MB.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
# Put this here to allow entry-docs and help to work without libfdt
|
||||
global state
|
||||
import state
|
||||
|
||||
Entry.__init__(self, section, etype, node)
|
||||
self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86')
|
||||
self._cbfs_entries = OrderedDict()
|
||||
|
|
|
@ -8,11 +8,7 @@ This handles putting an FDT into the image with just the information about the
|
|||
image.
|
||||
"""
|
||||
|
||||
import libfdt
|
||||
|
||||
from entry import Entry
|
||||
from fdt import Fdt
|
||||
import state
|
||||
import tools
|
||||
import tout
|
||||
|
||||
|
@ -80,6 +76,15 @@ class Entry_fdtmap(Entry):
|
|||
added as necessary. See the binman README.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
# Put these here to allow entry-docs and help to work without libfdt
|
||||
global libfdt
|
||||
global state
|
||||
global Fdt
|
||||
|
||||
import libfdt
|
||||
import state
|
||||
from fdt import Fdt
|
||||
|
||||
Entry.__init__(self, section, etype, node)
|
||||
|
||||
def _GetFdtmap(self):
|
||||
|
|
|
@ -11,7 +11,6 @@ import os
|
|||
|
||||
from section import Entry_section
|
||||
import fdt_util
|
||||
import state
|
||||
import tools
|
||||
|
||||
|
||||
|
@ -29,6 +28,10 @@ class Entry_files(Entry_section):
|
|||
at run-time so you can obtain the file positions.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
# Put this here to allow entry-docs and help to work without libfdt
|
||||
global state
|
||||
import state
|
||||
|
||||
Entry_section.__init__(self, section, etype, node)
|
||||
self._pattern = fdt_util.GetString(self._node, 'pattern')
|
||||
if not self._pattern:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for 'u-boot'
|
||||
# Entry-type module for Intel flash descriptor
|
||||
#
|
||||
|
||||
import struct
|
||||
|
|
32
tools/binman/etype/intel_fit.py
Normal file
32
tools/binman/etype/intel_fit.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for Intel Firmware Image Table
|
||||
#
|
||||
|
||||
import struct
|
||||
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_intel_fit(Entry_blob):
|
||||
"""Intel Firmware Image Table (FIT)
|
||||
|
||||
This entry contains a dummy FIT as required by recent Intel CPUs. The FIT
|
||||
contains information about the firmware and microcode available in the
|
||||
image.
|
||||
|
||||
At present binman only supports a basic FIT with no microcode.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def ReadNode(self):
|
||||
"""Force 16-byte alignment as required by FIT pointer"""
|
||||
Entry_blob.ReadNode(self)
|
||||
self.align = 16
|
||||
|
||||
def ObtainContents(self):
|
||||
data = struct.pack('<8sIHBB', '_FIT_ ', 1, 0x100, 0x80, 0x7d)
|
||||
self.SetContents(data)
|
||||
return True
|
41
tools/binman/etype/intel_fit_ptr.py
Normal file
41
tools/binman/etype/intel_fit_ptr.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for a pointer to an Intel Firmware Image Table
|
||||
#
|
||||
|
||||
import struct
|
||||
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_intel_fit_ptr(Entry_blob):
|
||||
"""Intel Firmware Image Table (FIT) pointer
|
||||
|
||||
This entry contains a pointer to the FIT. It is required to be at address
|
||||
0xffffffc0 in the image.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
if self.HasSibling('intel-fit') is False:
|
||||
self.Raise("'intel-fit-ptr' section must have an 'intel-fit' sibling")
|
||||
|
||||
def _GetContents(self):
|
||||
fit_pos = self.GetSiblingImagePos('intel-fit')
|
||||
return struct.pack('<II', fit_pos or 0, 0)
|
||||
|
||||
def ObtainContents(self):
|
||||
self.SetContents(self._GetContents())
|
||||
return True
|
||||
|
||||
def ProcessContents(self):
|
||||
"""Write an updated version of the FIT pointer to this entry
|
||||
|
||||
This is necessary since image_pos is not available when ObtainContents()
|
||||
is called, since by then the entries have not been packed in the image.
|
||||
"""
|
||||
return self.ProcessContentsUpdate(self._GetContents())
|
||||
|
||||
def Pack(self, offset):
|
||||
"""Special pack method to set the offset to the right place"""
|
||||
return Entry_blob.Pack(self, 0xffffffc0)
|
27
tools/binman/etype/intel_fsp_m.py
Normal file
27
tools/binman/etype/intel_fsp_m.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright 2019 Google LLC
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for Intel Firmware Support Package binary blob (T section)
|
||||
#
|
||||
|
||||
from entry import Entry
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_intel_fsp_m(Entry_blob):
|
||||
"""Entry containing Intel Firmware Support Package (FSP) memory init
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of file to read into entry
|
||||
|
||||
This file contains a binary blob which is used on some devices to set up
|
||||
SDRAM. U-Boot executes this code in SPL so that it can make full use of
|
||||
memory. Documentation is typically not available in sufficient detail to
|
||||
allow U-Boot do this this itself..
|
||||
|
||||
An example filename is 'fsp_m.bin'
|
||||
|
||||
See README.x86 for information about x86 binary blobs.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
|
@ -36,13 +36,52 @@ class Entry_intel_ifwi(Entry_blob):
|
|||
Each subnode describes an entry which is placed into the IFWFI with a given
|
||||
sub-partition (and optional entry name).
|
||||
|
||||
Properties for subnodes:
|
||||
ifwi-subpart - sub-parition to put this entry into, e.g. "IBBP"
|
||||
ifwi-entry - entry name t use, e.g. "IBBL"
|
||||
ifwi-replace - if present, indicates that the item should be replaced
|
||||
in the IFWI. Otherwise it is added.
|
||||
|
||||
See README.x86 for information about x86 binary blobs.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
self._convert_fit = fdt_util.GetBool(self._node, 'convert-fit')
|
||||
self._ifwi_entries = OrderedDict()
|
||||
|
||||
def ReadNode(self):
|
||||
self._ReadSubnodes()
|
||||
Entry_blob.ReadNode(self)
|
||||
|
||||
def _BuildIfwi(self):
|
||||
"""Build the contents of the IFWI and write it to the 'data' property"""
|
||||
# Create the IFWI file if needed
|
||||
if self._convert_fit:
|
||||
inname = self._pathname
|
||||
outname = tools.GetOutputFilename('ifwi.bin')
|
||||
tools.RunIfwiTool(inname, tools.CMD_CREATE, outname)
|
||||
self._filename = 'ifwi.bin'
|
||||
self._pathname = outname
|
||||
else:
|
||||
# Provide a different code path here to ensure we have test coverage
|
||||
outname = self._pathname
|
||||
|
||||
# Delete OBBP if it is there, then add the required new items.
|
||||
tools.RunIfwiTool(outname, tools.CMD_DELETE, subpart='OBBP')
|
||||
|
||||
for entry in self._ifwi_entries.values():
|
||||
# First get the input data and put it in a file
|
||||
data = entry.GetData()
|
||||
uniq = self.GetUniqueName()
|
||||
input_fname = tools.GetOutputFilename('input.%s' % uniq)
|
||||
tools.WriteFile(input_fname, data)
|
||||
|
||||
tools.RunIfwiTool(outname,
|
||||
tools.CMD_REPLACE if entry._ifwi_replace else tools.CMD_ADD,
|
||||
input_fname, entry._ifwi_subpart, entry._ifwi_entry_name)
|
||||
|
||||
self.ReadBlobContents()
|
||||
return True
|
||||
|
||||
def ObtainContents(self):
|
||||
"""Get the contects for the IFWI
|
||||
|
@ -59,43 +98,28 @@ class Entry_intel_ifwi(Entry_blob):
|
|||
that we want in the IFWI file, one for each sub-entry of the IWFI node.
|
||||
"""
|
||||
self._pathname = tools.GetInputFilename(self._filename)
|
||||
|
||||
# Create the IFWI file if needed
|
||||
if self._convert_fit:
|
||||
inname = self._pathname
|
||||
outname = tools.GetOutputFilename('ifwi.bin')
|
||||
tools.RunIfwiTool(inname, tools.CMD_CREATE, outname)
|
||||
self._filename = 'ifwi.bin'
|
||||
self._pathname = outname
|
||||
else:
|
||||
# Provide a different code path here to ensure we have test coverage
|
||||
inname = self._pathname
|
||||
|
||||
# Delete OBBP if it is there, then add the required new items.
|
||||
tools.RunIfwiTool(inname, tools.CMD_DELETE, subpart='OBBP')
|
||||
|
||||
for entry in self._ifwi_entries.values():
|
||||
# First get the input data and put it in a file
|
||||
if not entry.ObtainContents():
|
||||
return False
|
||||
data = entry.GetData()
|
||||
uniq = self.GetUniqueName()
|
||||
input_fname = tools.GetOutputFilename('input.%s' % uniq)
|
||||
tools.WriteFile(input_fname, data)
|
||||
return self._BuildIfwi()
|
||||
|
||||
tools.RunIfwiTool(inname,
|
||||
tools.CMD_REPLACE if entry._ifwi_replace else tools.CMD_ADD,
|
||||
input_fname, entry._ifwi_subpart, entry._ifwi_entry_name)
|
||||
|
||||
self.ReadBlobContents()
|
||||
return True
|
||||
def ProcessContents(self):
|
||||
orig_data = self.data
|
||||
self._BuildIfwi()
|
||||
same = orig_data == self.data
|
||||
return same
|
||||
|
||||
def _ReadSubnodes(self):
|
||||
"""Read the subnodes to find out what should go in this IFWI"""
|
||||
for node in self._node.subnodes:
|
||||
entry = Entry.Create(self.section, node)
|
||||
entry.ReadNode()
|
||||
entry._ifwi_replace = fdt_util.GetBool(node, 'replace')
|
||||
entry._ifwi_replace = fdt_util.GetBool(node, 'ifwi-replace')
|
||||
entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart')
|
||||
entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry')
|
||||
self._ifwi_entries[entry._ifwi_subpart] = entry
|
||||
|
||||
def WriteSymbols(self, section):
|
||||
"""Write symbol values into binary files for access at run time"""
|
||||
for entry in self._ifwi_entries.values():
|
||||
entry.WriteSymbols(self)
|
||||
|
|
|
@ -142,13 +142,19 @@ class Entry_section(Entry):
|
|||
return self.GetEntryContents()
|
||||
|
||||
def GetData(self):
|
||||
section_data = tools.GetBytes(self._pad_byte, self.size)
|
||||
section_data = b''
|
||||
|
||||
for entry in self._entries.values():
|
||||
data = entry.GetData()
|
||||
base = self.pad_before + entry.offset - self._skip_at_start
|
||||
section_data = (section_data[:base] + data +
|
||||
section_data[base + len(data):])
|
||||
base = self.pad_before + (entry.offset or 0) - self._skip_at_start
|
||||
pad = base - len(section_data)
|
||||
if pad > 0:
|
||||
section_data += tools.GetBytes(self._pad_byte, pad)
|
||||
section_data += data
|
||||
if self.size:
|
||||
pad = self.size - len(section_data)
|
||||
if pad > 0:
|
||||
section_data += tools.GetBytes(self._pad_byte, pad)
|
||||
self.Detail('GetData: %d entries, total size %#x' %
|
||||
(len(self._entries), len(section_data)))
|
||||
return section_data
|
||||
|
@ -338,6 +344,8 @@ class Entry_section(Entry):
|
|||
return entry.offset
|
||||
elif prop_name == 'image_pos':
|
||||
return entry.image_pos
|
||||
if prop_name == 'size':
|
||||
return entry.size
|
||||
else:
|
||||
raise ValueError("%s: No such property '%s'" % (msg, prop_name))
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
from entry import Entry
|
||||
from blob_dtb import Entry_blob_dtb
|
||||
import state
|
||||
import tools
|
||||
|
||||
class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
|
||||
|
@ -25,6 +24,10 @@ class Entry_u_boot_dtb_with_ucode(Entry_blob_dtb):
|
|||
it available to u_boot_ucode.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
# Put this here to allow entry-docs and help to work without libfdt
|
||||
global state
|
||||
import state
|
||||
|
||||
Entry_blob_dtb.__init__(self, section, etype, node)
|
||||
self.ucode_data = b''
|
||||
self.collate = False
|
||||
|
|
|
@ -40,4 +40,4 @@ class Entry_u_boot_spl(Entry_blob):
|
|||
return 'spl/u-boot-spl.bin'
|
||||
|
||||
def WriteSymbols(self, section):
|
||||
elf.LookupAndWriteSymbols(self.elf_fname, self, section)
|
||||
elf.LookupAndWriteSymbols(self.elf_fname, self, section.GetImage())
|
||||
|
|
|
@ -40,4 +40,4 @@ class Entry_u_boot_tpl(Entry_blob):
|
|||
return 'tpl/u-boot-tpl.bin'
|
||||
|
||||
def WriteSymbols(self, section):
|
||||
elf.LookupAndWriteSymbols(self.elf_fname, self, section)
|
||||
elf.LookupAndWriteSymbols(self.elf_fname, self, section.GetImage())
|
||||
|
|
29
tools/binman/etype/x86_reset16.py
Normal file
29
tools/binman/etype/x86_reset16.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for the 16-bit x86 reset code for U-Boot
|
||||
#
|
||||
|
||||
from entry import Entry
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_x86_reset16(Entry_blob):
|
||||
"""x86 16-bit reset code for U-Boot
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 64-bit U-Boot, the 'x86_reset16_spl' entry type is used instead.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'u-boot-x86-reset16.bin'
|
29
tools/binman/etype/x86_reset16_spl.py
Normal file
29
tools/binman/etype/x86_reset16_spl.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for the 16-bit x86 reset code for U-Boot
|
||||
#
|
||||
|
||||
from entry import Entry
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_x86_reset16_spl(Entry_blob):
|
||||
"""x86 16-bit reset code for U-Boot
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 32-bit U-Boot, the 'x86_reset_spl' entry type is used instead.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'spl/u-boot-x86-reset16-spl.bin'
|
29
tools/binman/etype/x86_reset16_tpl.py
Normal file
29
tools/binman/etype/x86_reset16_tpl.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
# Copyright (c) 2016 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
#
|
||||
# Entry-type module for the 16-bit x86 reset code for U-Boot
|
||||
#
|
||||
|
||||
from entry import Entry
|
||||
from blob import Entry_blob
|
||||
|
||||
class Entry_x86_reset16_tpl(Entry_blob):
|
||||
"""x86 16-bit reset code for U-Boot
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-reset16.bin (default
|
||||
'u-boot-x86-reset16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_RESET_VEC_LOC. The code is responsible
|
||||
for jumping to the x86-start16 code, which continues execution.
|
||||
|
||||
For 32-bit U-Boot, the 'x86_reset_tpl' entry type is used instead.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'tpl/u-boot-x86-reset16-tpl.bin'
|
|
@ -12,14 +12,15 @@ class Entry_x86_start16(Entry_blob):
|
|||
"""x86 16-bit start-up code for U-Boot
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of u-boot-x86-16bit.bin (default
|
||||
'u-boot-x86-16bit.bin')
|
||||
- filename: Filename of u-boot-x86-start16.bin (default
|
||||
'u-boot-x86-start16.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and jumping to U-Boot's entry point, which
|
||||
requires 32-bit mode (for 32-bit U-Boot).
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
For 64-bit U-Boot, the 'x86_start16_spl' entry type is used instead.
|
||||
"""
|
||||
|
@ -27,4 +28,4 @@ class Entry_x86_start16(Entry_blob):
|
|||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'u-boot-x86-16bit.bin'
|
||||
return 'u-boot-x86-start16.bin'
|
||||
|
|
|
@ -12,19 +12,20 @@ class Entry_x86_start16_spl(Entry_blob):
|
|||
"""x86 16-bit start-up code for SPL
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of spl/u-boot-x86-16bit-spl.bin (default
|
||||
'spl/u-boot-x86-16bit-spl.bin')
|
||||
- filename: Filename of spl/u-boot-x86-start16-spl.bin (default
|
||||
'spl/u-boot-x86-start16-spl.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and starting SPL, which in turn changes to
|
||||
64-bit mode and jumps to U-Boot (for 64-bit U-Boot).
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
For 32-bit U-Boot, the 'x86_start16' entry type is used instead.
|
||||
For 32-bit U-Boot, the 'x86-start16' entry type is used instead.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'spl/u-boot-x86-16bit-spl.bin'
|
||||
return 'spl/u-boot-x86-start16-spl.bin'
|
||||
|
|
|
@ -12,19 +12,21 @@ class Entry_x86_start16_tpl(Entry_blob):
|
|||
"""x86 16-bit start-up code for TPL
|
||||
|
||||
Properties / Entry arguments:
|
||||
- filename: Filename of tpl/u-boot-x86-16bit-tpl.bin (default
|
||||
'tpl/u-boot-x86-16bit-tpl.bin')
|
||||
- filename: Filename of tpl/u-boot-x86-start16-tpl.bin (default
|
||||
'tpl/u-boot-x86-start16-tpl.bin')
|
||||
|
||||
x86 CPUs start up in 16-bit mode, even if they are 64-bit CPUs. This code
|
||||
must be placed at a particular address. This entry holds that code. It is
|
||||
typically placed at offset CONFIG_SYS_X86_START16. The code is responsible
|
||||
for changing to 32-bit mode and starting TPL, which in turn jumps to SPL.
|
||||
x86 CPUs start up in 16-bit mode, even if they are 32-bit CPUs. This code
|
||||
must be placed in the top 64KB of the ROM. The reset code jumps to it. This
|
||||
entry holds that code. It is typically placed at offset
|
||||
CONFIG_SYS_X86_START16. The code is responsible for changing to 32-bit mode
|
||||
and jumping to U-Boot's entry point, which requires 32-bit mode (for 32-bit
|
||||
U-Boot).
|
||||
|
||||
If TPL is not being used, the 'x86_start16_spl or 'x86_start16' entry types
|
||||
If TPL is not being used, the 'x86-start16-spl or 'x86-start16' entry types
|
||||
may be used instead.
|
||||
"""
|
||||
def __init__(self, section, etype, node):
|
||||
Entry_blob.__init__(self, section, etype, node)
|
||||
|
||||
def GetDefaultFilename(self):
|
||||
return 'tpl/u-boot-x86-16bit-tpl.bin'
|
||||
return 'tpl/u-boot-x86-start16-tpl.bin'
|
||||
|
|
|
@ -23,6 +23,7 @@ import cmdline
|
|||
import command
|
||||
import control
|
||||
import elf
|
||||
import elf_test
|
||||
import fdt
|
||||
from etype import fdtmap
|
||||
from etype import image_header
|
||||
|
@ -38,8 +39,8 @@ import tout
|
|||
# Contents of test files, corresponding to different entry types
|
||||
U_BOOT_DATA = b'1234'
|
||||
U_BOOT_IMG_DATA = b'img'
|
||||
U_BOOT_SPL_DATA = b'56780123456789abcde'
|
||||
U_BOOT_TPL_DATA = b'tpl'
|
||||
U_BOOT_SPL_DATA = b'56780123456789abcdefghi'
|
||||
U_BOOT_TPL_DATA = b'tpl9876543210fedcbazyw'
|
||||
BLOB_DATA = b'89'
|
||||
ME_DATA = b'0abcd'
|
||||
VGA_DATA = b'vga'
|
||||
|
@ -49,6 +50,9 @@ U_BOOT_TPL_DTB_DATA = b'tpldtb'
|
|||
X86_START16_DATA = b'start16'
|
||||
X86_START16_SPL_DATA = b'start16spl'
|
||||
X86_START16_TPL_DATA = b'start16tpl'
|
||||
X86_RESET16_DATA = b'reset16'
|
||||
X86_RESET16_SPL_DATA = b'reset16spl'
|
||||
X86_RESET16_TPL_DATA = b'reset16tpl'
|
||||
PPC_MPC85XX_BR_DATA = b'ppcmpc85xxbr'
|
||||
U_BOOT_NODTB_DATA = b'nodtb with microcode pointer somewhere in here'
|
||||
U_BOOT_SPL_NODTB_DATA = b'splnodtb with microcode pointer somewhere in here'
|
||||
|
@ -68,6 +72,7 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " +
|
|||
b"sorry you're alive\n")
|
||||
COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data'
|
||||
REFCODE_DATA = b'refcode'
|
||||
FSP_M_DATA = b'fsp_m'
|
||||
|
||||
# The expected size for the device tree in some tests
|
||||
EXTRACT_DTB_SIZE = 0x3c9
|
||||
|
@ -94,16 +99,16 @@ class TestFunctional(unittest.TestCase):
|
|||
the test/ diurectory.
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
def setUpClass(cls):
|
||||
global entry
|
||||
import entry
|
||||
|
||||
# Handle the case where argv[0] is 'python'
|
||||
self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
self._binman_pathname = os.path.join(self._binman_dir, 'binman')
|
||||
cls._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
cls._binman_pathname = os.path.join(cls._binman_dir, 'binman')
|
||||
|
||||
# Create a temporary directory for input files
|
||||
self._indir = tempfile.mkdtemp(prefix='binmant.')
|
||||
cls._indir = tempfile.mkdtemp(prefix='binmant.')
|
||||
|
||||
# Create some test files
|
||||
TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA)
|
||||
|
@ -113,13 +118,23 @@ class TestFunctional(unittest.TestCase):
|
|||
TestFunctional._MakeInputFile('blobfile', BLOB_DATA)
|
||||
TestFunctional._MakeInputFile('me.bin', ME_DATA)
|
||||
TestFunctional._MakeInputFile('vga.bin', VGA_DATA)
|
||||
self._ResetDtbs()
|
||||
TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA)
|
||||
cls._ResetDtbs()
|
||||
|
||||
TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA)
|
||||
TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin',
|
||||
|
||||
TestFunctional._MakeInputFile('u-boot-x86-start16.bin', X86_START16_DATA)
|
||||
TestFunctional._MakeInputFile('spl/u-boot-x86-start16-spl.bin',
|
||||
X86_START16_SPL_DATA)
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin',
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-x86-start16-tpl.bin',
|
||||
X86_START16_TPL_DATA)
|
||||
|
||||
TestFunctional._MakeInputFile('u-boot-x86-reset16.bin',
|
||||
X86_RESET16_DATA)
|
||||
TestFunctional._MakeInputFile('spl/u-boot-x86-reset16-spl.bin',
|
||||
X86_RESET16_SPL_DATA)
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-x86-reset16-tpl.bin',
|
||||
X86_RESET16_TPL_DATA)
|
||||
|
||||
TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA)
|
||||
TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin',
|
||||
U_BOOT_SPL_NODTB_DATA)
|
||||
|
@ -133,37 +148,41 @@ class TestFunctional(unittest.TestCase):
|
|||
TestFunctional._MakeInputDir('devkeys')
|
||||
TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA)
|
||||
TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA)
|
||||
TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA)
|
||||
|
||||
cls._elf_testdir = os.path.join(cls._indir, 'elftest')
|
||||
elf_test.BuildElfTestFiles(cls._elf_testdir)
|
||||
|
||||
# ELF file with a '_dt_ucode_base_size' symbol
|
||||
with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('u-boot', fd.read())
|
||||
TestFunctional._MakeInputFile('u-boot',
|
||||
tools.ReadFile(cls.ElfTestFile('u_boot_ucode_ptr')))
|
||||
|
||||
# Intel flash descriptor file
|
||||
with open(self.TestFile('descriptor.bin'), 'rb') as fd:
|
||||
with open(cls.TestFile('descriptor.bin'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('descriptor.bin', fd.read())
|
||||
|
||||
shutil.copytree(self.TestFile('files'),
|
||||
os.path.join(self._indir, 'files'))
|
||||
shutil.copytree(cls.TestFile('files'),
|
||||
os.path.join(cls._indir, 'files'))
|
||||
|
||||
TestFunctional._MakeInputFile('compress', COMPRESS_DATA)
|
||||
|
||||
# Travis-CI may have an old lz4
|
||||
self.have_lz4 = True
|
||||
cls.have_lz4 = True
|
||||
try:
|
||||
tools.Run('lz4', '--no-frame-crc', '-c',
|
||||
os.path.join(self._indir, 'u-boot.bin'))
|
||||
os.path.join(cls._indir, 'u-boot.bin'))
|
||||
except:
|
||||
self.have_lz4 = False
|
||||
cls.have_lz4 = False
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
def tearDownClass(cls):
|
||||
"""Remove the temporary input directory and its contents"""
|
||||
if self.preserve_indir:
|
||||
print('Preserving input dir: %s' % self._indir)
|
||||
if cls.preserve_indir:
|
||||
print('Preserving input dir: %s' % cls._indir)
|
||||
else:
|
||||
if self._indir:
|
||||
shutil.rmtree(self._indir)
|
||||
self._indir = None
|
||||
if cls._indir:
|
||||
shutil.rmtree(cls._indir)
|
||||
cls._indir = None
|
||||
|
||||
@classmethod
|
||||
def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False,
|
||||
|
@ -226,7 +245,7 @@ class TestFunctional(unittest.TestCase):
|
|||
return tmpdir, updated_fname
|
||||
|
||||
@classmethod
|
||||
def _ResetDtbs(self):
|
||||
def _ResetDtbs(cls):
|
||||
TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA)
|
||||
TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA)
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA)
|
||||
|
@ -432,7 +451,7 @@ class TestFunctional(unittest.TestCase):
|
|||
return self._DoReadFileDtb(fname, use_real_dtb)[0]
|
||||
|
||||
@classmethod
|
||||
def _MakeInputFile(self, fname, contents):
|
||||
def _MakeInputFile(cls, fname, contents):
|
||||
"""Create a new test input file, creating directories as needed
|
||||
|
||||
Args:
|
||||
|
@ -441,7 +460,7 @@ class TestFunctional(unittest.TestCase):
|
|||
Returns:
|
||||
Full pathname of file created
|
||||
"""
|
||||
pathname = os.path.join(self._indir, fname)
|
||||
pathname = os.path.join(cls._indir, fname)
|
||||
dirname = os.path.dirname(pathname)
|
||||
if dirname and not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
@ -450,7 +469,7 @@ class TestFunctional(unittest.TestCase):
|
|||
return pathname
|
||||
|
||||
@classmethod
|
||||
def _MakeInputDir(self, dirname):
|
||||
def _MakeInputDir(cls, dirname):
|
||||
"""Create a new test input directory, creating directories as needed
|
||||
|
||||
Args:
|
||||
|
@ -459,24 +478,38 @@ class TestFunctional(unittest.TestCase):
|
|||
Returns:
|
||||
Full pathname of directory created
|
||||
"""
|
||||
pathname = os.path.join(self._indir, dirname)
|
||||
pathname = os.path.join(cls._indir, dirname)
|
||||
if not os.path.exists(pathname):
|
||||
os.makedirs(pathname)
|
||||
return pathname
|
||||
|
||||
@classmethod
|
||||
def _SetupSplElf(self, src_fname='bss_data'):
|
||||
def _SetupSplElf(cls, src_fname='bss_data'):
|
||||
"""Set up an ELF file with a '_dt_ucode_base_size' symbol
|
||||
|
||||
Args:
|
||||
Filename of ELF file to use as SPL
|
||||
"""
|
||||
with open(self.TestFile(src_fname), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
|
||||
TestFunctional._MakeInputFile('spl/u-boot-spl',
|
||||
tools.ReadFile(cls.ElfTestFile(src_fname)))
|
||||
|
||||
@classmethod
|
||||
def TestFile(self, fname):
|
||||
return os.path.join(self._binman_dir, 'test', fname)
|
||||
def _SetupTplElf(cls, src_fname='bss_data'):
|
||||
"""Set up an ELF file with a '_dt_ucode_base_size' symbol
|
||||
|
||||
Args:
|
||||
Filename of ELF file to use as TPL
|
||||
"""
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-tpl',
|
||||
tools.ReadFile(cls.ElfTestFile(src_fname)))
|
||||
|
||||
@classmethod
|
||||
def TestFile(cls, fname):
|
||||
return os.path.join(cls._binman_dir, 'test', fname)
|
||||
|
||||
@classmethod
|
||||
def ElfTestFile(cls, fname):
|
||||
return os.path.join(cls._elf_testdir, fname)
|
||||
|
||||
def AssertInList(self, grep_list, target):
|
||||
"""Assert that at least one of a list of things is in a target
|
||||
|
@ -875,7 +908,7 @@ class TestFunctional(unittest.TestCase):
|
|||
"""Test that the end-at-4gb and skip-at-size property can't be used
|
||||
together"""
|
||||
with self.assertRaises(ValueError) as e:
|
||||
self._DoTestFile('80_4gb_and_skip_at_start_together.dts')
|
||||
self._DoTestFile('098_4gb_and_skip_at_start_together.dts')
|
||||
self.assertIn("Image '/binman': Provide either 'end-at-4gb' or "
|
||||
"'skip-at-start'", str(e.exception))
|
||||
|
||||
|
@ -890,29 +923,29 @@ class TestFunctional(unittest.TestCase):
|
|||
def testPackX86Rom(self):
|
||||
"""Test that a basic x86 ROM can be created"""
|
||||
self._SetupSplElf()
|
||||
data = self._DoReadFile('029_x86-rom.dts')
|
||||
self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA +
|
||||
data = self._DoReadFile('029_x86_rom.dts')
|
||||
self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 3) + U_BOOT_SPL_DATA +
|
||||
tools.GetBytes(0, 2), data)
|
||||
|
||||
def testPackX86RomMeNoDesc(self):
|
||||
"""Test that an invalid Intel descriptor entry is detected"""
|
||||
TestFunctional._MakeInputFile('descriptor.bin', b'')
|
||||
with self.assertRaises(ValueError) as e:
|
||||
self._DoTestFile('031_x86-rom-me.dts')
|
||||
self._DoTestFile('031_x86_rom_me.dts')
|
||||
self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature",
|
||||
str(e.exception))
|
||||
|
||||
def testPackX86RomBadDesc(self):
|
||||
"""Test that the Intel requires a descriptor entry"""
|
||||
with self.assertRaises(ValueError) as e:
|
||||
self._DoTestFile('030_x86-rom-me-no-desc.dts')
|
||||
self._DoTestFile('030_x86_rom_me_no_desc.dts')
|
||||
self.assertIn("Node '/binman/intel-me': No offset set with "
|
||||
"offset-unset: should another entry provide this correct "
|
||||
"offset?", str(e.exception))
|
||||
|
||||
def testPackX86RomMe(self):
|
||||
"""Test that an x86 ROM with an ME region can be created"""
|
||||
data = self._DoReadFile('031_x86-rom-me.dts')
|
||||
data = self._DoReadFile('031_x86_rom_me.dts')
|
||||
expected_desc = tools.ReadFile(self.TestFile('descriptor.bin'))
|
||||
if data[:0x1000] != expected_desc:
|
||||
self.fail('Expected descriptor binary at start of image')
|
||||
|
@ -920,18 +953,18 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testPackVga(self):
|
||||
"""Test that an image with a VGA binary can be created"""
|
||||
data = self._DoReadFile('032_intel-vga.dts')
|
||||
data = self._DoReadFile('032_intel_vga.dts')
|
||||
self.assertEqual(VGA_DATA, data[:len(VGA_DATA)])
|
||||
|
||||
def testPackStart16(self):
|
||||
"""Test that an image with an x86 start16 region can be created"""
|
||||
data = self._DoReadFile('033_x86-start16.dts')
|
||||
data = self._DoReadFile('033_x86_start16.dts')
|
||||
self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)])
|
||||
|
||||
def testPackPowerpcMpc85xxBootpgResetvec(self):
|
||||
"""Test that an image with powerpc-mpc85xx-bootpg-resetvec can be
|
||||
created"""
|
||||
data = self._DoReadFile('81_powerpc_mpc85xx_bootpg_resetvec.dts')
|
||||
data = self._DoReadFile('150_powerpc_mpc85xx_bootpg_resetvec.dts')
|
||||
self.assertEqual(PPC_MPC85XX_BR_DATA, data[:len(PPC_MPC85XX_BR_DATA)])
|
||||
|
||||
def _RunMicrocodeTest(self, dts_fname, nodtb_data, ucode_second=False):
|
||||
|
@ -1066,8 +1099,8 @@ class TestFunctional(unittest.TestCase):
|
|||
"""Test that a U-Boot binary without the microcode symbol is detected"""
|
||||
# ELF file without a '_dt_ucode_base_size' symbol
|
||||
try:
|
||||
with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('u-boot', fd.read())
|
||||
TestFunctional._MakeInputFile('u-boot',
|
||||
tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr')))
|
||||
|
||||
with self.assertRaises(ValueError) as e:
|
||||
self._RunPackUbootSingleMicrocode()
|
||||
|
@ -1076,8 +1109,8 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
finally:
|
||||
# Put the original file back
|
||||
with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('u-boot', fd.read())
|
||||
TestFunctional._MakeInputFile('u-boot',
|
||||
tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr')))
|
||||
|
||||
def testMicrocodeNotInImage(self):
|
||||
"""Test that microcode must be placed within the image"""
|
||||
|
@ -1089,8 +1122,8 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testWithoutMicrocode(self):
|
||||
"""Test that we can cope with an image without microcode (e.g. qemu)"""
|
||||
with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('u-boot', fd.read())
|
||||
TestFunctional._MakeInputFile('u-boot',
|
||||
tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr')))
|
||||
data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True)
|
||||
|
||||
# Now check the device tree has no microcode
|
||||
|
@ -1113,17 +1146,17 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testPackFsp(self):
|
||||
"""Test that an image with a FSP binary can be created"""
|
||||
data = self._DoReadFile('042_intel-fsp.dts')
|
||||
data = self._DoReadFile('042_intel_fsp.dts')
|
||||
self.assertEqual(FSP_DATA, data[:len(FSP_DATA)])
|
||||
|
||||
def testPackCmc(self):
|
||||
"""Test that an image with a CMC binary can be created"""
|
||||
data = self._DoReadFile('043_intel-cmc.dts')
|
||||
data = self._DoReadFile('043_intel_cmc.dts')
|
||||
self.assertEqual(CMC_DATA, data[:len(CMC_DATA)])
|
||||
|
||||
def testPackVbt(self):
|
||||
"""Test that an image with a VBT binary can be created"""
|
||||
data = self._DoReadFile('046_intel-vbt.dts')
|
||||
data = self._DoReadFile('046_intel_vbt.dts')
|
||||
self.assertEqual(VBT_DATA, data[:len(VBT_DATA)])
|
||||
|
||||
def testSplBssPad(self):
|
||||
|
@ -1144,7 +1177,7 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testPackStart16Spl(self):
|
||||
"""Test that an image with an x86 start16 SPL region can be created"""
|
||||
data = self._DoReadFile('048_x86-start16-spl.dts')
|
||||
data = self._DoReadFile('048_x86_start16_spl.dts')
|
||||
self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)])
|
||||
|
||||
def _PackUbootSplMicrocode(self, dts, ucode_second=False):
|
||||
|
@ -1198,17 +1231,17 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testSymbols(self):
|
||||
"""Test binman can assign symbols embedded in U-Boot"""
|
||||
elf_fname = self.TestFile('u_boot_binman_syms')
|
||||
elf_fname = self.ElfTestFile('u_boot_binman_syms')
|
||||
syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
|
||||
addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start')
|
||||
self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr)
|
||||
|
||||
self._SetupSplElf('u_boot_binman_syms')
|
||||
data = self._DoReadFile('053_symbols.dts')
|
||||
sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20)
|
||||
expected = (sym_values + U_BOOT_SPL_DATA[16:] +
|
||||
sym_values = struct.pack('<LQLL', 0, 28, 24, 4)
|
||||
expected = (sym_values + U_BOOT_SPL_DATA[20:] +
|
||||
tools.GetBytes(0xff, 1) + U_BOOT_DATA + sym_values +
|
||||
U_BOOT_SPL_DATA[16:])
|
||||
U_BOOT_SPL_DATA[20:])
|
||||
self.assertEqual(expected, data)
|
||||
|
||||
def testPackUnitAddress(self):
|
||||
|
@ -1536,10 +1569,9 @@ class TestFunctional(unittest.TestCase):
|
|||
"'other'", str(e.exception))
|
||||
|
||||
def testTpl(self):
|
||||
"""Test that an image with TPL and ots device tree can be created"""
|
||||
"""Test that an image with TPL and its device tree can be created"""
|
||||
# ELF file with a '__bss_size' symbol
|
||||
with open(self.TestFile('bss_data'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
|
||||
self._SetupTplElf()
|
||||
data = self._DoReadFile('078_u_boot_tpl.dts')
|
||||
self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data)
|
||||
|
||||
|
@ -1564,7 +1596,7 @@ class TestFunctional(unittest.TestCase):
|
|||
|
||||
def testPackStart16Tpl(self):
|
||||
"""Test that an image with an x86 start16 TPL region can be created"""
|
||||
data = self._DoReadFile('081_x86-start16-tpl.dts')
|
||||
data = self._DoReadFile('081_x86_start16_tpl.dts')
|
||||
self.assertEqual(X86_START16_TPL_DATA, data[:len(X86_START16_TPL_DATA)])
|
||||
|
||||
def testSelectImage(self):
|
||||
|
@ -1636,8 +1668,6 @@ class TestFunctional(unittest.TestCase):
|
|||
# source file (e.g. test/075_fdt_update_all.dts) thus does not enter
|
||||
# binman as a file called u-boot.dtb. To fix this, copy the file
|
||||
# over to the expected place.
|
||||
#tools.WriteFile(os.path.join(self._indir, 'u-boot.dtb'),
|
||||
#tools.ReadFile(tools.GetOutputFilename('source.dtb')))
|
||||
start = 0
|
||||
for fname in ['u-boot.dtb.out', 'spl/u-boot-spl.dtb.out',
|
||||
'tpl/u-boot-tpl.dtb.out']:
|
||||
|
@ -1793,8 +1823,7 @@ class TestFunctional(unittest.TestCase):
|
|||
u-boot-tpl.dtb with the microcode removed
|
||||
the microcode
|
||||
"""
|
||||
with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
|
||||
self._SetupTplElf('u_boot_ucode_ptr')
|
||||
first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts',
|
||||
U_BOOT_TPL_NODTB_DATA)
|
||||
self.assertEqual(b'tplnodtb with microc' + pos_and_size +
|
||||
|
@ -1848,16 +1877,15 @@ class TestFunctional(unittest.TestCase):
|
|||
def testElf(self):
|
||||
"""Basic test of ELF entries"""
|
||||
self._SetupSplElf()
|
||||
with open(self.TestFile('bss_data'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
|
||||
with open(self.TestFile('bss_data'), 'rb') as fd:
|
||||
self._SetupTplElf()
|
||||
with open(self.ElfTestFile('bss_data'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('-boot', fd.read())
|
||||
data = self._DoReadFile('096_elf.dts')
|
||||
|
||||
def testElfStrip(self):
|
||||
"""Basic test of ELF entries"""
|
||||
self._SetupSplElf()
|
||||
with open(self.TestFile('bss_data'), 'rb') as fd:
|
||||
with open(self.ElfTestFile('bss_data'), 'rb') as fd:
|
||||
TestFunctional._MakeInputFile('-boot', fd.read())
|
||||
data = self._DoReadFile('097_elf_strip.dts')
|
||||
|
||||
|
@ -2008,6 +2036,7 @@ class TestFunctional(unittest.TestCase):
|
|||
fname: Filename of input file to provide (fitimage.bin or ifwi.bin)
|
||||
"""
|
||||
self._SetupSplElf()
|
||||
self._SetupTplElf()
|
||||
|
||||
# Intel Integrated Firmware Image (IFWI) file
|
||||
with gzip.open(self.TestFile('%s.gz' % fname), 'rb') as fd:
|
||||
|
@ -2031,25 +2060,25 @@ class TestFunctional(unittest.TestCase):
|
|||
subpart='IBBP', entry_name='IBBL')
|
||||
|
||||
tpl_data = tools.ReadFile(tpl_fname)
|
||||
self.assertEqual(tpl_data[:len(U_BOOT_TPL_DATA)], U_BOOT_TPL_DATA)
|
||||
self.assertEqual(U_BOOT_TPL_DATA, tpl_data[:len(U_BOOT_TPL_DATA)])
|
||||
|
||||
def testPackX86RomIfwi(self):
|
||||
"""Test that an x86 ROM with Integrated Firmware Image can be created"""
|
||||
self._SetupIfwi('fitimage.bin')
|
||||
data = self._DoReadFile('111_x86-rom-ifwi.dts')
|
||||
data = self._DoReadFile('111_x86_rom_ifwi.dts')
|
||||
self._CheckIfwi(data)
|
||||
|
||||
def testPackX86RomIfwiNoDesc(self):
|
||||
"""Test that an x86 ROM with IFWI can be created from an ifwi.bin file"""
|
||||
self._SetupIfwi('ifwi.bin')
|
||||
data = self._DoReadFile('112_x86-rom-ifwi-nodesc.dts')
|
||||
data = self._DoReadFile('112_x86_rom_ifwi_nodesc.dts')
|
||||
self._CheckIfwi(data)
|
||||
|
||||
def testPackX86RomIfwiNoData(self):
|
||||
"""Test that an x86 ROM with IFWI handles missing data"""
|
||||
self._SetupIfwi('ifwi.bin')
|
||||
with self.assertRaises(ValueError) as e:
|
||||
data = self._DoReadFile('113_x86-rom-ifwi-nodata.dts')
|
||||
data = self._DoReadFile('113_x86_rom_ifwi_nodata.dts')
|
||||
self.assertIn('Could not complete processing of contents',
|
||||
str(e.exception))
|
||||
|
||||
|
@ -3236,6 +3265,74 @@ class TestFunctional(unittest.TestCase):
|
|||
self.assertIn('Must specify exactly one entry path to write with -f',
|
||||
str(e.exception))
|
||||
|
||||
def testPackReset16(self):
|
||||
"""Test that an image with an x86 reset16 region can be created"""
|
||||
data = self._DoReadFile('144_x86_reset16.dts')
|
||||
self.assertEqual(X86_RESET16_DATA, data[:len(X86_RESET16_DATA)])
|
||||
|
||||
def testPackReset16Spl(self):
|
||||
"""Test that an image with an x86 reset16-spl region can be created"""
|
||||
data = self._DoReadFile('145_x86_reset16_spl.dts')
|
||||
self.assertEqual(X86_RESET16_SPL_DATA, data[:len(X86_RESET16_SPL_DATA)])
|
||||
|
||||
def testPackReset16Tpl(self):
|
||||
"""Test that an image with an x86 reset16-tpl region can be created"""
|
||||
data = self._DoReadFile('146_x86_reset16_tpl.dts')
|
||||
self.assertEqual(X86_RESET16_TPL_DATA, data[:len(X86_RESET16_TPL_DATA)])
|
||||
|
||||
def testPackIntelFit(self):
|
||||
"""Test that an image with an Intel FIT and pointer can be created"""
|
||||
data = self._DoReadFile('147_intel_fit.dts')
|
||||
self.assertEqual(U_BOOT_DATA, data[:len(U_BOOT_DATA)])
|
||||
fit = data[16:32];
|
||||
self.assertEqual(b'_FIT_ \x01\x00\x00\x00\x00\x01\x80}' , fit)
|
||||
ptr = struct.unpack('<i', data[0x40:0x44])[0]
|
||||
|
||||
image = control.images['image']
|
||||
entries = image.GetEntries()
|
||||
expected_ptr = entries['intel-fit'].image_pos - (1 << 32)
|
||||
self.assertEqual(expected_ptr, ptr)
|
||||
|
||||
def testPackIntelFitMissing(self):
|
||||
"""Test detection of a FIT pointer with not FIT region"""
|
||||
with self.assertRaises(ValueError) as e:
|
||||
self._DoReadFile('148_intel_fit_missing.dts')
|
||||
self.assertIn("'intel-fit-ptr' section must have an 'intel-fit' sibling",
|
||||
str(e.exception))
|
||||
|
||||
def testSymbolsTplSection(self):
|
||||
"""Test binman can assign symbols embedded in U-Boot TPL in a section"""
|
||||
self._SetupSplElf('u_boot_binman_syms')
|
||||
self._SetupTplElf('u_boot_binman_syms')
|
||||
data = self._DoReadFile('149_symbols_tpl.dts')
|
||||
sym_values = struct.pack('<LQLL', 4, 0x1c, 0x34, 4)
|
||||
upto1 = 4 + len(U_BOOT_SPL_DATA)
|
||||
expected1 = tools.GetBytes(0xff, 4) + sym_values + U_BOOT_SPL_DATA[20:]
|
||||
self.assertEqual(expected1, data[:upto1])
|
||||
|
||||
upto2 = upto1 + 1 + len(U_BOOT_SPL_DATA)
|
||||
expected2 = tools.GetBytes(0xff, 1) + sym_values + U_BOOT_SPL_DATA[20:]
|
||||
self.assertEqual(expected2, data[upto1:upto2])
|
||||
|
||||
upto3 = 0x34 + len(U_BOOT_DATA)
|
||||
expected3 = tools.GetBytes(0xff, 1) + U_BOOT_DATA
|
||||
self.assertEqual(expected3, data[upto2:upto3])
|
||||
|
||||
expected4 = sym_values + U_BOOT_TPL_DATA[20:]
|
||||
self.assertEqual(expected4, data[upto3:])
|
||||
|
||||
def testPackX86RomIfwiSectiom(self):
|
||||
"""Test that a section can be placed in an IFWI region"""
|
||||
self._SetupIfwi('fitimage.bin')
|
||||
data = self._DoReadFile('151_x86_rom_ifwi_section.dts')
|
||||
self._CheckIfwi(data)
|
||||
|
||||
def testPackFspM(self):
|
||||
"""Test that an image with a FSP memory-init binary can be created"""
|
||||
data = self._DoReadFile('152_intel_fsp_m.dts')
|
||||
self.assertEqual(FSP_M_DATA, data[:len(FSP_M_DATA)])
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
};
|
||||
|
||||
u-boot {
|
||||
offset = <20>;
|
||||
offset = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
binman {
|
||||
sort-by-offset;
|
||||
u-boot {
|
||||
offset = <22>;
|
||||
offset = <26>;
|
||||
};
|
||||
|
||||
u-boot-spl {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
};
|
||||
|
||||
u-boot-spl {
|
||||
offset = <0xffffffeb>;
|
||||
offset = <0xffffffe7>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
};
|
||||
|
||||
u-boot-spl {
|
||||
offset = <0xffffffeb>;
|
||||
offset = <0xffffffe7>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -10,7 +10,7 @@
|
|||
};
|
||||
|
||||
u-boot {
|
||||
offset = <20>;
|
||||
offset = <24>;
|
||||
};
|
||||
|
||||
u-boot-spl2 {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
convert-fit;
|
||||
|
||||
u-boot-tpl {
|
||||
replace;
|
||||
ifwi-replace;
|
||||
ifwi-subpart = "IBBP";
|
||||
ifwi-entry = "IBBL";
|
||||
};
|
|
@ -19,7 +19,7 @@
|
|||
filename = "ifwi.bin";
|
||||
|
||||
u-boot-tpl {
|
||||
replace;
|
||||
ifwi-replace;
|
||||
ifwi-subpart = "IBBP";
|
||||
ifwi-entry = "IBBL";
|
||||
};
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
_testing {
|
||||
return-unknown-contents;
|
||||
replace;
|
||||
ifwi-replace;
|
||||
ifwi-subpart = "IBBP";
|
||||
ifwi-entry = "IBBL";
|
||||
};
|
13
tools/binman/test/144_x86_reset16.dts
Normal file
13
tools/binman/test/144_x86_reset16.dts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
size = <16>;
|
||||
|
||||
x86-reset16 {
|
||||
};
|
||||
};
|
||||
};
|
13
tools/binman/test/145_x86_reset16_spl.dts
Normal file
13
tools/binman/test/145_x86_reset16_spl.dts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
size = <16>;
|
||||
|
||||
x86-reset16-spl {
|
||||
};
|
||||
};
|
||||
};
|
13
tools/binman/test/146_x86_reset16_tpl.dts
Normal file
13
tools/binman/test/146_x86_reset16_tpl.dts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
size = <16>;
|
||||
|
||||
x86-reset16-tpl {
|
||||
};
|
||||
};
|
||||
};
|
20
tools/binman/test/147_intel_fit.dts
Normal file
20
tools/binman/test/147_intel_fit.dts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
end-at-4gb;
|
||||
size = <0x80>;
|
||||
|
||||
u-boot {
|
||||
};
|
||||
|
||||
intel-fit {
|
||||
};
|
||||
|
||||
intel-fit-ptr {
|
||||
};
|
||||
};
|
||||
};
|
17
tools/binman/test/148_intel_fit_missing.dts
Normal file
17
tools/binman/test/148_intel_fit_missing.dts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
end-at-4gb;
|
||||
size = <0x80>;
|
||||
|
||||
u-boot {
|
||||
};
|
||||
|
||||
intel-fit-ptr {
|
||||
};
|
||||
};
|
||||
};
|
28
tools/binman/test/149_symbols_tpl.dts
Normal file
28
tools/binman/test/149_symbols_tpl.dts
Normal file
|
@ -0,0 +1,28 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
pad-byte = <0xff>;
|
||||
u-boot-spl {
|
||||
offset = <4>;
|
||||
};
|
||||
|
||||
u-boot-spl2 {
|
||||
offset = <0x1c>;
|
||||
type = "u-boot-spl";
|
||||
};
|
||||
|
||||
u-boot {
|
||||
offset = <0x34>;
|
||||
};
|
||||
|
||||
section {
|
||||
u-boot-tpl {
|
||||
type = "u-boot-tpl";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
33
tools/binman/test/151_x86_rom_ifwi_section.dts
Normal file
33
tools/binman/test/151_x86_rom_ifwi_section.dts
Normal file
|
@ -0,0 +1,33 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
sort-by-offset;
|
||||
end-at-4gb;
|
||||
size = <0x800000>;
|
||||
intel-descriptor {
|
||||
filename = "descriptor.bin";
|
||||
};
|
||||
|
||||
intel-ifwi {
|
||||
offset-unset;
|
||||
filename = "fitimage.bin";
|
||||
convert-fit;
|
||||
|
||||
section {
|
||||
ifwi-replace;
|
||||
ifwi-subpart = "IBBP";
|
||||
ifwi-entry = "IBBL";
|
||||
u-boot-tpl {
|
||||
};
|
||||
u-boot-dtb {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
14
tools/binman/test/152_intel_fsp_m.dts
Normal file
14
tools/binman/test/152_intel_fsp_m.dts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
size = <16>;
|
||||
|
||||
intel-fsp-m {
|
||||
filename = "fsp_m.bin";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Builds test programs
|
||||
# Builds test programs. This is launched from elf_test.BuildElfTestFiles()
|
||||
#
|
||||
# Copyright (C) 2017 Google, Inc
|
||||
# Written by Simon Glass <sjg@chromium.org>
|
||||
|
@ -7,11 +7,13 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
CFLAGS := -march=i386 -m32 -nostdlib -I ../../../include
|
||||
VPATH := $(SRC)
|
||||
CFLAGS := -march=i386 -m32 -nostdlib -I $(SRC)../../../include \
|
||||
-Wl,--no-dynamic-linker
|
||||
|
||||
LDS_UCODE := -T u_boot_ucode_ptr.lds
|
||||
LDS_BINMAN := -T u_boot_binman_syms.lds
|
||||
LDS_BINMAN_BAD := -T u_boot_binman_syms_bad.lds
|
||||
LDS_UCODE := -T $(SRC)u_boot_ucode_ptr.lds
|
||||
LDS_BINMAN := -T $(SRC)u_boot_binman_syms.lds
|
||||
LDS_BINMAN_BAD := -T $(SRC)u_boot_binman_syms_bad.lds
|
||||
|
||||
TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data \
|
||||
u_boot_binman_syms u_boot_binman_syms.bin u_boot_binman_syms_bad \
|
||||
|
@ -25,7 +27,7 @@ u_boot_no_ucode_ptr: u_boot_no_ucode_ptr.c
|
|||
u_boot_ucode_ptr: CFLAGS += $(LDS_UCODE)
|
||||
u_boot_ucode_ptr: u_boot_ucode_ptr.c
|
||||
|
||||
bss_data: CFLAGS += bss_data.lds
|
||||
bss_data: CFLAGS += $(SRC)bss_data.lds
|
||||
bss_data: bss_data.c
|
||||
|
||||
u_boot_binman_syms.bin: u_boot_binman_syms
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -11,3 +11,4 @@
|
|||
binman_sym_declare(unsigned long, u_boot_spl, offset);
|
||||
binman_sym_declare(unsigned long long, u_boot_spl2, offset);
|
||||
binman_sym_declare(unsigned long, u_boot_any, image_pos);
|
||||
binman_sym_declare(unsigned long, u_boot_any, size);
|
||||
|
|
|
@ -25,5 +25,6 @@ SECTIONS
|
|||
KEEP(*(SORT(.binman_sym*)));
|
||||
__binman_sym_end = .;
|
||||
}
|
||||
.interp : { *(.interp*) }
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,9 +9,10 @@ ENTRY(_start)
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0xfffffdf0;
|
||||
. = 0xfffffe14;
|
||||
_start = .;
|
||||
.ucode : {
|
||||
*(.ucode)
|
||||
}
|
||||
.interp : { *(.interp*) }
|
||||
}
|
||||
|
|
|
@ -259,12 +259,18 @@ Series-process-log: sort, uniq
|
|||
unique entries. If omitted, no change log processing is done.
|
||||
Separate each tag with a comma.
|
||||
|
||||
Change-Id:
|
||||
This tag is stripped out but is used to generate the Message-Id
|
||||
of the emails that will be sent. When you keep the Change-Id the
|
||||
same you are asserting that this is a slightly different version
|
||||
(but logically the same patch) as other patches that have been
|
||||
sent out with the same Change-Id.
|
||||
|
||||
Various other tags are silently removed, like these Chrome OS and
|
||||
Gerrit tags:
|
||||
|
||||
BUG=...
|
||||
TEST=...
|
||||
Change-Id:
|
||||
Review URL:
|
||||
Reviewed-on:
|
||||
Commit-xxxx: (except Commit-notes)
|
||||
|
|
|
@ -21,6 +21,8 @@ class Commit:
|
|||
The dict is indexed by change version (an integer)
|
||||
cc_list: List of people to aliases/emails to cc on this commit
|
||||
notes: List of lines in the commit (not series) notes
|
||||
change_id: the Change-Id: tag that was stripped from this commit
|
||||
and can be used to generate the Message-Id.
|
||||
"""
|
||||
def __init__(self, hash):
|
||||
self.hash = hash
|
||||
|
@ -30,6 +32,7 @@ class Commit:
|
|||
self.cc_list = []
|
||||
self.signoff_set = set()
|
||||
self.notes = []
|
||||
self.change_id = None
|
||||
|
||||
def AddChange(self, version, info):
|
||||
"""Add a new change line to the change list for a version.
|
||||
|
|
|
@ -54,7 +54,7 @@ class Popen(subprocess.Popen):
|
|||
"""
|
||||
|
||||
def __init__(self, args, stdin=None, stdout=PIPE_PTY, stderr=PIPE_PTY,
|
||||
shell=False, cwd=None, env=None, binary=False, **kwargs):
|
||||
shell=False, cwd=None, env=None, **kwargs):
|
||||
"""Cut-down constructor
|
||||
|
||||
Args:
|
||||
|
@ -72,7 +72,6 @@ class Popen(subprocess.Popen):
|
|||
"""
|
||||
stdout_pty = None
|
||||
stderr_pty = None
|
||||
self.binary = binary
|
||||
|
||||
if stdout == PIPE_PTY:
|
||||
stdout_pty = pty.openpty()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# Copyright (c) 2011 The Chromium OS Authors.
|
||||
#
|
||||
|
||||
import datetime
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
|
@ -14,7 +15,7 @@ import gitutil
|
|||
from series import Series
|
||||
|
||||
# Tags that we detect and remove
|
||||
re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Change-Id:|^Review URL:'
|
||||
re_remove = re.compile('^BUG=|^TEST=|^BRANCH=|^Review URL:'
|
||||
'|Reviewed-on:|Commit-\w*:')
|
||||
|
||||
# Lines which are allowed after a TEST= line
|
||||
|
@ -32,6 +33,9 @@ re_cover_cc = re.compile('^Cover-letter-cc: *(.*)')
|
|||
# Patch series tag
|
||||
re_series_tag = re.compile('^Series-([a-z-]*): *(.*)')
|
||||
|
||||
# Change-Id will be used to generate the Message-Id and then be stripped
|
||||
re_change_id = re.compile('^Change-Id: *(.*)')
|
||||
|
||||
# Commit series tag
|
||||
re_commit_tag = re.compile('^Commit-([a-z-]*): *(.*)')
|
||||
|
||||
|
@ -156,6 +160,7 @@ class PatchStream:
|
|||
|
||||
# Handle state transition and skipping blank lines
|
||||
series_tag_match = re_series_tag.match(line)
|
||||
change_id_match = re_change_id.match(line)
|
||||
commit_tag_match = re_commit_tag.match(line)
|
||||
cover_match = re_cover.match(line)
|
||||
cover_cc_match = re_cover_cc.match(line)
|
||||
|
@ -177,7 +182,7 @@ class PatchStream:
|
|||
self.state = STATE_MSG_HEADER
|
||||
|
||||
# If a tag is detected, or a new commit starts
|
||||
if series_tag_match or commit_tag_match or \
|
||||
if series_tag_match or commit_tag_match or change_id_match or \
|
||||
cover_match or cover_cc_match or signoff_match or \
|
||||
self.state == STATE_MSG_HEADER:
|
||||
# but we are already in a section, this means 'END' is missing
|
||||
|
@ -275,6 +280,16 @@ class PatchStream:
|
|||
self.AddToSeries(line, name, value)
|
||||
self.skip_blank = True
|
||||
|
||||
# Detect Change-Id tags
|
||||
elif change_id_match:
|
||||
value = change_id_match.group(1)
|
||||
if self.is_log:
|
||||
if self.commit.change_id:
|
||||
raise ValueError("%s: Two Change-Ids: '%s' vs. '%s'" %
|
||||
(self.commit.hash, self.commit.change_id, value))
|
||||
self.commit.change_id = value
|
||||
self.skip_blank = True
|
||||
|
||||
# Detect Commit-xxx tags
|
||||
elif commit_tag_match:
|
||||
name = commit_tag_match.group(1)
|
||||
|
@ -345,6 +360,47 @@ class PatchStream:
|
|||
self.warn.append('Found %d lines after TEST=' %
|
||||
self.lines_after_test)
|
||||
|
||||
def WriteMessageId(self, outfd):
|
||||
"""Write the Message-Id into the output.
|
||||
|
||||
This is based on the Change-Id in the original patch, the version,
|
||||
and the prefix.
|
||||
|
||||
Args:
|
||||
outfd: Output stream file object
|
||||
"""
|
||||
if not self.commit.change_id:
|
||||
return
|
||||
|
||||
# If the count is -1 we're testing, so use a fixed time
|
||||
if self.commit.count == -1:
|
||||
time_now = datetime.datetime(1999, 12, 31, 23, 59, 59)
|
||||
else:
|
||||
time_now = datetime.datetime.now()
|
||||
|
||||
# In theory there is email.utils.make_msgid() which would be nice
|
||||
# to use, but it already produces something way too long and thus
|
||||
# will produce ugly commit lines if someone throws this into
|
||||
# a "Link:" tag in the final commit. So (sigh) roll our own.
|
||||
|
||||
# Start with the time; presumably we wouldn't send the same series
|
||||
# with the same Change-Id at the exact same second.
|
||||
parts = [time_now.strftime("%Y%m%d%H%M%S")]
|
||||
|
||||
# These seem like they would be nice to include.
|
||||
if 'prefix' in self.series:
|
||||
parts.append(self.series['prefix'])
|
||||
if 'version' in self.series:
|
||||
parts.append("v%s" % self.series['version'])
|
||||
|
||||
parts.append(str(self.commit.count + 1))
|
||||
|
||||
# The Change-Id must be last, right before the @
|
||||
parts.append(self.commit.change_id)
|
||||
|
||||
# Join parts together with "." and write it out.
|
||||
outfd.write('Message-Id: <%s@changeid>\n' % '.'.join(parts))
|
||||
|
||||
def ProcessStream(self, infd, outfd):
|
||||
"""Copy a stream from infd to outfd, filtering out unwanting things.
|
||||
|
||||
|
@ -358,6 +414,9 @@ class PatchStream:
|
|||
fname = None
|
||||
last_fname = None
|
||||
re_fname = re.compile('diff --git a/(.*) b/.*')
|
||||
|
||||
self.WriteMessageId(outfd)
|
||||
|
||||
while True:
|
||||
line = infd.readline()
|
||||
if not line:
|
||||
|
@ -481,6 +540,7 @@ def FixPatches(series, fnames):
|
|||
for fname in fnames:
|
||||
commit = series.commits[count]
|
||||
commit.patch = fname
|
||||
commit.count = count
|
||||
result = FixPatch(backup_dir, fname, series, commit)
|
||||
if result:
|
||||
print('%d warnings for %s:' % (len(result), fname))
|
||||
|
|
|
@ -12,6 +12,7 @@ import checkpatch
|
|||
import gitutil
|
||||
import patchstream
|
||||
import series
|
||||
import commit
|
||||
|
||||
|
||||
class TestPatch(unittest.TestCase):
|
||||
|
@ -48,7 +49,8 @@ Signed-off-by: Simon Glass <sjg@chromium.org>
|
|||
arch/arm/cpu/armv7/tegra2/ap20.c | 57 ++----
|
||||
arch/arm/cpu/armv7/tegra2/clock.c | 163 +++++++++++++++++
|
||||
'''
|
||||
expected='''
|
||||
expected='''Message-Id: <19991231235959.0.I80fe1d0c0b7dd10aa58ce5bb1d9290b6664d5413@changeid>
|
||||
|
||||
|
||||
From 656c9a8c31fa65859d924cd21da920d6ba537fad Mon Sep 17 00:00:00 2001
|
||||
From: Simon Glass <sjg@chromium.org>
|
||||
|
@ -79,7 +81,16 @@ Signed-off-by: Simon Glass <sjg@chromium.org>
|
|||
expfd.write(expected)
|
||||
expfd.close()
|
||||
|
||||
patchstream.FixPatch(None, inname, series.Series(), None)
|
||||
# Normally by the time we call FixPatch we've already collected
|
||||
# metadata. Here, we haven't, but at least fake up something.
|
||||
# Set the "count" to -1 which tells FixPatch to use a bogus/fixed
|
||||
# time for generating the Message-Id.
|
||||
com = commit.Commit('')
|
||||
com.change_id = 'I80fe1d0c0b7dd10aa58ce5bb1d9290b6664d5413'
|
||||
com.count = -1
|
||||
|
||||
patchstream.FixPatch(None, inname, series.Series(), com)
|
||||
|
||||
rc = os.system('diff -u %s %s' % (inname, expname))
|
||||
self.assertEqual(rc, 0)
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ def GetInputFilename(fname):
|
|||
Returns:
|
||||
The full path of the filename, within the input directory
|
||||
"""
|
||||
if not indir:
|
||||
if not indir or fname[:1] == '/':
|
||||
return fname
|
||||
for dirname in indir:
|
||||
pathname = os.path.join(dirname, fname)
|
||||
|
@ -186,7 +186,7 @@ def PathHasFile(path_spec, fname):
|
|||
return True
|
||||
return False
|
||||
|
||||
def Run(name, *args, **kwargs):
|
||||
def Run(name, *args):
|
||||
"""Run a tool with some arguments
|
||||
|
||||
This runs a 'tool', which is a program used by binman to process files and
|
||||
|
@ -196,7 +196,6 @@ def Run(name, *args, **kwargs):
|
|||
Args:
|
||||
name: Command name to run
|
||||
args: Arguments to the tool
|
||||
kwargs: Options to pass to command.run()
|
||||
|
||||
Returns:
|
||||
CommandResult object
|
||||
|
@ -206,8 +205,14 @@ def Run(name, *args, **kwargs):
|
|||
if tool_search_paths:
|
||||
env = dict(os.environ)
|
||||
env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH']
|
||||
return command.Run(name, *args, capture=True,
|
||||
capture_stderr=True, env=env, **kwargs)
|
||||
all_args = (name,) + args
|
||||
result = command.RunPipe([all_args], capture=True, capture_stderr=True,
|
||||
env=env, raise_on_error=False)
|
||||
if result.return_code:
|
||||
raise Exception("Error %d running '%s': %s" %
|
||||
(result.return_code,' '.join(all_args),
|
||||
result.stderr))
|
||||
return result.stdout
|
||||
except:
|
||||
if env and not PathHasFile(env['PATH'], name):
|
||||
msg = "Please install tool '%s'" % name
|
||||
|
@ -401,14 +406,14 @@ def Compress(indata, algo, with_header=True):
|
|||
fname = GetOutputFilename('%s.comp.tmp' % algo)
|
||||
WriteFile(fname, indata)
|
||||
if algo == 'lz4':
|
||||
data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True)
|
||||
data = Run('lz4', '--no-frame-crc', '-c', fname)
|
||||
# cbfstool uses a very old version of lzma
|
||||
elif algo == 'lzma':
|
||||
outfname = GetOutputFilename('%s.comp.otmp' % algo)
|
||||
Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8')
|
||||
data = ReadFile(outfname)
|
||||
elif algo == 'gzip':
|
||||
data = Run('gzip', '-c', fname, binary=True)
|
||||
data = Run('gzip', '-c', fname)
|
||||
else:
|
||||
raise ValueError("Unknown algorithm '%s'" % algo)
|
||||
if with_header:
|
||||
|
@ -441,13 +446,13 @@ def Decompress(indata, algo, with_header=True):
|
|||
with open(fname, 'wb') as fd:
|
||||
fd.write(indata)
|
||||
if algo == 'lz4':
|
||||
data = Run('lz4', '-dc', fname, binary=True)
|
||||
data = Run('lz4', '-dc', fname)
|
||||
elif algo == 'lzma':
|
||||
outfname = GetOutputFilename('%s.decomp.otmp' % algo)
|
||||
Run('lzma_alone', 'd', fname, outfname)
|
||||
data = ReadFile(outfname)
|
||||
elif algo == 'gzip':
|
||||
data = Run('gzip', '-cd', fname, binary=True)
|
||||
data = Run('gzip', '-cd', fname)
|
||||
else:
|
||||
raise ValueError("Unknown algorithm '%s'" % algo)
|
||||
return data
|
||||
|
|
Loading…
Reference in a new issue