aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-10-14 10:50:20 -0400
committerTom Rini <trini@konsulko.com>2023-10-14 10:50:20 -0400
commit3c3f1626919cd93cbe6c56e3849937de5be18dbb (patch)
tree97483e691431094e5a668fcc9ac1cc96032ef543
parent25edd247a84a31298c22a34ec5cf2851cbf61f70 (diff)
parent74aae507bc4d5726308c191d3191d9cd624ba0d2 (diff)
downloadu-boot-WIP/14Oct2023.zip
u-boot-WIP/14Oct2023.tar.gz
u-boot-WIP/14Oct2023.tar.bz2
Merge tag 'dm-pull-13oct23' of https://source.denx.de/u-boot/custodians/u-boot-dmWIP/14Oct2023
improvements with dev_read_addr_..._ptr() scan all entries in multi-device boot_targets EFI empty-capsule support
-rw-r--r--arch/arm/mach-k3/sysfw-loader.c16
-rw-r--r--arch/sandbox/cpu/spl.c3
-rw-r--r--boot/bootdev-uclass.c3
-rw-r--r--boot/bootflow.c21
-rw-r--r--doc/develop/uefi/uefi.rst17
-rw-r--r--drivers/core/fdtaddr.c25
-rw-r--r--drivers/core/read.c21
-rw-r--r--drivers/dma/ti/k3-udma.c5
-rw-r--r--drivers/gpio/tegra186_gpio.c4
-rw-r--r--drivers/mailbox/k3-sec-proxy.c18
-rw-r--r--drivers/phy/allwinner/phy-sun4i-usb.c12
-rw-r--r--drivers/phy/phy-bcm-sr-pcie.c4
-rw-r--r--drivers/pinctrl/pinctrl-single.c34
-rw-r--r--drivers/ram/k3-am654-ddrss.c20
-rw-r--r--drivers/ram/k3-ddrss/k3-ddrss.c23
-rw-r--r--drivers/soc/ti/k3-navss-ringacc.c12
-rw-r--r--include/dm/fdtaddr.h47
-rw-r--r--include/dm/read.h47
-rw-r--r--test/boot/bootdev.c10
-rw-r--r--tools/binman/btool/bootgen.py2
-rw-r--r--tools/binman/btool/fiptool.py2
-rw-r--r--tools/binman/btool/futility.py2
-rw-r--r--tools/binman/btool/mkeficapsule.py26
-rw-r--r--tools/binman/entries.rst44
-rw-r--r--tools/binman/etype/efi_capsule.py24
-rw-r--r--tools/binman/etype/efi_empty_capsule.py86
-rw-r--r--tools/binman/ftest.py160
-rw-r--r--tools/binman/test/311_capsule.dts3
-rw-r--r--tools/binman/test/312_capsule_signed.dts3
-rw-r--r--tools/binman/test/313_capsule_version.dts3
-rw-r--r--tools/binman/test/314_capsule_signed_ver.dts3
-rw-r--r--tools/binman/test/315_capsule_oemflags.dts3
-rw-r--r--tools/binman/test/316_capsule_missing_key.dts3
-rw-r--r--tools/binman/test/317_capsule_missing_index.dts3
-rw-r--r--tools/binman/test/318_capsule_missing_guid.dts3
-rw-r--r--tools/binman/test/319_capsule_accept.dts13
-rw-r--r--tools/binman/test/320_capsule_revert.dts11
-rw-r--r--tools/binman/test/321_capsule_accept_missing_guid.dts11
-rw-r--r--tools/binman/test/322_empty_capsule_type_missing.dts12
-rw-r--r--tools/binman/test/323_capsule_accept_revert_missing.dts13
-rw-r--r--tools/eficapsule.h2
-rw-r--r--tools/mkeficapsule.c227
42 files changed, 837 insertions, 164 deletions
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index 9be2d9e..ef245fe 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -321,7 +321,7 @@ exit:
static void *k3_sysfw_get_spi_addr(void)
{
struct udevice *dev;
- fdt_addr_t addr;
+ void *addr;
int ret;
unsigned int sf_bus = spl_spi_boot_bus();
@@ -329,11 +329,11 @@ static void *k3_sysfw_get_spi_addr(void)
if (ret)
return NULL;
- addr = dev_read_addr_index(dev, 1);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_index_ptr(dev, 1);
+ if (!addr)
return NULL;
- return (void *)(addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS);
+ return addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS;
}
static void k3_sysfw_spi_copy(u32 *dst, u32 *src, size_t len)
@@ -349,18 +349,18 @@ static void k3_sysfw_spi_copy(u32 *dst, u32 *src, size_t len)
static void *get_sysfw_hf_addr(void)
{
struct udevice *dev;
- fdt_addr_t addr;
+ void *addr;
int ret;
ret = uclass_find_first_device(UCLASS_MTD, &dev);
if (ret)
return NULL;
- addr = dev_read_addr_index(dev, 1);
- if (addr == FDT_ADDR_T_NONE)
+ addr = dev_read_addr_index_ptr(dev, 1);
+ if (!addr)
return NULL;
- return (void *)(addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS);
+ return addr + CONFIG_K3_SYSFW_IMAGE_SPI_OFFS;
}
#endif
diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c
index 09e3d10..7590f1b 100644
--- a/arch/sandbox/cpu/spl.c
+++ b/arch/sandbox/cpu/spl.c
@@ -126,6 +126,9 @@ void spl_board_init(void)
{
struct sandbox_state *state = state_get_current();
+ if (!CONFIG_IS_ENABLED(UNIT_TEST))
+ return;
+
if (state->run_unittests) {
struct unit_test *tests = UNIT_TEST_ALL_START();
const int count = UNIT_TEST_ALL_COUNT();
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 974ddee..44ae98a 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -469,10 +469,11 @@ int bootdev_find_by_label(const char *label, struct udevice **devp,
* if no sequence number was provided, we must scan all
* bootdevs for this media uclass
*/
- if (IS_ENABLED(CONFIG_BOOTSTD_FULL) && seq == -1)
+ if (seq == -1)
method_flags |= BOOTFLOW_METHF_SINGLE_UCLASS;
if (method_flagsp)
*method_flagsp = method_flags;
+ log_debug("method flags %x\n", method_flags);
return 0;
}
log_debug("- no device in %s\n", media->name);
diff --git a/boot/bootflow.c b/boot/bootflow.c
index 6ef62e1..e03932e 100644
--- a/boot/bootflow.c
+++ b/boot/bootflow.c
@@ -260,8 +260,25 @@ static int iter_incr(struct bootflow_iter *iter)
} else {
log_debug("labels %p\n", iter->labels);
if (iter->labels) {
- ret = bootdev_next_label(iter, &dev,
- &method_flags);
+ /*
+ * when the label is "mmc" we want to scan all
+ * mmc bootdevs, not just the first. See
+ * bootdev_find_by_label() where this flag is
+ * set up
+ */
+ if (iter->method_flags & BOOTFLOW_METHF_SINGLE_UCLASS) {
+ uclass_next_device(&dev);
+ log_debug("looking for next device %s: %s\n",
+ iter->dev->name,
+ dev ? dev->name : "<none>");
+ } else {
+ dev = NULL;
+ }
+ if (!dev) {
+ log_debug("looking at next label\n");
+ ret = bootdev_next_label(iter, &dev,
+ &method_flags);
+ }
} else {
ret = bootdev_next_prio(iter, &dev);
method_flags = 0;
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index f8510d3..fb16ac7 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -385,6 +385,23 @@ capsules. Refer :ref:`etype_efi_capsule` for documentation about the
efi-capsule binman entry type, which describes all the properties that
can be specified.
+Dumping capsule headers
+***********************
+
+The mkeficapsule tool also provides a command-line option to dump the
+contents of the capsule header. This is a useful functionality when
+trying to understand the structure of a capsule and is also used in
+capsule verification. This feature is used in testing the capsule
+contents in binman's test framework.
+
+To check the contents of the capsule headers, the mkeficapsule command
+can be used.
+
+.. code-block:: console
+
+ $ mkeficapsule --dump-capsule \
+ <capsule_file_name>
+
Performing the update
*********************
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index b79d138..8e774d4 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -145,7 +145,7 @@ fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name)
index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
"reg-names", name);
if (index < 0)
- return index;
+ return FDT_ADDR_T_NONE;
return devfdt_get_addr_index(dev, index);
#else
@@ -153,6 +153,16 @@ fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name)
#endif
}
+void *devfdt_get_addr_name_ptr(const struct udevice *dev, const char *name)
+{
+ fdt_addr_t addr = devfdt_get_addr_name(dev, name);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_sysmem(addr, 0);
+}
+
fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev,
const char *name, fdt_size_t *size)
{
@@ -162,7 +172,7 @@ fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev,
index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
"reg-names", name);
if (index < 0)
- return index;
+ return FDT_ADDR_T_NONE;
return devfdt_get_addr_size_index(dev, index, size);
#else
@@ -170,6 +180,17 @@ fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev,
#endif
}
+void *devfdt_get_addr_size_name_ptr(const struct udevice *dev,
+ const char *name, fdt_size_t *size)
+{
+ fdt_addr_t addr = devfdt_get_addr_size_name(dev, name, size);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_sysmem(addr, 0);
+}
+
fdt_addr_t devfdt_get_addr(const struct udevice *dev)
{
return devfdt_get_addr_index(dev, 0);
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 4190134..1a4a95c 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -181,6 +181,16 @@ fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name)
return dev_read_addr_index(dev, index);
}
+void *dev_read_addr_name_ptr(const struct udevice *dev, const char *name)
+{
+ fdt_addr_t addr = dev_read_addr_name(dev, name);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_sysmem(addr, 0);
+}
+
fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name,
fdt_size_t *size)
{
@@ -192,6 +202,17 @@ fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name,
return dev_read_addr_size_index(dev, index, size);
}
+void *dev_read_addr_size_name_ptr(const struct udevice *dev, const char *name,
+ fdt_size_t *size)
+{
+ fdt_addr_t addr = dev_read_addr_size_name(dev, name, size);
+
+ if (addr == FDT_ADDR_T_NONE)
+ return NULL;
+
+ return map_sysmem(addr, 0);
+}
+
void *dev_remap_addr_name(const struct udevice *dev, const char *name)
{
fdt_addr_t addr = dev_read_addr_name(dev, name);
diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
index 4f2effd..9273c70 100644
--- a/drivers/dma/ti/k3-udma.c
+++ b/drivers/dma/ti/k3-udma.c
@@ -1287,7 +1287,7 @@ static int udma_get_mmrs(struct udevice *dev)
u32 cap2, cap3, cap4;
int i;
- ud->mmrs[MMR_GCFG] = (uint32_t *)devfdt_get_addr_name(dev, mmr_names[MMR_GCFG]);
+ ud->mmrs[MMR_GCFG] = dev_read_addr_name_ptr(dev, mmr_names[MMR_GCFG]);
if (!ud->mmrs[MMR_GCFG])
return -EINVAL;
@@ -1325,8 +1325,7 @@ static int udma_get_mmrs(struct udevice *dev)
if (i == MMR_RCHANRT && ud->rchan_cnt == 0)
continue;
- ud->mmrs[i] = (uint32_t *)devfdt_get_addr_name(dev,
- mmr_names[i]);
+ ud->mmrs[i] = dev_read_addr_name_ptr(dev, mmr_names[i]);
if (!ud->mmrs[i])
return -EINVAL;
}
diff --git a/drivers/gpio/tegra186_gpio.c b/drivers/gpio/tegra186_gpio.c
index 82dcaf9..94a20d1 100644
--- a/drivers/gpio/tegra186_gpio.c
+++ b/drivers/gpio/tegra186_gpio.c
@@ -176,8 +176,8 @@ static int tegra186_gpio_bind(struct udevice *parent)
if (parent_plat)
return 0;
- regs = (uint32_t *)devfdt_get_addr_name(parent, "gpio");
- if (regs == (uint32_t *)FDT_ADDR_T_NONE)
+ regs = dev_read_addr_name_ptr(parent, "gpio");
+ if (!regs)
return -EINVAL;
for (port = 0; port < ctlr_data->port_count; port++) {
diff --git a/drivers/mailbox/k3-sec-proxy.c b/drivers/mailbox/k3-sec-proxy.c
index 2707261..e0a18d8 100644
--- a/drivers/mailbox/k3-sec-proxy.c
+++ b/drivers/mailbox/k3-sec-proxy.c
@@ -84,9 +84,9 @@ struct k3_sec_proxy_mbox {
struct mbox_chan chan;
struct k3_sec_proxy_desc *desc;
struct k3_sec_proxy_thread *chans;
- phys_addr_t target_data;
- phys_addr_t scfg;
- phys_addr_t rt;
+ void *target_data;
+ void *scfg;
+ void *rt;
};
static inline u32 sp_readl(void __iomem *addr, unsigned int offset)
@@ -319,20 +319,20 @@ static int k3_sec_proxy_of_to_priv(struct udevice *dev,
return -ENODEV;
}
- spm->target_data = devfdt_get_addr_name(dev, "target_data");
- if (spm->target_data == FDT_ADDR_T_NONE) {
+ spm->target_data = dev_read_addr_name_ptr(dev, "target_data");
+ if (!spm->target_data) {
dev_err(dev, "No reg property for target data base\n");
return -EINVAL;
}
- spm->scfg = devfdt_get_addr_name(dev, "scfg");
- if (spm->scfg == FDT_ADDR_T_NONE) {
+ spm->scfg = dev_read_addr_name_ptr(dev, "scfg");
+ if (!spm->scfg) {
dev_err(dev, "No reg property for Secure Cfg base\n");
return -EINVAL;
}
- spm->rt = devfdt_get_addr_name(dev, "rt");
- if (spm->rt == FDT_ADDR_T_NONE) {
+ spm->rt = dev_read_addr_name_ptr(dev, "rt");
+ if (!spm->rt) {
dev_err(dev, "No reg property for Real Time Cfg base\n");
return -EINVAL;
}
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 77dffca..6624e91 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -472,9 +472,9 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
if (!data->cfg)
return -EINVAL;
- data->base = (void __iomem *)devfdt_get_addr_name(dev, "phy_ctrl");
- if (IS_ERR(data->base))
- return PTR_ERR(data->base);
+ data->base = (void __iomem *)dev_read_addr_name_ptr(dev, "phy_ctrl");
+ if (!data->base)
+ return -EINVAL;
device_get_supply_regulator(dev, "usb0_vbus_power-supply",
&data->vbus_power_supply);
@@ -555,9 +555,9 @@ static int sun4i_usb_phy_probe(struct udevice *dev)
if (i || data->cfg->phy0_dual_route) {
snprintf(name, sizeof(name), "pmu%d", i);
- phy->pmu = (void __iomem *)devfdt_get_addr_name(dev, name);
- if (IS_ERR(phy->pmu))
- return PTR_ERR(phy->pmu);
+ phy->pmu = (void __iomem *)dev_read_addr_name_ptr(dev, name);
+ if (!phy->pmu)
+ return -EINVAL;
}
phy->id = i;
diff --git a/drivers/phy/phy-bcm-sr-pcie.c b/drivers/phy/phy-bcm-sr-pcie.c
index f0e7953..cf33bab 100644
--- a/drivers/phy/phy-bcm-sr-pcie.c
+++ b/drivers/phy/phy-bcm-sr-pcie.c
@@ -143,8 +143,8 @@ static int sr_pcie_phy_probe(struct udevice *dev)
core->dev = dev;
- core->base = (void __iomem *)devfdt_get_addr_name(dev, "reg_base");
- core->cdru = (void __iomem *)devfdt_get_addr_name(dev, "cdru_base");
+ core->base = (void __iomem *)dev_read_addr_name_ptr(dev, "reg_base");
+ core->cdru = (void __iomem *)dev_read_addr_name_ptr(dev, "cdru_base");
debug("ip base %p\n", core->base);
debug("cdru base %p\n", core->cdru);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index d80281f..d1db377 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <mapmem.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
@@ -24,7 +25,7 @@
* @bits_per_mux: true if one register controls more than one pin
*/
struct single_pdata {
- fdt_addr_t base;
+ void *base;
int offset;
u32 mask;
u32 width;
@@ -97,7 +98,7 @@ struct single_fdt_bits_cfg {
#if (!IS_ENABLED(CONFIG_SANDBOX))
-static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
+static unsigned int single_read(struct udevice *dev, void *reg)
{
struct single_pdata *pdata = dev_get_plat(dev);
@@ -113,7 +114,7 @@ static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
return readb(reg);
}
-static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
+static void single_write(struct udevice *dev, unsigned int val, void *reg)
{
struct single_pdata *pdata = dev_get_plat(dev);
@@ -131,18 +132,18 @@ static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
#else /* CONFIG_SANDBOX */
-static unsigned int single_read(struct udevice *dev, fdt_addr_t reg)
+static unsigned int single_read(struct udevice *dev, void *reg)
{
struct single_priv *priv = dev_get_priv(dev);
- return priv->sandbox_regs[reg];
+ return priv->sandbox_regs[map_to_sysmem(reg)];
}
-static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg)
+static void single_write(struct udevice *dev, unsigned int val, void *reg)
{
struct single_priv *priv = dev_get_priv(dev);
- priv->sandbox_regs[reg] = val;
+ priv->sandbox_regs[map_to_sysmem(reg)] = val;
}
#endif /* CONFIG_SANDBOX */
@@ -214,7 +215,8 @@ static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
{
struct single_pdata *pdata = dev_get_plat(dev);
struct single_priv *priv = dev_get_priv(dev);
- fdt_addr_t reg;
+ phys_addr_t phys_reg;
+ void *reg;
const char *fname;
unsigned int val;
int offset, pin_shift = 0;
@@ -226,13 +228,15 @@ static int single_get_pin_muxing(struct udevice *dev, unsigned int pin,
reg = pdata->base + offset;
val = single_read(dev, reg);
+ phys_reg = map_to_sysmem(reg);
+
if (pdata->bits_per_mux)
pin_shift = pin % (pdata->width / priv->bits_per_pin) *
priv->bits_per_pin;
val &= (pdata->mask << pin_shift);
fname = single_get_pin_function(dev, pin);
- snprintf(buf, size, "%pa 0x%08x %s", &reg, val,
+ snprintf(buf, size, "%pa 0x%08x %s", &phys_reg, val,
fname ? fname : "UNCLAIMED");
return 0;
}
@@ -243,7 +247,7 @@ static int single_request(struct udevice *dev, int pin, int flags)
struct single_pdata *pdata = dev_get_plat(dev);
struct single_gpiofunc_range *frange = NULL;
struct list_head *pos, *tmp;
- phys_addr_t reg;
+ void *reg;
int mux_bytes = 0;
u32 data;
@@ -321,7 +325,7 @@ static int single_configure_pins(struct udevice *dev,
int stride = pdata->args_count + 1;
int n, pin, count = size / sizeof(u32);
struct single_func *func;
- phys_addr_t reg;
+ void *reg;
u32 offset, val, mux;
/* If function mask is null, needn't enable it. */
@@ -379,7 +383,7 @@ static int single_configure_bits(struct udevice *dev,
int n, pin, count = size / sizeof(struct single_fdt_bits_cfg);
int npins_in_reg, pin_num_from_lsb;
struct single_func *func;
- phys_addr_t reg;
+ void *reg;
u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask;
/* If function mask is null, needn't enable it. */
@@ -570,7 +574,7 @@ static int single_probe(struct udevice *dev)
static int single_of_to_plat(struct udevice *dev)
{
- fdt_addr_t addr;
+ void *addr;
fdt_size_t size;
struct single_pdata *pdata = dev_get_plat(dev);
int ret;
@@ -591,8 +595,8 @@ static int single_of_to_plat(struct udevice *dev)
return -EINVAL;
}
- addr = dev_read_addr_size_index(dev, 0, &size);
- if (addr == FDT_ADDR_T_NONE) {
+ addr = dev_read_addr_size_index_ptr(dev, 0, &size);
+ if (!addr) {
dev_err(dev, "failed to get base register address\n");
return -EINVAL;
}
diff --git a/drivers/ram/k3-am654-ddrss.c b/drivers/ram/k3-am654-ddrss.c
index b8338f8..4a8a6a9 100644
--- a/drivers/ram/k3-am654-ddrss.c
+++ b/drivers/ram/k3-am654-ddrss.c
@@ -903,7 +903,7 @@ static int am654_ddrss_power_on(struct am654_ddrss_desc *ddrss)
static int am654_ddrss_ofdata_to_priv(struct udevice *dev)
{
struct am654_ddrss_desc *ddrss = dev_get_priv(dev);
- phys_addr_t reg;
+ void *reg;
int ret;
debug("%s(dev=%p)\n", __func__, dev);
@@ -926,26 +926,26 @@ static int am654_ddrss_ofdata_to_priv(struct udevice *dev)
return ret;
}
- reg = devfdt_get_addr_name(dev, "ss");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "ss");
+ if (!reg) {
dev_err(dev, "No reg property for DDRSS wrapper logic\n");
return -EINVAL;
}
- ddrss->ddrss_ss_cfg = (void *)reg;
+ ddrss->ddrss_ss_cfg = reg;
- reg = devfdt_get_addr_name(dev, "ctl");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "ctl");
+ if (!reg) {
dev_err(dev, "No reg property for Controller region\n");
return -EINVAL;
}
- ddrss->ddrss_ctl_cfg = (void *)reg;
+ ddrss->ddrss_ctl_cfg = reg;
- reg = devfdt_get_addr_name(dev, "phy");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "phy");
+ if (!reg) {
dev_err(dev, "No reg property for PHY region\n");
return -EINVAL;
}
- ddrss->ddrss_phy_cfg = (void *)reg;
+ ddrss->ddrss_phy_cfg = reg;
ret = dev_read_u32_array(dev, "ti,ss-reg",
(u32 *)&ddrss->params.ss_reg,
diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index b54557f..5b6089e 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -331,32 +331,29 @@ static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
{
struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
- phys_addr_t reg;
+ void *reg;
int ret;
debug("%s(dev=%p)\n", __func__, dev);
- reg = dev_read_addr_name(dev, "cfg");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "cfg");
+ if (!reg) {
dev_err(dev, "No reg property for DDRSS wrapper logic\n");
return -EINVAL;
}
- ddrss->ddrss_ctl_cfg = (void *)reg;
+ ddrss->ddrss_ctl_cfg = reg;
- reg = dev_read_addr_name(dev, "ctrl_mmr_lp4");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "ctrl_mmr_lp4");
+ if (!reg) {
dev_err(dev, "No reg property for CTRL MMR\n");
return -EINVAL;
}
- ddrss->ddrss_ctrl_mmr = (void *)reg;
+ ddrss->ddrss_ctrl_mmr = reg;
- reg = dev_read_addr_name(dev, "ss_cfg");
- if (reg == FDT_ADDR_T_NONE) {
+ reg = dev_read_addr_name_ptr(dev, "ss_cfg");
+ if (!reg)
dev_dbg(dev, "No reg property for SS Config region, but this is optional so continuing.\n");
- ddrss->ddrss_ss_cfg = NULL;
- } else {
- ddrss->ddrss_ss_cfg = (void *)reg;
- }
+ ddrss->ddrss_ss_cfg = reg;
ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0);
if (ret) {
diff --git a/drivers/soc/ti/k3-navss-ringacc.c b/drivers/soc/ti/k3-navss-ringacc.c
index 9881bff..e028896 100644
--- a/drivers/soc/ti/k3-navss-ringacc.c
+++ b/drivers/soc/ti/k3-navss-ringacc.c
@@ -987,10 +987,10 @@ static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringa
if (!base_cfg)
return -EINVAL;
- base_rt = (uint32_t *)devfdt_get_addr_name(dev, "rt");
+ base_rt = dev_read_addr_name_ptr(dev, "rt");
pr_debug("rt %p\n", base_rt);
- if (IS_ERR(base_rt))
- return PTR_ERR(base_rt);
+ if (!base_rt)
+ return -EINVAL;
ringacc->rings = devm_kzalloc(dev,
sizeof(*ringacc->rings) *
@@ -1045,9 +1045,9 @@ struct k3_nav_ringacc *k3_ringacc_dmarings_init(struct udevice *dev,
ringacc->tisci = data->tisci;
ringacc->tisci_dev_id = data->tisci_dev_id;
- base_rt = (uint32_t *)devfdt_get_addr_name(dev, "ringrt");
- if (IS_ERR(base_rt))
- return base_rt;
+ base_rt = dev_read_addr_name_ptr(dev, "ringrt");
+ if (!base_rt)
+ return ERR_PTR(-EINVAL);
ringacc->rings = devm_kzalloc(dev,
sizeof(*ringacc->rings) *
diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h
index 6d2fa8f..bf8132d 100644
--- a/include/dm/fdtaddr.h
+++ b/include/dm/fdtaddr.h
@@ -19,7 +19,7 @@ struct udevice;
*
* @dev: Pointer to a device
*
- * Return: addr
+ * Return: Address, or FDT_ADDR_T_NONE if there is no such property
*/
fdt_addr_t devfdt_get_addr(const struct udevice *dev);
@@ -59,7 +59,7 @@ void *devfdt_remap_addr_index(const struct udevice *dev, int index);
* devfdt_remap_addr_name() - Get the reg property of a device, indexed by
* name, as a memory-mapped I/O pointer
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
*
* @dev: Pointer to a device
@@ -87,7 +87,7 @@ void *devfdt_map_physmem(const struct udevice *dev, unsigned long size);
* @index: the 'reg' property can hold a list of <addr, size> pairs
* and @index is used to select which one is required
*
- * Return: addr
+ * Return: Address, or FDT_ADDR_T_NONE if there is no such property
*/
fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index);
@@ -114,7 +114,7 @@ void *devfdt_get_addr_index_ptr(const struct udevice *dev, int index);
* @size: Pointer to size variable - this function returns the size
* specified in the 'reg' property here
*
- * Return: addr
+ * Return: Address, or FDT_ADDR_T_NONE if there is no such property
*/
fdt_addr_t devfdt_get_addr_size_index(const struct udevice *dev, int index,
fdt_size_t *size);
@@ -139,14 +139,27 @@ void *devfdt_get_addr_size_index_ptr(const struct udevice *dev, int index,
*
* @dev: Pointer to a device
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
*
- * Return: addr
+ * Return: Address, or FDT_ADDR_T_NONE if there is no such property
*/
fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name);
/**
+ * devfdt_get_addr_name_ptr() - Get the reg property of a device as a pointer,
+ * indexed by name
+ *
+ * @dev: Pointer to a device
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @name
+ * indicates the value to search for in 'reg-names'.
+ *
+ * Return: Pointer to addr, or NULL if there is no such property
+ */
+void *devfdt_get_addr_name_ptr(const struct udevice *dev, const char *name);
+
+/**
* devfdt_get_addr_size_name() - Get the reg property and its size for a device,
* indexed by name
*
@@ -154,17 +167,35 @@ fdt_addr_t devfdt_get_addr_name(const struct udevice *dev, const char *name);
*
* @dev: Pointer to a device
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
* @size: Pointer to size variable - this function returns the size
* specified in the 'reg' property here
*
- * Return: addr
+ * Return: Address, or FDT_ADDR_T_NONE if there is no such property
*/
fdt_addr_t devfdt_get_addr_size_name(const struct udevice *dev,
const char *name, fdt_size_t *size);
/**
+ * devfdt_get_addr_size_name_ptr() - Get the reg property for a device as a
+ * pointer, indexed by name
+ *
+ * Returns the address and size specified in the 'reg' property of a device.
+ *
+ * @dev: Pointer to a device
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @name
+ * indicates the value to search for in 'reg-names'.
+ * @size: Pointer to size variable - this function returns the size
+ * specified in the 'reg' property here
+ *
+ * Return: Pointer to addr, or NULL if there is no such property
+ */
+void *devfdt_get_addr_size_name_ptr(const struct udevice *dev,
+ const char *name, fdt_size_t *size);
+
+/**
* devfdt_get_addr_pci() - Read an address and handle PCI address translation
*
* @dev: Device to read from
diff --git a/include/dm/read.h b/include/dm/read.h
index 3c2eea6..894bc69 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -277,7 +277,7 @@ void *dev_remap_addr_index(const struct udevice *dev, int index);
*
* @dev: Device to read from
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
*
* Return: address or FDT_ADDR_T_NONE if not found
@@ -285,11 +285,24 @@ void *dev_remap_addr_index(const struct udevice *dev, int index);
fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name);
/**
+ * dev_read_addr_name_ptr() - Get the reg property of a device as a pointer,
+ * indexed by name
+ *
+ * @dev: Device to read from
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @name
+ * indicates the value to search for in 'reg-names'.
+ *
+ * Return: pointer or NULL if not found
+ */
+void *dev_read_addr_name_ptr(const struct udevice *dev, const char *name);
+
+/**
* dev_read_addr_size_name() - Get the reg property of a device, indexed by name
*
* @dev: Device to read from
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
* @size: place to put size value (on success)
*
@@ -299,12 +312,27 @@ fdt_addr_t dev_read_addr_size_name(const struct udevice *dev, const char *name,
fdt_size_t *size);
/**
+ * dev_read_addr_size_name_ptr() - Get the reg property of a device as a pointer,
+ * indexed by name
+ *
+ * @dev: Device to read from
+ * @name: the 'reg' property can hold a list of <addr, size> pairs, with the
+ * 'reg-names' property providing named-based identification. @name
+ * indicates the value to search for in 'reg-names'.
+ * @size: place to put size value (on success)
+ *
+ * Return: pointer or NULL if not found
+ */
+void *dev_read_addr_size_name_ptr(const struct udevice *dev, const char *name,
+ fdt_size_t *size);
+
+/**
* dev_remap_addr_name() - Get the reg property of a device, indexed by name,
* as a memory-mapped I/O pointer
*
* @dev: Device to read from
* @name: the 'reg' property can hold a list of <addr, size> pairs, with the
- * 'reg-names' property providing named-based identification. @index
+ * 'reg-names' property providing named-based identification. @name
* indicates the value to search for in 'reg-names'.
*
* Return: pointer or NULL if not found
@@ -980,6 +1008,12 @@ static inline fdt_addr_t dev_read_addr_name(const struct udevice *dev,
return devfdt_get_addr_name(dev, name);
}
+static inline void *dev_read_addr_name_ptr(const struct udevice *dev,
+ const char *name)
+{
+ return devfdt_get_addr_name_ptr(dev, name);
+}
+
static inline fdt_addr_t dev_read_addr_size_name(const struct udevice *dev,
const char *name,
fdt_size_t *size)
@@ -987,6 +1021,13 @@ static inline fdt_addr_t dev_read_addr_size_name(const struct udevice *dev,
return devfdt_get_addr_size_name(dev, name, size);
}
+static inline void *dev_read_addr_size_name_ptr(const struct udevice *dev,
+ const char *name,
+ fdt_size_t *size)
+{
+ return devfdt_get_addr_size_name_ptr(dev, name, size);
+}
+
static inline fdt_addr_t dev_read_addr(const struct udevice *dev)
{
return devfdt_get_addr(dev);
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 6b29213..c5f14a7 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -221,6 +221,16 @@ static int bootdev_test_order(struct unit_test_state *uts)
ut_asserteq_str("mmc2.bootdev", iter.dev_used[1]->name);
bootflow_iter_uninit(&iter);
+ /* Make sure it scans a bootdevs in each target */
+ ut_assertok(env_set("boot_targets", "mmc spi"));
+ ut_asserteq(0, bootflow_scan_first(NULL, NULL, &iter, 0, &bflow));
+ ut_asserteq(-ENODEV, bootflow_scan_next(&iter, &bflow));
+ ut_asserteq(3, iter.num_devs);
+ ut_asserteq_str("mmc2.bootdev", iter.dev_used[0]->name);
+ ut_asserteq_str("mmc1.bootdev", iter.dev_used[1]->name);
+ ut_asserteq_str("mmc0.bootdev", iter.dev_used[2]->name);
+ bootflow_iter_uninit(&iter);
+
return 0;
}
BOOTSTD_TEST(bootdev_test_order, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
diff --git a/tools/binman/btool/bootgen.py b/tools/binman/btool/bootgen.py
index f2ca552..1bc9f0a 100644
--- a/tools/binman/btool/bootgen.py
+++ b/tools/binman/btool/bootgen.py
@@ -132,6 +132,6 @@ class Bintoolbootgen(bintool.Bintool):
result = self.build_from_git(
'https://github.com/Xilinx/bootgen',
- 'all',
+ ['all'],
'bootgen')
return result
diff --git a/tools/binman/btool/fiptool.py b/tools/binman/btool/fiptool.py
index c80f827..34002f5 100644
--- a/tools/binman/btool/fiptool.py
+++ b/tools/binman/btool/fiptool.py
@@ -109,6 +109,6 @@ class Bintoolfiptool(bintool.Bintool):
return None
result = self.build_from_git(
'https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git',
- 'fiptool',
+ ['fiptool'],
'tools/fiptool/fiptool')
return result
diff --git a/tools/binman/btool/futility.py b/tools/binman/btool/futility.py
index 04c9aef..0d3980d 100644
--- a/tools/binman/btool/futility.py
+++ b/tools/binman/btool/futility.py
@@ -170,7 +170,7 @@ class Bintoolfutility(bintool.Bintool):
# .gitcookies file. So use a mirror instead.
result = self.build_from_git(
'https://github.com/sjg20/vboot_reference.git',
- 'all',
+ ['all'],
'build/futility/futility',
flags=['USE_FLASHROM=0'])
return result
diff --git a/tools/binman/btool/mkeficapsule.py b/tools/binman/btool/mkeficapsule.py
index 6117974..ef1da63 100644
--- a/tools/binman/btool/mkeficapsule.py
+++ b/tools/binman/btool/mkeficapsule.py
@@ -80,6 +80,32 @@ class Bintoolmkeficapsule(bintool.Bintool):
return self.run_cmd(*args)
+ def generate_empty_capsule(self, image_guid, output_fname,
+ accept=True):
+ """Generate empty capsules for FWU A/B updates
+
+ Args:
+ image_guid (str): GUID used for identifying the image
+ in case of an accept capsule
+ output_fname (str): Path to the output capsule file
+ accept (bool): Generate an accept capsule,
+ else a revert capsule
+
+ Returns:
+ str: Tool output
+ """
+ if accept:
+ args = [
+ f'--guid={image_guid}',
+ '--fw-accept'
+ ]
+ else:
+ args = [ '--fw-revert' ]
+
+ args += [ output_fname ]
+
+ return self.run_cmd(*args)
+
def fetch(self, method):
"""Fetch handler for mkeficapsule
diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 801bd94..e7b4e93 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -532,6 +532,50 @@ payload using the blob-ext subnode.
+.. _etype_efi_empty_capsule:
+
+Entry: efi-empty-capsule: Entry for generating EFI Empty Capsule files
+----------------------------------------------------------------------
+
+The parameters needed for generation of the empty capsules can
+be provided as properties in the entry.
+
+Properties / Entry arguments:
+ - image-guid: Image GUID which will be used for identifying the
+ updatable image on the board. Mandatory for accept capsule.
+ - capsule-type - String to indicate type of capsule to generate. Valid
+ values are 'accept' and 'revert'.
+
+For more details on the description of the capsule format, and the capsule
+update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+specification`_. For more information on the empty capsule, refer the
+sections 2.3.2 and 2.3.3 in the `Dependable Boot specification`_.
+
+A typical accept empty capsule entry node would then look something
+like this::
+
+ empty-capsule {
+ type = "efi-empty-capsule";
+ /* GUID of the image being accepted */
+ image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+ capsule-type = "accept";
+ };
+
+A typical revert empty capsule entry node would then look something
+like this::
+
+ empty-capsule {
+ type = "efi-empty-capsule";
+ capsule-type = "revert";
+ };
+
+The empty capsules do not have any input payload image.
+
+.. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+.. _`Dependable Boot specification`: https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
+
+
+
.. _etype_encrypted:
Entry: encrypted: Externally built encrypted binary blob
diff --git a/tools/binman/etype/efi_capsule.py b/tools/binman/etype/efi_capsule.py
index 006eb63..e320371 100644
--- a/tools/binman/etype/efi_capsule.py
+++ b/tools/binman/etype/efi_capsule.py
@@ -11,6 +11,24 @@ from binman.etype.section import Entry_section
from dtoc import fdt_util
from u_boot_pylib import tools
+def get_binman_test_guid(type_str):
+ """Get the test image GUID for binman
+
+ Based on the string passed to the function, return
+ the corresponding GUID.
+
+ Args:
+ type_str: Key value of the type of GUID to look for
+
+ Returns:
+ The actual GUID value (str)
+ """
+ TYPE_TO_GUID = {
+ 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8'
+ }
+
+ return TYPE_TO_GUID[type_str]
+
class Entry_efi_capsule(Entry_section):
"""Generate EFI capsules
@@ -104,12 +122,6 @@ class Entry_efi_capsule(Entry_section):
self.auth = 1
def BuildSectionData(self, required):
- def get_binman_test_guid(type_str):
- TYPE_TO_GUID = {
- 'binman-test' : '09d7cf52-0720-4710-91d1-08469b7fe9c8'
- }
- return TYPE_TO_GUID[type_str]
-
private_key = ''
public_key_cert = ''
if self.auth:
diff --git a/tools/binman/etype/efi_empty_capsule.py b/tools/binman/etype/efi_empty_capsule.py
new file mode 100644
index 0000000..064bf9a
--- /dev/null
+++ b/tools/binman/etype/efi_empty_capsule.py
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2023 Linaro Limited
+#
+# Entry-type module for producing an empty EFI capsule
+#
+
+import os
+
+from binman.entry import Entry
+from binman.etype.efi_capsule import get_binman_test_guid
+from binman.etype.section import Entry_section
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+class Entry_efi_empty_capsule(Entry_section):
+ """Generate EFI empty capsules
+
+ The parameters needed for generation of the empty capsules can
+ be provided as properties in the entry.
+
+ Properties / Entry arguments:
+ - image-guid: Image GUID which will be used for identifying the
+ updatable image on the board. Mandatory for accept capsule.
+ - capsule-type - String to indicate type of capsule to generate. Valid
+ values are 'accept' and 'revert'.
+
+ For more details on the description of the capsule format, and the capsule
+ update functionality, refer Section 8.5 and Chapter 23 in the `UEFI
+ specification`_. For more information on the empty capsule, refer the
+ sections 2.3.2 and 2.3.3 in the `Dependable Boot specification`_.
+
+ A typical accept empty capsule entry node would then look something like this
+
+ empty-capsule {
+ type = "efi-empty-capsule";
+ /* GUID of image being accepted */
+ image-type-id = SANDBOX_UBOOT_IMAGE_GUID;
+ capsule-type = "accept";
+ };
+
+ A typical revert empty capsule entry node would then look something like this
+
+ empty-capsule {
+ type = "efi-empty-capsule";
+ capsule-type = "revert";
+ };
+
+ The empty capsules do not have any input payload image.
+
+ .. _`UEFI specification`: https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf
+ .. _`Dependable Boot specification`: https://git.codelinaro.org/linaro/dependable-boot/mbfw/uploads/6f7ddfe3be24e18d4319e108a758d02e/mbfw.pdf
+ """
+ def __init__(self, section, etype, node):
+ super().__init__(section, etype, node)
+ self.required_props = ['capsule-type']
+ self.accept = 0
+ self.revert = 0
+
+ def ReadNode(self):
+ super().ReadNode()
+
+ self.image_guid = fdt_util.GetString(self._node, 'image-guid')
+ self.capsule_type = fdt_util.GetString(self._node, 'capsule-type')
+
+ if self.capsule_type != 'accept' and self.capsule_type != 'revert':
+ self.Raise('capsule-type should be either \'accept\' or \'revert\'')
+
+ if self.capsule_type == 'accept' and not self.image_guid:
+ self.Raise('Image GUID needed for generating accept capsule')
+
+ def BuildSectionData(self, required):
+ uniq = self.GetUniqueName()
+ outfile = self._filename if self._filename else 'capsule.%s' % uniq
+ capsule_fname = tools.get_output_filename(outfile)
+ accept = True if self.capsule_type == 'accept' else False
+ guid = self.image_guid
+ if self.image_guid == "binman-test":
+ guid = get_binman_test_guid('binman-test')
+
+ ret = self.mkeficapsule.generate_empty_capsule(guid, capsule_fname,
+ accept)
+ if ret is not None:
+ return tools.read_file(capsule_fname)
+
+ def AddBintools(self, btools):
+ self.mkeficapsule = self.AddBintool(btools, 'mkeficapsule')
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 8e41964..16156b7 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -121,9 +121,14 @@ COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd']
TEE_ADDR = 0x5678
# Firmware Management Protocol(FMP) GUID
-FW_MGMT_GUID = 'edd5cb6d2de8444cbda17194199ad92a'
+FW_MGMT_GUID = '6dcbd5ed-e82d-4c44-bda1-7194199ad92a'
# Image GUID specified in the DTS
-CAPSULE_IMAGE_GUID = '52cfd7092007104791d108469b7fe9c8'
+CAPSULE_IMAGE_GUID = '09d7cf52-0720-4710-91d1-08469b7fe9c8'
+# Windows cert GUID
+WIN_CERT_TYPE_EFI_GUID = '4aafd29d-68df-49ee-8aa9-347d375665a7'
+# Empty capsule GUIDs
+EMPTY_CAPSULE_ACCEPT_GUID = '0c996046-bcc0-4d04-85ec-e1fcedf1c6f8'
+EMPTY_CAPSULE_REVERT_GUID = 'acd58b4b-c0e8-475f-99b5-6b3f7e07aaf0'
class TestFunctional(unittest.TestCase):
"""Functional tests for binman
@@ -7223,52 +7228,94 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertRegex(err,
"Image 'image'.*missing bintools.*: bootgen")
+ def _GetCapsuleHeaders(self, data):
+ """Get the capsule header contents
+
+ Args:
+ data: Capsule file contents
+
+ Returns:
+ Dict:
+ key: Capsule Header name (str)
+ value: Header field value (str)
+ """
+ capsule_file = os.path.join(self._indir, 'test.capsule')
+ tools.write_file(capsule_file, data)
+
+ out = tools.run('mkeficapsule', '--dump-capsule', capsule_file)
+ lines = out.splitlines()
+
+ re_line = re.compile(r'^([^:\-\t]*)(?:\t*\s*:\s*(.*))?$')
+ vals = {}
+ for line in lines:
+ mat = re_line.match(line)
+ if mat:
+ vals[mat.group(1)] = mat.group(2)
+
+ return vals
+
def _CheckCapsule(self, data, signed_capsule=False, version_check=False,
capoemflags=False):
- fmp_signature = "4d535331" # 'M', 'S', 'S', '1'
- fmp_size = "10"
- fmp_fw_version = "02"
- oemflag = "0080"
+ fmp_signature = "3153534D" # 'M', 'S', 'S', '1'
+ fmp_size = "00000010"
+ fmp_fw_version = "00000002"
+ capsule_image_index = "00000001"
+ oemflag = "00018000"
+ auth_hdr_revision = "00000200"
+ auth_hdr_cert_type = "00000EF1"
- payload_data = EFI_CAPSULE_DATA
+ payload_data_len = len(EFI_CAPSULE_DATA)
- # TODO - Currently, these offsets for capsule fields are hardcoded.
- # There are plans to add support to the mkeficapsule tool to dump
- # the capsule contents which can then be used for capsule
- # verification.
+ hdr = self._GetCapsuleHeaders(data)
- # Firmware Management Protocol(FMP) GUID - offset(0 - 32)
- self.assertEqual(FW_MGMT_GUID, data.hex()[:32])
- # Image GUID - offset(96 - 128)
- self.assertEqual(CAPSULE_IMAGE_GUID, data.hex()[96:128])
+ self.assertEqual(FW_MGMT_GUID.upper(), hdr['EFI_CAPSULE_HDR.CAPSULE_GUID'])
+
+ self.assertEqual(CAPSULE_IMAGE_GUID.upper(),
+ hdr['FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_TYPE_ID'])
+ self.assertEqual(capsule_image_index,
+ hdr['FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_INDEX'])
if capoemflags:
- # OEM Flags - offset(40 - 44)
- self.assertEqual(oemflag, data.hex()[40:44])
- if signed_capsule and version_check:
- # FMP header signature - offset(4770 - 4778)
- self.assertEqual(fmp_signature, data.hex()[4770:4778])
- # FMP header size - offset(4778 - 4780)
- self.assertEqual(fmp_size, data.hex()[4778:4780])
- # firmware version - offset(4786 - 4788)
- self.assertEqual(fmp_fw_version, data.hex()[4786:4788])
- # payload offset signed capsule(4802 - 4808)
- self.assertEqual(payload_data.hex(), data.hex()[4802:4808])
- elif signed_capsule:
- # payload offset signed capsule(4770 - 4776)
- self.assertEqual(payload_data.hex(), data.hex()[4770:4776])
- elif version_check:
- # FMP header signature - offset(184 - 192)
- self.assertEqual(fmp_signature, data.hex()[184:192])
- # FMP header size - offset(192 - 194)
- self.assertEqual(fmp_size, data.hex()[192:194])
- # firmware version - offset(200 - 202)
- self.assertEqual(fmp_fw_version, data.hex()[200:202])
- # payload offset for non-signed capsule with version header(216 - 222)
- self.assertEqual(payload_data.hex(), data.hex()[216:222])
+ self.assertEqual(oemflag, hdr['EFI_CAPSULE_HDR.FLAGS'])
+
+ if signed_capsule:
+ self.assertEqual(auth_hdr_revision,
+ hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wREVISION'])
+ self.assertEqual(auth_hdr_cert_type,
+ hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wCERTTYPE'])
+ self.assertEqual(WIN_CERT_TYPE_EFI_GUID.upper(),
+ hdr['EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.CERT_TYPE'])
+
+ if version_check:
+ self.assertEqual(fmp_signature,
+ hdr['FMP_PAYLOAD_HDR.SIGNATURE'])
+ self.assertEqual(fmp_size,
+ hdr['FMP_PAYLOAD_HDR.HEADER_SIZE'])
+ self.assertEqual(fmp_fw_version,
+ hdr['FMP_PAYLOAD_HDR.FW_VERSION'])
+
+ self.assertEqual(payload_data_len, int(hdr['Payload Image Size']))
+
+ def _CheckEmptyCapsule(self, data, accept_capsule=False):
+ if accept_capsule:
+ capsule_hdr_guid = EMPTY_CAPSULE_ACCEPT_GUID
+ else:
+ capsule_hdr_guid = EMPTY_CAPSULE_REVERT_GUID
+
+ hdr = self._GetCapsuleHeaders(data)
+
+ self.assertEqual(capsule_hdr_guid.upper(),
+ hdr['EFI_CAPSULE_HDR.CAPSULE_GUID'])
+
+ if accept_capsule:
+ capsule_size = "0000002C"
else:
- # payload offset for non-signed capsule with no version header(184 - 190)
- self.assertEqual(payload_data.hex(), data.hex()[184:190])
+ capsule_size = "0000001C"
+ self.assertEqual(capsule_size,
+ hdr['EFI_CAPSULE_HDR.CAPSULE_IMAGE_SIZE'])
+
+ if accept_capsule:
+ self.assertEqual(CAPSULE_IMAGE_GUID.upper(), hdr['ACCEPT_IMAGE_GUID'])
def testCapsuleGen(self):
"""Test generation of EFI capsule"""
@@ -7334,5 +7381,38 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertIn("entry is missing properties: image-guid",
str(e.exception))
+ def testCapsuleGenAcceptCapsule(self):
+ """Test generationg of accept EFI capsule"""
+ data = self._DoReadFile('319_capsule_accept.dts')
+
+ self._CheckEmptyCapsule(data, accept_capsule=True)
+
+ def testCapsuleGenRevertCapsule(self):
+ """Test generationg of revert EFI capsule"""
+ data = self._DoReadFile('320_capsule_revert.dts')
+
+ self._CheckEmptyCapsule(data)
+
+ def testCapsuleGenAcceptGuidMissing(self):
+ """Test that binman errors out on missing image GUID for accept capsule"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('321_capsule_accept_missing_guid.dts')
+
+ self.assertIn("Image GUID needed for generating accept capsule",
+ str(e.exception))
+
+ def testCapsuleGenEmptyCapsuleTypeMissing(self):
+ """Test that capsule-type is specified"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('322_empty_capsule_type_missing.dts')
+
+ self.assertIn("entry is missing properties: capsule-type",
+ str(e.exception))
+
+ def testCapsuleGenAcceptOrRevertMissing(self):
+ """Test that both accept and revert capsule are not specified"""
+ with self.assertRaises(ValueError) as e:
+ self._DoReadFile('323_capsule_accept_revert_missing.dts')
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/test/311_capsule.dts b/tools/binman/test/311_capsule.dts
index 8eb4250..0a62ef8 100644
--- a/tools/binman/test/311_capsule.dts
+++ b/tools/binman/test/311_capsule.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/312_capsule_signed.dts b/tools/binman/test/312_capsule_signed.dts
index d1c76e2..4ab838e 100644
--- a/tools/binman/test/312_capsule_signed.dts
+++ b/tools/binman/test/312_capsule_signed.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/313_capsule_version.dts b/tools/binman/test/313_capsule_version.dts
index bafef36..19e7e83 100644
--- a/tools/binman/test/313_capsule_version.dts
+++ b/tools/binman/test/313_capsule_version.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/314_capsule_signed_ver.dts b/tools/binman/test/314_capsule_signed_ver.dts
index 85c784b..649b8cc 100644
--- a/tools/binman/test/314_capsule_signed_ver.dts
+++ b/tools/binman/test/314_capsule_signed_ver.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/315_capsule_oemflags.dts b/tools/binman/test/315_capsule_oemflags.dts
index f736e87..45853f6 100644
--- a/tools/binman/test/315_capsule_oemflags.dts
+++ b/tools/binman/test/315_capsule_oemflags.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/316_capsule_missing_key.dts b/tools/binman/test/316_capsule_missing_key.dts
index 2080b50..a14a74e 100644
--- a/tools/binman/test/316_capsule_missing_key.dts
+++ b/tools/binman/test/316_capsule_missing_key.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/317_capsule_missing_index.dts b/tools/binman/test/317_capsule_missing_index.dts
index aadb61f..99a54d5 100644
--- a/tools/binman/test/317_capsule_missing_index.dts
+++ b/tools/binman/test/317_capsule_missing_index.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
/* Image GUID for testing capsule update */
diff --git a/tools/binman/test/318_capsule_missing_guid.dts b/tools/binman/test/318_capsule_missing_guid.dts
index d76afba..85d3317 100644
--- a/tools/binman/test/318_capsule_missing_guid.dts
+++ b/tools/binman/test/318_capsule_missing_guid.dts
@@ -3,9 +3,6 @@
/dts-v1/;
/ {
- #address-cells = <1>;
- #size-cells = <1>;
-
binman {
efi-capsule {
image-index = <0x1>;
diff --git a/tools/binman/test/319_capsule_accept.dts b/tools/binman/test/319_capsule_accept.dts
new file mode 100644
index 0000000..d48e59f
--- /dev/null
+++ b/tools/binman/test/319_capsule_accept.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-empty-capsule {
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ capsule-type = "accept";
+ };
+ };
+};
diff --git a/tools/binman/test/320_capsule_revert.dts b/tools/binman/test/320_capsule_revert.dts
new file mode 100644
index 0000000..bd141ef
--- /dev/null
+++ b/tools/binman/test/320_capsule_revert.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-empty-capsule {
+ capsule-type = "revert";
+ };
+ };
+};
diff --git a/tools/binman/test/321_capsule_accept_missing_guid.dts b/tools/binman/test/321_capsule_accept_missing_guid.dts
new file mode 100644
index 0000000..a0088b1
--- /dev/null
+++ b/tools/binman/test/321_capsule_accept_missing_guid.dts
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-empty-capsule {
+ capsule-type = "accept";
+ };
+ };
+};
diff --git a/tools/binman/test/322_empty_capsule_type_missing.dts b/tools/binman/test/322_empty_capsule_type_missing.dts
new file mode 100644
index 0000000..d356168
--- /dev/null
+++ b/tools/binman/test/322_empty_capsule_type_missing.dts
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-empty-capsule {
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ };
+ };
+};
diff --git a/tools/binman/test/323_capsule_accept_revert_missing.dts b/tools/binman/test/323_capsule_accept_revert_missing.dts
new file mode 100644
index 0000000..31268b2
--- /dev/null
+++ b/tools/binman/test/323_capsule_accept_revert_missing.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ binman {
+ efi-empty-capsule {
+ /* Image GUID for testing capsule update */
+ image-guid = "binman-test";
+ capsule-type = "foo";
+ };
+ };
+};
diff --git a/tools/eficapsule.h b/tools/eficapsule.h
index 2099a2e..6efd07d 100644
--- a/tools/eficapsule.h
+++ b/tools/eficapsule.h
@@ -22,6 +22,8 @@
#define __aligned(x) __attribute__((__aligned__(x)))
#endif
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
typedef struct {
uint8_t b[16];
} efi_guid_t __aligned(8);
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index 52be1f1..b8fc606 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule";
efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
-static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR";
+static const char *opts_short = "g:i:I:v:p:c:m:o:dhARD";
enum {
CAPSULE_NORMAL_BLOB = 0,
@@ -49,6 +49,7 @@ static struct option options[] = {
{"fw-accept", no_argument, NULL, 'A'},
{"fw-revert", no_argument, NULL, 'R'},
{"capoemflag", required_argument, NULL, 'o'},
+ {"dump-capsule", no_argument, NULL, 'D'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0},
};
@@ -69,6 +70,7 @@ static void print_usage(void)
"\t-A, --fw-accept firmware accept capsule, requires GUID, no image blob\n"
"\t-R, --fw-revert firmware revert capsule, takes no GUID, no image blob\n"
"\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
+ "\t-D, --dump-capsule dump the contents of the capsule headers\n"
"\t-h, --help print a help message\n",
tool_name);
}
@@ -647,6 +649,215 @@ err:
return ret;
}
+static void print_guid(void *ptr)
+{
+ int i;
+ efi_guid_t *guid = ptr;
+ const uint8_t seq[] = {
+ 3, 2, 1, 0, '-', 5, 4, '-', 7, 6,
+ '-', 8, 9, '-', 10, 11, 12, 13, 14, 15 };
+
+ for (i = 0; i < ARRAY_SIZE(seq); i++) {
+ if (seq[i] == '-')
+ putchar(seq[i]);
+ else
+ printf("%02X", guid->b[seq[i]]);
+ }
+
+ printf("\n");
+}
+
+static uint32_t dump_fmp_payload_header(
+ struct fmp_payload_header *fmp_payload_hdr)
+{
+ if (fmp_payload_hdr->signature == FMP_PAYLOAD_HDR_SIGNATURE) {
+ printf("--------\n");
+ printf("FMP_PAYLOAD_HDR.SIGNATURE\t\t\t: %08X\n",
+ FMP_PAYLOAD_HDR_SIGNATURE);
+ printf("FMP_PAYLOAD_HDR.HEADER_SIZE\t\t\t: %08X\n",
+ fmp_payload_hdr->header_size);
+ printf("FMP_PAYLOAD_HDR.FW_VERSION\t\t\t: %08X\n",
+ fmp_payload_hdr->fw_version);
+ printf("FMP_PAYLOAD_HDR.LOWEST_SUPPORTED_VERSION\t: %08X\n",
+ fmp_payload_hdr->lowest_supported_version);
+ return fmp_payload_hdr->header_size;
+ }
+
+ return 0;
+}
+
+static void dump_capsule_auth_header(
+ struct efi_firmware_image_authentication *capsule_auth_hdr)
+{
+ printf("EFI_FIRMWARE_IMAGE_AUTH.MONOTONIC_COUNT\t\t: %08lX\n",
+ capsule_auth_hdr->monotonic_count);
+ printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.dwLENGTH\t: %08X\n",
+ capsule_auth_hdr->auth_info.hdr.dwLength);
+ printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wREVISION\t: %08X\n",
+ capsule_auth_hdr->auth_info.hdr.wRevision);
+ printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.HDR.wCERTTYPE\t: %08X\n",
+ capsule_auth_hdr->auth_info.hdr.wCertificateType);
+ printf("EFI_FIRMWARE_IMAGE_AUTH.AUTH_INFO.CERT_TYPE\t: ");
+ print_guid(&capsule_auth_hdr->auth_info.cert_type);
+}
+
+static void dump_fmp_capsule_image_header(
+ struct efi_firmware_management_capsule_image_header *image_hdr)
+{
+ void *capsule_auth_hdr;
+ void *fmp_payload_hdr;
+ uint64_t signature_size = 0;
+ uint32_t payload_size = 0;
+ uint32_t fmp_payload_hdr_size = 0;
+ struct efi_firmware_image_authentication *auth_hdr;
+
+ printf("--------\n");
+ printf("FMP_CAPSULE_IMAGE_HDR.VERSION\t\t\t: %08X\n",
+ image_hdr->version);
+ printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_TYPE_ID\t: ");
+ print_guid(&image_hdr->update_image_type_id);
+ printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_INDEX\t: %08X\n",
+ image_hdr->update_image_index);
+ printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_IMAGE_SIZE\t\t: %08X\n",
+ image_hdr->update_image_size);
+ printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_VENDOR_CODE_SIZE\t: %08X\n",
+ image_hdr->update_vendor_code_size);
+ printf("FMP_CAPSULE_IMAGE_HDR.UPDATE_HARDWARE_INSTANCE\t: %08lX\n",
+ image_hdr->update_hardware_instance);
+ printf("FMP_CAPSULE_IMAGE_HDR.IMAGE_CAPSULE_SUPPORT\t: %08lX\n",
+ image_hdr->image_capsule_support);
+
+ printf("--------\n");
+ if (image_hdr->image_capsule_support & CAPSULE_SUPPORT_AUTHENTICATION) {
+ capsule_auth_hdr = (char *)image_hdr + sizeof(*image_hdr);
+ dump_capsule_auth_header(capsule_auth_hdr);
+
+ auth_hdr = capsule_auth_hdr;
+ signature_size = sizeof(auth_hdr->monotonic_count) +
+ auth_hdr->auth_info.hdr.dwLength;
+ fmp_payload_hdr = (char *)capsule_auth_hdr + signature_size;
+ } else {
+ printf("Capsule Authentication Not Enabled\n");
+ fmp_payload_hdr = (char *)image_hdr + sizeof(*image_hdr);
+ }
+
+ fmp_payload_hdr_size = dump_fmp_payload_header(fmp_payload_hdr);
+
+ payload_size = image_hdr->update_image_size - signature_size -
+ fmp_payload_hdr_size;
+ printf("--------\n");
+ printf("Payload Image Size\t\t\t\t: %08X\n", payload_size);
+}
+
+static void dump_fmp_header(
+ struct efi_firmware_management_capsule_header *fmp_hdr)
+{
+ int i;
+ void *capsule_image_hdr;
+
+ printf("EFI_FMP_HDR.VERSION\t\t\t\t: %08X\n", fmp_hdr->version);
+ printf("EFI_FMP_HDR.EMBEDDED_DRIVER_COUNT\t\t: %08X\n",
+ fmp_hdr->embedded_driver_count);
+ printf("EFI_FMP_HDR.PAYLOAD_ITEM_COUNT\t\t\t: %08X\n",
+ fmp_hdr->payload_item_count);
+
+ /*
+ * We currently don't support Embedded Drivers.
+ * Only worry about the payload items.
+ */
+ for (i = 0; i < fmp_hdr->payload_item_count; i++) {
+ capsule_image_hdr = (char *)fmp_hdr +
+ fmp_hdr->item_offset_list[i];
+ dump_fmp_capsule_image_header(capsule_image_hdr);
+ }
+}
+
+static void dump_capsule_header(struct efi_capsule_header *capsule_hdr)
+{
+ printf("EFI_CAPSULE_HDR.CAPSULE_GUID\t\t\t: ");
+ print_guid((void *)&capsule_hdr->capsule_guid);
+ printf("EFI_CAPSULE_HDR.HEADER_SIZE\t\t\t: %08X\n",
+ capsule_hdr->header_size);
+ printf("EFI_CAPSULE_HDR.FLAGS\t\t\t\t: %08X\n", capsule_hdr->flags);
+ printf("EFI_CAPSULE_HDR.CAPSULE_IMAGE_SIZE\t\t: %08X\n",
+ capsule_hdr->capsule_image_size);
+}
+
+static void normal_capsule_dump(void *capsule_buf)
+{
+ void *fmp_hdr;
+ struct efi_capsule_header *hdr = capsule_buf;
+
+ dump_capsule_header(hdr);
+ printf("--------\n");
+
+ fmp_hdr = (char *)capsule_buf + sizeof(*hdr);
+ dump_fmp_header(fmp_hdr);
+}
+
+static void empty_capsule_dump(void *capsule_buf)
+{
+ efi_guid_t *accept_image_guid;
+ struct efi_capsule_header *hdr = capsule_buf;
+ efi_guid_t efi_empty_accept_capsule = FW_ACCEPT_OS_GUID;
+
+ dump_capsule_header(hdr);
+
+ if (!memcmp(&efi_empty_accept_capsule, &hdr->capsule_guid,
+ sizeof(efi_guid_t))) {
+ accept_image_guid = (void *)(char *)capsule_buf +
+ sizeof(struct efi_capsule_header);
+ printf("--------\n");
+ printf("ACCEPT_IMAGE_GUID\t\t\t\t: ");
+ print_guid(accept_image_guid);
+ }
+}
+
+static void dump_capsule_contents(char *capsule_file)
+{
+ int fd;
+ char *ptr;
+ efi_guid_t efi_fmp_guid = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
+ efi_guid_t efi_empty_accept_capsule = FW_ACCEPT_OS_GUID;
+ efi_guid_t efi_empty_revert_capsule = FW_REVERT_OS_GUID;
+ struct stat sbuf;
+
+ if (!capsule_file) {
+ fprintf(stderr, "No capsule file provided\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if ((fd = open(capsule_file, O_RDONLY)) < 0) {
+ fprintf(stderr, "Error opening capsule file: %s\n",
+ capsule_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (fstat(fd, &sbuf) < 0) {
+ fprintf(stderr, "Can't stat capsule file: %s\n", capsule_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if ((ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))
+ == MAP_FAILED) {
+ fprintf(stderr, "Can't mmap capsule file: %s\n", capsule_file);
+ exit(EXIT_FAILURE);
+ }
+
+ if (!memcmp(&efi_fmp_guid, ptr, sizeof(efi_guid_t))) {
+ normal_capsule_dump(ptr);
+ } else if (!memcmp(&efi_empty_accept_capsule, ptr,
+ sizeof(efi_guid_t)) ||
+ !memcmp(&efi_empty_revert_capsule, ptr,
+ sizeof(efi_guid_t))) {
+ empty_capsule_dump(ptr);
+ } else {
+ fprintf(stderr, "Unable to decode the capsule file: %s\n",
+ capsule_file);
+ exit(EXIT_FAILURE);
+ }
+}
+
/**
* main - main entry function of mkeficapsule
* @argc: Number of arguments
@@ -666,6 +877,7 @@ int main(int argc, char **argv)
unsigned long index, instance;
uint64_t mcount;
unsigned long oemflags;
+ bool capsule_dump;
char *privkey_file, *cert_file;
int c, idx;
struct fmp_payload_header_params fmp_ph_params = { 0 };
@@ -676,6 +888,7 @@ int main(int argc, char **argv)
mcount = 0;
privkey_file = NULL;
cert_file = NULL;
+ capsule_dump = false;
dump_sig = 0;
capsule_type = CAPSULE_NORMAL_BLOB;
oemflags = 0;
@@ -754,12 +967,24 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case 'D':
+ capsule_dump = true;
+ break;
default:
print_usage();
exit(EXIT_SUCCESS);
}
}
+ if (capsule_dump) {
+ if (argc != optind + 1) {
+ fprintf(stderr, "Must provide the capsule file to parse\n");
+ exit(EXIT_FAILURE);
+ }
+ dump_capsule_contents(argv[argc - 1]);
+ exit(EXIT_SUCCESS);
+ }
+
/* check necessary parameters */
if ((capsule_type == CAPSULE_NORMAL_BLOB &&
((argc != optind + 2) || !guid ||