Commit 7d84fbb5 authored by Simon Glass's avatar Simon Glass
Browse files

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's avatarSimon Glass <sjg@chromium.org>
parent 1ac9c4ce
......@@ -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
......
......@@ -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;
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
int bootdev = spl_boot_list[i];
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();
}
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment