Merge patch series "Clean up bloblist initialization"
Tom Rini <trini@konsulko.com> says: This series does a few small but important cleanups to how we check for, and initialize a bloblist. The first thing is that the way things are done today, our HANDOFF code can only work with a fixed bloblist location, so express that requirement in Kconfig. Next, we demote the scary message about "Bloblist at ... not found" to a debug because we most often see that because the bloblist doesn't (and can't) exist yet. Finally, we remove bloblist_maybe_init and split this in to an exists and a real init. This results in practically no growth (between 8 bytes growth to 12 bytes saved, with some outliers saving much more thanks to knowing it's impossible to have been passed a bloblist yet). This also cleans up some of the code around checking for / knowing about a bloblist existing. Link: https://lore.kernel.org/r/20260519162225.770071-1-trini@konsulko.com
This commit is contained in:
+10
-5
@@ -566,13 +566,18 @@ int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
|
||||
{
|
||||
const struct bootdev_ops *ops = bootdev_get_ops(dev);
|
||||
|
||||
log_debug("->get_bootflow %s,%x=%p\n", dev->name, iter->part,
|
||||
ops->get_bootflow);
|
||||
bootflow_init(bflow, dev, iter->method);
|
||||
if (!ops->get_bootflow)
|
||||
return default_get_bootflow(dev, iter, bflow);
|
||||
|
||||
return ops->get_bootflow(dev, iter, bflow);
|
||||
if (ops && ops->get_bootflow) {
|
||||
log_debug("->get_bootflow %s,%x=%p\n", dev->name, iter->part,
|
||||
ops->get_bootflow);
|
||||
|
||||
return ops->get_bootflow(dev, iter, bflow);
|
||||
}
|
||||
|
||||
log_debug("->get_bootflow %s,%x is unset\n", dev->name, iter->part);
|
||||
|
||||
return default_get_bootflow(dev, iter, bflow);
|
||||
}
|
||||
|
||||
int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
|
||||
|
||||
+72
-70
@@ -448,6 +448,7 @@ int bloblist_new(ulong addr, uint size, uint flags, uint align_log2)
|
||||
hdr->align_log2 = align_log2 ? align_log2 : BLOBLIST_BLOB_ALIGN_LOG2;
|
||||
hdr->chksum = 0;
|
||||
gd->bloblist = hdr;
|
||||
gd->flags |= GD_FLG_BLOBLIST_READY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -475,6 +476,7 @@ int bloblist_check(ulong addr, uint size)
|
||||
return log_msg_ret("Bad checksum", -EIO);
|
||||
}
|
||||
gd->bloblist = hdr;
|
||||
gd->flags |= GD_FLG_BLOBLIST_READY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -576,90 +578,88 @@ int __weak xferlist_from_boot_arg(ulong __always_unused *addr)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int bloblist_init(void)
|
||||
bool bloblist_exists(void)
|
||||
{
|
||||
bool fixed = IS_ENABLED(CONFIG_BLOBLIST_FIXED);
|
||||
int ret = 0;
|
||||
ulong addr = 0, size;
|
||||
int ret;
|
||||
ulong addr = 0;
|
||||
|
||||
/* Check if a valid transfer list passed in */
|
||||
if (!xferlist_from_boot_arg(&addr)) {
|
||||
size = bloblist_get_total_size();
|
||||
} else {
|
||||
/*
|
||||
* If U-Boot is not in the first phase, an existing bloblist must
|
||||
* be at a fixed address.
|
||||
*/
|
||||
bool from_addr = fixed && !xpl_is_first_phase();
|
||||
if (!xferlist_from_boot_arg(&addr))
|
||||
goto found;
|
||||
|
||||
/*
|
||||
* If Firmware Handoff is mandatory but no transfer list is
|
||||
* observed, report it as an error.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
|
||||
return -ENOENT;
|
||||
/*
|
||||
* If Firmware Handoff is mandatory but no transfer list is
|
||||
* observed, report it as an error.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
|
||||
return false;
|
||||
|
||||
ret = -ENOENT;
|
||||
/*
|
||||
* We have checked for a valid transfer list being passed. At this
|
||||
* point, if we do not have a fixed address for the bloblist, we cannot
|
||||
* be provided with one.
|
||||
*/
|
||||
if (xpl_is_first_phase() || !IS_ENABLED(CONFIG_BLOBLIST_FIXED))
|
||||
return false;
|
||||
|
||||
if (xpl_prev_phase() == PHASE_TPL &&
|
||||
!IS_ENABLED(CONFIG_TPL_BLOBLIST))
|
||||
from_addr = false;
|
||||
if (fixed)
|
||||
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
|
||||
CONFIG_BLOBLIST_ADDR);
|
||||
size = CONFIG_BLOBLIST_SIZE;
|
||||
/*
|
||||
* Check for a valid list as the configured address.
|
||||
*/
|
||||
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
|
||||
CONFIG_BLOBLIST_ADDR);
|
||||
ret = bloblist_check(addr, CONFIG_BLOBLIST_SIZE);
|
||||
if (!ret)
|
||||
goto found;
|
||||
|
||||
if (from_addr)
|
||||
ret = bloblist_check(addr, size);
|
||||
|
||||
if (ret)
|
||||
log_warning("Bloblist at %lx not found (err=%d)\n",
|
||||
addr, ret);
|
||||
else
|
||||
/* Get the real size */
|
||||
size = gd->bloblist->total_size;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
/*
|
||||
* If we don't have a bloblist from a fixed address, or the one
|
||||
* in the fixed address is not valid. we must allocate the
|
||||
* memory for it now.
|
||||
*/
|
||||
if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
|
||||
void *ptr = memalign(BLOBLIST_ALIGN, size);
|
||||
|
||||
if (!ptr)
|
||||
return log_msg_ret("alloc", -ENOMEM);
|
||||
addr = map_to_sysmem(ptr);
|
||||
} else if (!fixed) {
|
||||
return log_msg_ret("BLOBLIST_FIXED is not enabled",
|
||||
ret);
|
||||
}
|
||||
log_debug("Creating new bloblist size %lx at %lx\n", size,
|
||||
addr);
|
||||
ret = bloblist_new(addr, size, 0, 0);
|
||||
} else {
|
||||
log_debug("Found existing bloblist size %lx at %lx\n", size,
|
||||
addr);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return log_msg_ret("ini", ret);
|
||||
gd->flags |= GD_FLG_BLOBLIST_READY;
|
||||
log_debug("Bloblist at %lx not found (err=%d)\n", addr, ret);
|
||||
return false;
|
||||
|
||||
found:
|
||||
#ifdef DEBUG
|
||||
bloblist_show_stats();
|
||||
bloblist_show_list();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int bloblist_maybe_init(void)
|
||||
int bloblist_init(void)
|
||||
{
|
||||
if (CONFIG_IS_ENABLED(BLOBLIST) && !(gd->flags & GD_FLG_BLOBLIST_READY))
|
||||
return bloblist_init();
|
||||
int ret;
|
||||
ulong addr = 0, size = CONFIG_BLOBLIST_SIZE;
|
||||
|
||||
if (gd->flags & GD_FLG_BLOBLIST_READY) {
|
||||
log_debug("Found existing bloblist size %x at %p\n",
|
||||
gd->bloblist->total_size, gd->bloblist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If Firmware Handoff is mandatory but no transfer list has been
|
||||
* observed by fdtdec_setup, report it as an error.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BLOBLIST_PASSAGE_MANDATORY))
|
||||
return -ENOENT;
|
||||
|
||||
/*
|
||||
* If we don't have an existing bloblist, we either need
|
||||
* to allocate one now, or initialize the fixed address
|
||||
* space as a bloblist.
|
||||
*/
|
||||
if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
|
||||
void *ptr = memalign(BLOBLIST_ALIGN, size);
|
||||
|
||||
if (!ptr)
|
||||
return log_msg_ret("alloc", -ENOMEM);
|
||||
addr = map_to_sysmem(ptr);
|
||||
} else
|
||||
addr = IF_ENABLED_INT(CONFIG_BLOBLIST_FIXED,
|
||||
CONFIG_BLOBLIST_ADDR);
|
||||
|
||||
log_debug("Creating new bloblist size %lx at %lx\n", size,
|
||||
addr);
|
||||
ret = bloblist_new(addr, size, 0, 0);
|
||||
if (ret)
|
||||
return log_msg_ret("ini", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -687,7 +687,9 @@ int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist)
|
||||
return ret;
|
||||
|
||||
if (rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
|
||||
gd->bloblist = NULL; /* Reset the gd bloblist pointer */
|
||||
/* Remove this bloblist from gd */
|
||||
gd->bloblist = NULL;
|
||||
gd->flags &= ~GD_FLG_BLOBLIST_READY;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -894,7 +894,9 @@ static void initcall_run_f(void)
|
||||
INITCALL(log_init);
|
||||
INITCALL(initf_bootstage); /* uses its own timer, so does not need DM */
|
||||
INITCALL(event_init);
|
||||
INITCALL(bloblist_maybe_init);
|
||||
#if CONFIG_IS_ENABLED(BLOBLIST)
|
||||
INITCALL(bloblist_init);
|
||||
#endif
|
||||
INITCALL(setup_spl_handoff);
|
||||
#if CONFIG_IS_ENABLED(CONSOLE_RECORD_INIT_F)
|
||||
INITCALL(console_record_init);
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ source "common/spl/Kconfig.nxp"
|
||||
|
||||
config HANDOFF
|
||||
bool "Pass hand-off information from SPL to U-Boot proper"
|
||||
depends on BLOBLIST
|
||||
depends on BLOBLIST_FIXED
|
||||
help
|
||||
It is useful to be able to pass information from SPL to U-Boot
|
||||
proper to preserve state that is known in SPL and is needed in U-Boot.
|
||||
|
||||
@@ -37,9 +37,6 @@ static int sata_bootdev_hunt(struct bootdev_hunter *info, bool show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct bootdev_ops sata_bootdev_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id sata_bootdev_ids[] = {
|
||||
{ .compatible = "u-boot,bootdev-sata" },
|
||||
{ }
|
||||
@@ -48,7 +45,6 @@ static const struct udevice_id sata_bootdev_ids[] = {
|
||||
U_BOOT_DRIVER(sata_bootdev) = {
|
||||
.name = "sata_bootdev",
|
||||
.id = UCLASS_BOOTDEV,
|
||||
.ops = &sata_bootdev_ops,
|
||||
.bind = sata_bootdev_bind,
|
||||
.of_match = sata_bootdev_ids,
|
||||
};
|
||||
|
||||
@@ -969,9 +969,6 @@ static int ide_bootdev_hunt(struct bootdev_hunter *info, bool show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct bootdev_ops ide_bootdev_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id ide_bootdev_ids[] = {
|
||||
{ .compatible = "u-boot,bootdev-ide" },
|
||||
{ }
|
||||
@@ -980,7 +977,6 @@ static const struct udevice_id ide_bootdev_ids[] = {
|
||||
U_BOOT_DRIVER(ide_bootdev) = {
|
||||
.name = "ide_bootdev",
|
||||
.id = UCLASS_BOOTDEV,
|
||||
.ops = &ide_bootdev_ops,
|
||||
.bind = ide_bootdev_bind,
|
||||
.of_match = ide_bootdev_ids,
|
||||
};
|
||||
|
||||
@@ -37,9 +37,6 @@ static int scsi_bootdev_hunt(struct bootdev_hunter *info, bool show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct bootdev_ops scsi_bootdev_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id scsi_bootdev_ids[] = {
|
||||
{ .compatible = "u-boot,bootdev-scsi" },
|
||||
{ }
|
||||
@@ -48,7 +45,6 @@ static const struct udevice_id scsi_bootdev_ids[] = {
|
||||
U_BOOT_DRIVER(scsi_bootdev) = {
|
||||
.name = "scsi_bootdev",
|
||||
.id = UCLASS_BOOTDEV,
|
||||
.ops = &scsi_bootdev_ops,
|
||||
.bind = scsi_bootdev_bind,
|
||||
.of_match = scsi_bootdev_ids,
|
||||
};
|
||||
|
||||
@@ -400,9 +400,6 @@ UCLASS_DRIVER(virtio) = {
|
||||
.per_device_auto = sizeof(struct virtio_dev_priv),
|
||||
};
|
||||
|
||||
struct bootdev_ops virtio_bootdev_ops = {
|
||||
};
|
||||
|
||||
static const struct udevice_id virtio_bootdev_ids[] = {
|
||||
{ .compatible = "u-boot,bootdev-virtio" },
|
||||
{ }
|
||||
@@ -411,7 +408,6 @@ static const struct udevice_id virtio_bootdev_ids[] = {
|
||||
U_BOOT_DRIVER(virtio_bootdev) = {
|
||||
.name = "virtio_bootdev",
|
||||
.id = UCLASS_BOOTDEV,
|
||||
.ops = &virtio_bootdev_ops,
|
||||
.bind = virtio_bootdev_bind,
|
||||
.of_match = virtio_bootdev_ids,
|
||||
};
|
||||
|
||||
+15
-17
@@ -488,10 +488,24 @@ const char *bloblist_tag_name(enum bloblist_tag_t tag);
|
||||
*/
|
||||
int bloblist_reloc(void *to, uint to_size);
|
||||
|
||||
/**
|
||||
* bloblist_exists() - Check for the prior existence of a bloblist
|
||||
*
|
||||
* This will check for a transfer list having been passed via standard
|
||||
* convention. If CONFIG_BLOBLIST_PASSAGE_MANDATORY is selected and one is not
|
||||
* found, we return false.
|
||||
*
|
||||
* If CONFIG_BLOBLIST_FIXED is selected, it uses CONFIG_BLOBLIST_ADDR and
|
||||
* CONFIG_BLOBLIST_SIZE to check for a bloblist.
|
||||
*
|
||||
* Return: true if found, false if not
|
||||
*/
|
||||
bool bloblist_exists(void);
|
||||
|
||||
/**
|
||||
* bloblist_init() - Init the bloblist system with a single bloblist
|
||||
*
|
||||
* This locates and sets up the blocklist for use.
|
||||
* This creates a bloblist for use, if not already found.
|
||||
*
|
||||
* If CONFIG_BLOBLIST_FIXED is selected, it uses CONFIG_BLOBLIST_ADDR and
|
||||
* CONFIG_BLOBLIST_SIZE to set up a bloblist for use by U-Boot.
|
||||
@@ -508,22 +522,6 @@ int bloblist_reloc(void *to, uint to_size);
|
||||
*/
|
||||
int bloblist_init(void);
|
||||
|
||||
#if CONFIG_IS_ENABLED(BLOBLIST)
|
||||
/**
|
||||
* bloblist_maybe_init() - Init the bloblist system if not already done
|
||||
*
|
||||
* Calls bloblist_init() if the GD_FLG_BLOBLIST_READY flag is not set
|
||||
*
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int bloblist_maybe_init(void);
|
||||
#else
|
||||
static inline int bloblist_maybe_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* BLOBLIST */
|
||||
|
||||
/**
|
||||
* bloblist_check_reg_conv() - Check whether the bloblist is compliant to
|
||||
* the register conventions according to the
|
||||
|
||||
+5
-10
@@ -1822,17 +1822,12 @@ int fdtdec_setup(void)
|
||||
int ret = -ENOENT;
|
||||
|
||||
/*
|
||||
* If allowing a bloblist, check that first. There was discussion about
|
||||
* adding an OF_BLOBLIST Kconfig, but this was rejected.
|
||||
*
|
||||
* The necessary test is whether the previous phase passed a bloblist,
|
||||
* not whether this phase creates one.
|
||||
* If allowing a bloblist, check that first. The necessary test is
|
||||
* whether the previous phase passed a bloblist, not whether this phase
|
||||
* creates one.
|
||||
*/
|
||||
if (CONFIG_IS_ENABLED(BLOBLIST) &&
|
||||
(xpl_prev_phase() != PHASE_TPL ||
|
||||
IS_ENABLED(CONFIG_TPL_BLOBLIST))) {
|
||||
ret = bloblist_maybe_init();
|
||||
if (!ret) {
|
||||
if (CONFIG_IS_ENABLED(BLOBLIST) && (xpl_phase() > PHASE_TPL)) {
|
||||
if (bloblist_exists()) {
|
||||
gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
|
||||
if (gd->fdt_blob) {
|
||||
gd->fdt_src = FDTSRC_BLOBLIST;
|
||||
|
||||
Reference in New Issue
Block a user