summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--boot/bootdev-uclass.c15
-rw-r--r--common/bloblist.c142
-rw-r--r--common/board_f.c4
-rw-r--r--common/spl/Kconfig2
-rw-r--r--drivers/ata/sata_bootdev.c4
-rw-r--r--drivers/block/ide.c4
-rw-r--r--drivers/scsi/scsi_bootdev.c4
-rw-r--r--drivers/virtio/virtio-uclass.c4
-rw-r--r--include/bloblist.h32
-rw-r--r--lib/fdtdec.c15
10 files changed, 106 insertions, 120 deletions
diff --git a/boot/bootdev-uclass.c b/boot/bootdev-uclass.c
index 3f8dc2c3c4e..657804949f8 100644
--- a/boot/bootdev-uclass.c
+++ b/boot/bootdev-uclass.c
@@ -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,
diff --git a/common/bloblist.c b/common/bloblist.c
index d084be89958..51ae9cc50a5 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -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 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 (!xferlist_from_boot_arg(&addr))
+ goto found;
- ret = -ENOENT;
-
- 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;
-
- if (from_addr)
- ret = bloblist_check(addr, size);
+ /*
+ * 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;
- if (ret)
- log_warning("Bloblist at %lx not found (err=%d)\n",
- addr, ret);
- else
- /* Get the real size */
- size = gd->bloblist->total_size;
- }
+ /*
+ * 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 (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);
+ /*
+ * 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 (!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;
}
diff --git a/common/board_f.c b/common/board_f.c
index ce87c619e68..c39e3b940d3 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -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);
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 5fa94098e49..cc819344cad 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -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.
diff --git a/drivers/ata/sata_bootdev.c b/drivers/ata/sata_bootdev.c
index a5ca6f6fd5b..7d5ef3c94bf 100644
--- a/drivers/ata/sata_bootdev.c
+++ b/drivers/ata/sata_bootdev.c
@@ -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,
};
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index cab5e1bc92b..c1a46dd2a94 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -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,
};
diff --git a/drivers/scsi/scsi_bootdev.c b/drivers/scsi/scsi_bootdev.c
index 28e4612f337..541b021b732 100644
--- a/drivers/scsi/scsi_bootdev.c
+++ b/drivers/scsi/scsi_bootdev.c
@@ -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,
};
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index c36e9e9b3a7..a871a1439d4 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -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,
};
diff --git a/include/bloblist.h b/include/bloblist.h
index e67b2a76358..4c578772965 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -489,9 +489,23 @@ 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
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index c67b6e8c133..d0a84b5034b 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -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;