Merge tag 'efi-2022-01-rc2-2' of https://source.denx.de/u-boot/custodians/u-boot-efi
[platform/kernel/u-boot.git] / lib / display_options.c
index f4b1059..360b01b 100644 (file)
@@ -8,7 +8,7 @@
 #include <compiler.h>
 #include <console.h>
 #include <div64.h>
-#include <version.h>
+#include <version_string.h>
 #include <linux/ctype.h>
 #include <asm/io.h>
 
@@ -54,7 +54,7 @@ void print_freq(uint64_t freq, const char *s)
 {
        unsigned long m = 0;
        uint32_t f;
-       static const char names[] = {'G', 'M', 'K'};
+       static const char names[] = {'G', 'M', 'k'};
        unsigned long d = 1e9;
        char c = 0;
        unsigned int i;
@@ -107,7 +107,12 @@ void print_size(uint64_t size, const char *s)
        }
 
        if (!c) {
-               printf("%llu Bytes%s", size, s);
+               /*
+                * SPL tiny-printf is not capable for printing uint64_t.
+                * We have just checked that the size is small enought to fit
+                * unsigned int safely.
+                */
+               printf("%u Bytes%s", (unsigned int)size, s);
                return;
        }
 
@@ -131,85 +136,99 @@ void print_size(uint64_t size, const char *s)
        printf (" %ciB%s", c, s);
 }
 
-#define MAX_LINE_LENGTH_BYTES (64)
-#define DEFAULT_LINE_LENGTH_BYTES (16)
-int print_buffer(ulong addr, const void *data, uint width, uint count,
-                uint linelen)
+#define MAX_LINE_LENGTH_BYTES          64
+#define DEFAULT_LINE_LENGTH_BYTES      16
+
+int hexdump_line(ulong addr, const void *data, uint width, uint count,
+                uint linelen, char *out, int size)
 {
        /* linebuf as a union causes proper alignment */
        union linebuf {
-#if MEM_SUPPORT_64BIT_DATA
                uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1];
-#endif
                uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1];
                uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1];
                uint8_t  uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1];
        } lb;
+       uint thislinelen;
        int i;
-#if MEM_SUPPORT_64BIT_DATA
-       uint64_t __maybe_unused x;
-#else
-       uint32_t __maybe_unused x;
-#endif
+       ulong x;
+
+       if (linelen * width > MAX_LINE_LENGTH_BYTES)
+               linelen = MAX_LINE_LENGTH_BYTES / width;
+       if (linelen < 1)
+               linelen = DEFAULT_LINE_LENGTH_BYTES / width;
+
+       /*
+        * Check the size here so that we don't need to use snprintf(). This
+        * helps to reduce code size
+        */
+       if (size < HEXDUMP_MAX_BUF_LENGTH(linelen * width))
+               return -ENOSPC;
+
+       thislinelen = linelen;
+       out += sprintf(out, "%08lx:", addr);
+
+       /* check for overflow condition */
+       if (count < thislinelen)
+               thislinelen = count;
+
+       /* Copy from memory into linebuf and print hex values */
+       for (i = 0; i < thislinelen; i++) {
+               if (width == 4)
+                       x = lb.ui[i] = *(volatile uint32_t *)data;
+               else if (MEM_SUPPORT_64BIT_DATA && width == 8)
+                       x = lb.uq[i] = *(volatile ulong *)data;
+               else if (width == 2)
+                       x = lb.us[i] = *(volatile uint16_t *)data;
+               else
+                       x = lb.uc[i] = *(volatile uint8_t *)data;
+               if (CONFIG_IS_ENABLED(USE_TINY_PRINTF))
+                       out += sprintf(out, " %x", (uint)x);
+               else
+                       out += sprintf(out, " %0*lx", width * 2, x);
+               data += width;
+       }
+
+       /* fill line with whitespace for nice ASCII print */
+       for (i = 0; i < (linelen - thislinelen) * (width * 2 + 1); i++)
+               *out++ = ' ';
+
+       /* Print data in ASCII characters */
+       for (i = 0; i < thislinelen * width; i++) {
+               if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
+                       lb.uc[i] = '.';
+       }
+       lb.uc[i] = '\0';
+       out += sprintf(out, "  %s", lb.uc);
+
+       return thislinelen;
+}
 
+int print_buffer(ulong addr, const void *data, uint width, uint count,
+                uint linelen)
+{
        if (linelen*width > MAX_LINE_LENGTH_BYTES)
                linelen = MAX_LINE_LENGTH_BYTES / width;
        if (linelen < 1)
                linelen = DEFAULT_LINE_LENGTH_BYTES / width;
 
        while (count) {
-               uint thislinelen = linelen;
-               printf("%08lx:", addr);
-
-               /* check for overflow condition */
-               if (count < thislinelen)
-                       thislinelen = count;
-
-               /* Copy from memory into linebuf and print hex values */
-               for (i = 0; i < thislinelen; i++) {
-                       if (width == 4)
-                               x = lb.ui[i] = *(volatile uint32_t *)data;
-#if MEM_SUPPORT_64BIT_DATA
-                       else if (width == 8)
-                               x = lb.uq[i] = *(volatile uint64_t *)data;
-#endif
-                       else if (width == 2)
-                               x = lb.us[i] = *(volatile uint16_t *)data;
-                       else
-                               x = lb.uc[i] = *(volatile uint8_t *)data;
-#if defined(CONFIG_SPL_BUILD)
-                       printf(" %x", (uint)x);
-#elif defined(MEM_SUPPORT_64BIT_DATA)
-                       printf(" %0*llx", width * 2, (long long)x);
-#else
-                       printf(" %0*x", width * 2, x);
-#endif
-                       data += width;
-               }
-
-               while (thislinelen < linelen) {
-                       /* fill line with whitespace for nice ASCII print */
-                       for (i=0; i<width*2+1; i++)
-                               puts(" ");
-                       linelen--;
-               }
+               uint thislinelen;
+               char buf[HEXDUMP_MAX_BUF_LENGTH(width * linelen)];
 
-               /* Print data in ASCII characters */
-               for (i = 0; i < thislinelen * width; i++) {
-                       if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
-                               lb.uc[i] = '.';
-               }
-               lb.uc[i] = '\0';
-               printf("    %s\n", lb.uc);
+               thislinelen = hexdump_line(addr, data, width, count, linelen,
+                                          buf, sizeof(buf));
+               assert(thislinelen >= 0);
+               puts(buf);
+               putc('\n');
 
                /* update references */
+               data += thislinelen * width;
                addr += thislinelen * width;
                count -= thislinelen;
 
-#ifndef CONFIG_SPL_BUILD
-               if (ctrlc())
-                       return -1;
-#endif
+               if (!IS_ENABLED(CONFIG_SPL_BUILD) && ctrlc())
+                       return -EINTR;
        }
 
        return 0;