]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - lib/display_options.c
Merge branch 'master' of git://git.denx.de/u-boot-x86
[karo-tx-uboot.git] / lib / display_options.c
index 08a7914a1d0bef542fd2314e3f8850a2a3e93c47..694d2f22e89ec574f9db84d75de143c52fbf9507 100644 (file)
 
 #include <config.h>
 #include <common.h>
+#include <version.h>
 #include <linux/ctype.h>
 #include <asm/io.h>
 
 int display_options (void)
 {
-       extern char version_string[];
-
 #if defined(BUILD_TAG)
        printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
 #else
@@ -39,30 +38,37 @@ int display_options (void)
 }
 
 /*
- * print sizes as "xxx kB", "xxx.y kB", "xxx MB", "xxx.y MB",
- * xxx GB, or xxx.y GB as needed; allow for optional trailing string
+ * print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB",
+ * xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string
  * (like "\n")
  */
-void print_size (phys_size_t size, const char *s)
+void print_size(unsigned long long size, const char *s)
 {
        unsigned long m = 0, n;
-       unsigned long long d = 1 << 30;         /* 1 GB */
-       char  c = 'G';
-
-       if (size < d) {                 /* try MB */
-               c = 'M';
-               d = 1 << 20;
-               if (size < d) {         /* print in kB */
-                       c = 'k';
-                       d = 1 << 10;
+       unsigned long long f;
+       static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'};
+       unsigned long d = 10 * ARRAY_SIZE(names);
+       char c = 0;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) {
+               if (size >> d) {
+                       c = names[i];
+                       break;
                }
        }
 
-       n = size / d;
+       if (!c) {
+               printf("%llu Bytes%s", size, s);
+               return;
+       }
+
+       n = size >> d;
+       f = size & ((1ULL << d) - 1);
 
        /* If there's a remainder, deal with it */
-       if(size % d) {
-               m = (10 * (size - (n * d)) + (d / 2) ) / d;
+       if (f) {
+               m = (10ULL * f + (1ULL << (d - 1))) >> d;
 
                if (m >= 10) {
                        m -= 10;
@@ -70,11 +76,11 @@ void print_size (phys_size_t size, const char *s)
                }
        }
 
-       printf ("%2ld", n);
+       printf ("%lu", n);
        if (m) {
                printf (".%ld", m);
        }
-       printf (" %cB%s", c, s);
+       printf (" %ciB%s", c, s);
 }
 
 /*
@@ -94,10 +100,12 @@ void print_size (phys_size_t size, const char *s)
 #define DEFAULT_LINE_LENGTH_BYTES (16)
 int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen)
 {
-       uint8_t linebuf[MAX_LINE_LENGTH_BYTES];
-       uint32_t *uip = (void*)linebuf;
-       uint16_t *usp = (void*)linebuf;
-       uint8_t *ucp = (void*)linebuf;
+       /* linebuf as a union causes proper alignment */
+       union linebuf {
+               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;
        int i;
 
        if (linelen*width > MAX_LINE_LENGTH_BYTES)
@@ -114,24 +122,24 @@ int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen)
 
                /* Copy from memory into linebuf and print hex values */
                for (i = 0; i < linelen; i++) {
-                       if (width == 4) {
-                               uip[i] = *(volatile uint32_t *)data;
-                               printf(" %08x", uip[i]);
-                       } else if (width == 2) {
-                               usp[i] = *(volatile uint16_t *)data;
-                               printf(" %04x", usp[i]);
-                       } else {
-                               ucp[i] = *(volatile uint8_t *)data;
-                               printf(" %02x", ucp[i]);
-                       }
+                       uint32_t x;
+                       if (width == 4)
+                               x = lb.ui[i] = *(volatile uint32_t *)data;
+                       else if (width == 2)
+                               x = lb.us[i] = *(volatile uint16_t *)data;
+                       else
+                               x = lb.uc[i] = *(volatile uint8_t *)data;
+                       printf(" %0*x", width * 2, x);
                        data += width;
                }
 
                /* Print data in ASCII characters */
-               puts("    ");
-               for (i = 0; i < linelen * width; i++)
-                       putc(isprint(ucp[i]) && (ucp[i] < 0x80) ? ucp[i] : '.');
-               putc ('\n');
+               for (i = 0; i < linelen * width; i++) {
+                       if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
+                               lb.uc[i] = '.';
+               }
+               lb.uc[i] = '\0';
+               printf("    %s\n", lb.uc);
 
                /* update references */
                addr += linelen * width;