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:
Tom Rini 2019-10-16 18:10:31 -04:00
commit c83b1bb923
98 changed files with 1300 additions and 285 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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
*

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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
---------------------------------------

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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",
};

View File

@ -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",

View File

@ -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,
};

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}

View File

@ -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,

View File

@ -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:

View File

@ -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

View 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";
};
};
};
};

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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__':

View File

@ -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

View File

@ -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()

View File

@ -7,7 +7,6 @@
from entry import Entry
import fdt_util
import state
import tools
import tout

View File

@ -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):

View File

@ -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()

View File

@ -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):

View File

@ -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:

View File

@ -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

View 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

View 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)

View 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)

View File

@ -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)

View File

@ -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))

View File

@ -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

View File

@ -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())

View File

@ -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())

View 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'

View 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'

View 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'

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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()

View File

@ -10,7 +10,7 @@
};
u-boot {
offset = <20>;
offset = <24>;
};
};
};

View File

@ -7,7 +7,7 @@
binman {
sort-by-offset;
u-boot {
offset = <22>;
offset = <26>;
};
u-boot-spl {

View File

@ -13,7 +13,7 @@
};
u-boot-spl {
offset = <0xffffffeb>;
offset = <0xffffffe7>;
};
};
};

View File

@ -13,7 +13,7 @@
};
u-boot-spl {
offset = <0xffffffeb>;
offset = <0xffffffe7>;
};
};
};

View File

@ -10,7 +10,7 @@
};
u-boot {
offset = <20>;
offset = <24>;
};
u-boot-spl2 {

View File

@ -20,7 +20,7 @@
convert-fit;
u-boot-tpl {
replace;
ifwi-replace;
ifwi-subpart = "IBBP";
ifwi-entry = "IBBL";
};

View File

@ -19,7 +19,7 @@
filename = "ifwi.bin";
u-boot-tpl {
replace;
ifwi-replace;
ifwi-subpart = "IBBP";
ifwi-entry = "IBBL";
};

View File

@ -20,7 +20,7 @@
_testing {
return-unknown-contents;
replace;
ifwi-replace;
ifwi-subpart = "IBBP";
ifwi-entry = "IBBL";
};

View File

@ -0,0 +1,13 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
x86-reset16 {
};
};
};

View File

@ -0,0 +1,13 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
x86-reset16-spl {
};
};
};

View File

@ -0,0 +1,13 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
x86-reset16-tpl {
};
};
};

View 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 {
};
};
};

View File

@ -0,0 +1,17 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
end-at-4gb;
size = <0x80>;
u-boot {
};
intel-fit-ptr {
};
};
};

View 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";
};
};
};
};

View 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 {
};
};
};
};
};

View File

@ -0,0 +1,14 @@
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <16>;
intel-fsp-m {
filename = "fsp_m.bin";
};
};
};

View File

@ -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.

View File

@ -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);

View File

@ -25,5 +25,6 @@ SECTIONS
KEEP(*(SORT(.binman_sym*)));
__binman_sym_end = .;
}
.interp : { *(.interp*) }
}

Binary file not shown.

View File

@ -9,9 +9,10 @@ ENTRY(_start)
SECTIONS
{
. = 0xfffffdf0;
. = 0xfffffe14;
_start = .;
.ucode : {
*(.ucode)
}
.interp : { *(.interp*) }
}

View File

@ -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)

View File

@ -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.

View File

@ -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()

View File

@ -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))

View File

@ -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)

View File

@ -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