spl: Provide more information on boot failure
authorSimon Glass <sjg@chromium.org>
Mon, 5 Jul 2021 22:32:57 +0000 (16:32 -0600)
committerSimon Glass <sjg@chromium.org>
Wed, 21 Jul 2021 16:27:35 +0000 (10:27 -0600)
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>
common/spl/Kconfig
common/spl/spl.c
include/spl.h

index 2df3e5d..c018352 100644 (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
index eba77ca..3b96f2f 100644 (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;
-
-               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();
        }
 
index d88fb79..74a1939 100644 (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)