1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <config.h> 9 #include <common.h> 10 #include <inttypes.h> 11 #include <version.h> 12 #include <linux/ctype.h> 13 #include <asm/io.h> 14 15 int display_options (void) 16 { 17 #if defined(BUILD_TAG) 18 printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG); 19 #else 20 printf ("\n\n%s\n\n", version_string); 21 #endif 22 return 0; 23 } 24 25 void print_size(uint64_t size, const char *s) 26 { 27 unsigned long m = 0, n; 28 uint64_t f; 29 static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'}; 30 unsigned long d = 10 * ARRAY_SIZE(names); 31 char c = 0; 32 unsigned int i; 33 34 for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) { 35 if (size >> d) { 36 c = names[i]; 37 break; 38 } 39 } 40 41 if (!c) { 42 printf("%" PRIu64 " Bytes%s", size, s); 43 return; 44 } 45 46 n = size >> d; 47 f = size & ((1ULL << d) - 1); 48 49 /* If there's a remainder, deal with it */ 50 if (f) { 51 m = (10ULL * f + (1ULL << (d - 1))) >> d; 52 53 if (m >= 10) { 54 m -= 10; 55 n += 1; 56 } 57 } 58 59 printf ("%lu", n); 60 if (m) { 61 printf (".%ld", m); 62 } 63 printf (" %ciB%s", c, s); 64 } 65 66 #define MAX_LINE_LENGTH_BYTES (64) 67 #define DEFAULT_LINE_LENGTH_BYTES (16) 68 int print_buffer(ulong addr, const void *data, uint width, uint count, 69 uint linelen) 70 { 71 /* linebuf as a union causes proper alignment */ 72 union linebuf { 73 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 74 uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; 75 #endif 76 uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; 77 uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; 78 uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; 79 } lb; 80 int i; 81 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 82 uint64_t x; 83 #else 84 uint32_t x; 85 #endif 86 87 if (linelen*width > MAX_LINE_LENGTH_BYTES) 88 linelen = MAX_LINE_LENGTH_BYTES / width; 89 if (linelen < 1) 90 linelen = DEFAULT_LINE_LENGTH_BYTES / width; 91 92 while (count) { 93 uint thislinelen = linelen; 94 printf("%08lx:", addr); 95 96 /* check for overflow condition */ 97 if (count < thislinelen) 98 thislinelen = count; 99 100 /* Copy from memory into linebuf and print hex values */ 101 for (i = 0; i < thislinelen; i++) { 102 if (width == 4) 103 x = lb.ui[i] = *(volatile uint32_t *)data; 104 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 105 else if (width == 8) 106 x = lb.uq[i] = *(volatile uint64_t *)data; 107 #endif 108 else if (width == 2) 109 x = lb.us[i] = *(volatile uint16_t *)data; 110 else 111 x = lb.uc[i] = *(volatile uint8_t *)data; 112 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 113 printf(" %0*" PRIx64, width * 2, x); 114 #else 115 printf(" %0*x", width * 2, x); 116 #endif 117 data += width; 118 } 119 120 while (thislinelen < linelen) { 121 /* fill line with whitespace for nice ASCII print */ 122 for (i=0; i<width*2+1; i++) 123 puts(" "); 124 linelen--; 125 } 126 127 /* Print data in ASCII characters */ 128 for (i = 0; i < thislinelen * width; i++) { 129 if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80) 130 lb.uc[i] = '.'; 131 } 132 lb.uc[i] = '\0'; 133 printf(" %s\n", lb.uc); 134 135 /* update references */ 136 addr += thislinelen * width; 137 count -= thislinelen; 138 139 if (ctrlc()) 140 return -1; 141 } 142 143 return 0; 144 } 145