spl: Provide more information on boot failure

If SPL fails to boot, try to provide an error code to indicate what is
wrong. For example, if a uclass is missing, this can return -EPFNOSUPPORT
(-96) which provides useful information.

Add a helper for accessing the image-loader name so we can drop the use
of #ifdefs in this code.

Put this feature behind a CONFIG_SHOW_ERRORS option to avoid increasing
the code size.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2021-07-05 16:32:57 -06:00
parent 1ac9c4cef5
commit 7d84fbb573
3 changed files with 51 additions and 15 deletions

View File

@ -91,6 +91,16 @@ config SPL_SYS_REPORT_STACK_F_USAGE
occurrence of non 0xaa bytes.
This default implementation works for stacks growing down only.
config SPL_SHOW_ERRORS
bool "Show more information when something goes wrong"
help
This enabled more verbose error messages and checking when something
goes wrong in SPL. For example, it shows the error code when U-Boot
cannot be located. This can help to diagnose the problem and figure
out a fix, particularly during development.
This adds a small amount to SPL code size, perhaps 100 bytes.
menu "PowerPC and LayerScape SPL Boot options"
config SPL_NAND_BOOT

View File

@ -593,32 +593,42 @@ static int spl_load_image(struct spl_image_info *spl_image,
* @spl_image: Place to put the image details if successful
* @spl_boot_list: List of boot devices to try
* @count: Number of elements in spl_boot_list
* @return 0 if OK, -ve on error
* @return 0 if OK, -ENODEV if there were no boot devices
* if CONFIG_SHOW_ERRORS is enabled, returns -ENXIO if there were
* devices but none worked
*/
static int boot_from_devices(struct spl_image_info *spl_image,
u32 spl_boot_list[], int count)
{
int ret = -ENODEV;
int i;
for (i = 0; i < count && spl_boot_list[i] != BOOT_DEVICE_NONE; i++) {
struct spl_image_loader *loader;
int bootdev = spl_boot_list[i];
loader = spl_ll_find_loader(spl_boot_list[i]);
#if defined(CONFIG_SPL_SERIAL_SUPPORT) \
&& defined(CONFIG_SPL_LIBCOMMON_SUPPORT) \
&& !defined(CONFIG_SILENT_CONSOLE)
if (loader)
printf("Trying to boot from %s\n", loader->name);
else
puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
#endif
if (CONFIG_IS_ENABLED(SHOW_ERRORS))
ret = -ENXIO;
loader = spl_ll_find_loader(bootdev);
if (CONFIG_IS_ENABLED(SERIAL_SUPPORT) &&
CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT) &&
!IS_ENABLED(CONFIG_SILENT_CONSOLE)) {
if (loader)
printf("Trying to boot from %s\n",
spl_loader_name(loader));
else if (CONFIG_IS_ENABLED(SHOW_ERRORS))
printf(SPL_TPL_PROMPT
"Unsupported Boot Device %d\n", bootdev);
else
puts(SPL_TPL_PROMPT "Unsupported Boot Device!\n");
}
if (loader && !spl_load_image(spl_image, loader)) {
spl_image->boot_device = spl_boot_list[i];
spl_image->boot_device = bootdev;
return 0;
}
}
return -ENODEV;
return ret;
}
#if defined(CONFIG_SPL_FRAMEWORK_BOARD_INIT_F)
@ -710,9 +720,15 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
spl_image.boot_device = BOOT_DEVICE_NONE;
board_boot_order(spl_boot_list);
if (boot_from_devices(&spl_image, spl_boot_list,
ARRAY_SIZE(spl_boot_list))) {
puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
ret = boot_from_devices(&spl_image, spl_boot_list,
ARRAY_SIZE(spl_boot_list));
if (ret) {
if (CONFIG_IS_ENABLED(SHOW_ERRORS) &&
CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT))
printf(SPL_TPL_PROMPT "failed to boot from all boot devices (err=%d)\n",
ret);
else
puts(SPL_TPL_PROMPT "failed to boot from all boot devices\n");
hang();
}

View File

@ -505,6 +505,16 @@ struct spl_image_loader {
struct spl_boot_device *bootdev);
};
/* Helper function for accessing the name */
static inline const char *spl_loader_name(const struct spl_image_loader *loader)
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
return loader->name;
#else
return NULL;
#endif
}
/* Declare an SPL image loader */
#define SPL_LOAD_IMAGE(__name) \
ll_entry_declare(struct spl_image_loader, __name, spl_image_loader)