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 <common.h> 9 #include <console.h> 10 #include <div64.h> 11 #include <inttypes.h> 12 #include <version.h> 13 #include <linux/ctype.h> 14 #include <asm/io.h> 15 16 int display_options (void) 17 { 18 #if defined(BUILD_TAG) 19 printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG); 20 #else 21 printf ("\n\n%s\n\n", version_string); 22 #endif 23 return 0; 24 } 25 26 void print_freq(uint64_t freq, const char *s) 27 { 28 unsigned long m = 0; 29 uint32_t f; 30 static const char names[] = {'G', 'M', 'K'}; 31 unsigned long d = 1e9; 32 char c = 0; 33 unsigned int i; 34 35 for (i = 0; i < ARRAY_SIZE(names); i++, d /= 1000) { 36 if (freq >= d) { 37 c = names[i]; 38 break; 39 } 40 } 41 42 if (!c) { 43 printf("%" PRIu64 " Hz%s", freq, s); 44 return; 45 } 46 47 f = do_div(freq, d); 48 49 /* If there's a remainder, show the first few digits */ 50 if (f) { 51 m = f; 52 while (m > 1000) 53 m /= 10; 54 while (m && !(m % 10)) 55 m /= 10; 56 if (m >= 100) 57 m = (m / 10) + (m % 100 >= 50); 58 } 59 60 printf("%lu", (unsigned long) freq); 61 if (m) 62 printf(".%ld", m); 63 printf(" %cHz%s", c, s); 64 } 65 66 void print_size(uint64_t size, const char *s) 67 { 68 unsigned long m = 0, n; 69 uint64_t f; 70 static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'}; 71 unsigned long d = 10 * ARRAY_SIZE(names); 72 char c = 0; 73 unsigned int i; 74 75 for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) { 76 if (size >> d) { 77 c = names[i]; 78 break; 79 } 80 } 81 82 if (!c) { 83 printf("%" PRIu64 " Bytes%s", size, s); 84 return; 85 } 86 87 n = size >> d; 88 f = size & ((1ULL << d) - 1); 89 90 /* If there's a remainder, deal with it */ 91 if (f) { 92 m = (10ULL * f + (1ULL << (d - 1))) >> d; 93 94 if (m >= 10) { 95 m -= 10; 96 n += 1; 97 } 98 } 99 100 printf ("%lu", n); 101 if (m) { 102 printf (".%ld", m); 103 } 104 printf (" %ciB%s", c, s); 105 } 106 107 #define MAX_LINE_LENGTH_BYTES (64) 108 #define DEFAULT_LINE_LENGTH_BYTES (16) 109 int print_buffer(ulong addr, const void *data, uint width, uint count, 110 uint linelen) 111 { 112 /* linebuf as a union causes proper alignment */ 113 union linebuf { 114 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 115 uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1]; 116 #endif 117 uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; 118 uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; 119 uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; 120 } lb; 121 int i; 122 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 123 uint64_t __maybe_unused x; 124 #else 125 uint32_t __maybe_unused x; 126 #endif 127 128 if (linelen*width > MAX_LINE_LENGTH_BYTES) 129 linelen = MAX_LINE_LENGTH_BYTES / width; 130 if (linelen < 1) 131 linelen = DEFAULT_LINE_LENGTH_BYTES / width; 132 133 while (count) { 134 uint thislinelen = linelen; 135 printf("%08lx:", addr); 136 137 /* check for overflow condition */ 138 if (count < thislinelen) 139 thislinelen = count; 140 141 /* Copy from memory into linebuf and print hex values */ 142 for (i = 0; i < thislinelen; i++) { 143 if (width == 4) 144 x = lb.ui[i] = *(volatile uint32_t *)data; 145 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 146 else if (width == 8) 147 x = lb.uq[i] = *(volatile uint64_t *)data; 148 #endif 149 else if (width == 2) 150 x = lb.us[i] = *(volatile uint16_t *)data; 151 else 152 x = lb.uc[i] = *(volatile uint8_t *)data; 153 #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 154 printf(" %0*llx", width * 2, (long long)x); 155 #else 156 printf(" %0*x", width * 2, x); 157 #endif 158 data += width; 159 } 160 161 while (thislinelen < linelen) { 162 /* fill line with whitespace for nice ASCII print */ 163 for (i=0; i<width*2+1; i++) 164 puts(" "); 165 linelen--; 166 } 167 168 /* Print data in ASCII characters */ 169 for (i = 0; i < thislinelen * width; i++) { 170 if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80) 171 lb.uc[i] = '.'; 172 } 173 lb.uc[i] = '\0'; 174 printf(" %s\n", lb.uc); 175 176 /* update references */ 177 addr += thislinelen * width; 178 count -= thislinelen; 179 180 if (ctrlc()) 181 return -1; 182 } 183 184 return 0; 185 } 186