Merge tag 'dm-pull-13oct23' of https://source.denx.de/u-boot/custodians/u-boot-dm
improvements with dev_read_addr_..._ptr() scan all entries in multi-device boot_targets EFI empty-capsule support
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
+19
-2
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*********************
|
||||
|
||||
|
||||
+23
-2
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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", ®, 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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) *
|
||||
|
||||
+39
-8
@@ -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,13 +139,26 @@ 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,16 +167,34 @@ 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
|
||||
*
|
||||
|
||||
+44
-3
@@ -277,19 +277,32 @@ 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
|
||||
*/
|
||||
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)
|
||||
*
|
||||
@@ -298,13 +311,28 @@ fdt_addr_t dev_read_addr_name(const struct udevice *dev, const char *name);
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -132,6 +132,6 @@ class Bintoolbootgen(bintool.Bintool):
|
||||
|
||||
result = self.build_from_git(
|
||||
'https://github.com/Xilinx/bootgen',
|
||||
'all',
|
||||
['all'],
|
||||
'bootgen')
|
||||
return result
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
+120
-40
@@ -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:
|
||||
# payload offset for non-signed capsule with no version header(184 - 190)
|
||||
self.assertEqual(payload_data.hex(), data.hex()[184:190])
|
||||
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:
|
||||
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()
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
/* Image GUID for testing capsule update */
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
binman {
|
||||
efi-capsule {
|
||||
image-index = <0x1>;
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
binman {
|
||||
efi-empty-capsule {
|
||||
capsule-type = "revert";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
binman {
|
||||
efi-empty-capsule {
|
||||
capsule-type = "accept";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
+226
-1
@@ -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 ||
|
||||
|
||||
Reference in New Issue
Block a user