1 /* 2 * (C) Copyright 2000-2002 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <config.h> 25 #include <common.h> 26 #include <linux/ctype.h> 27 #include <asm/io.h> 28 29 int display_options (void) 30 { 31 extern char version_string[]; 32 33 #if defined(BUILD_TAG) 34 printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG); 35 #else 36 printf ("\n\n%s\n\n", version_string); 37 #endif 38 return 0; 39 } 40 41 /* 42 * print sizes as "xxx KiB", "xxx.y KiB", "xxx MiB", "xxx.y MiB", 43 * xxx GiB, xxx.y GiB, etc as needed; allow for optional trailing string 44 * (like "\n") 45 */ 46 void print_size(unsigned long long size, const char *s) 47 { 48 unsigned long m = 0, n; 49 unsigned long long f; 50 static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'}; 51 unsigned long d = 10 * ARRAY_SIZE(names); 52 char c = 0; 53 unsigned int i; 54 55 for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) { 56 if (size >> d) { 57 c = names[i]; 58 break; 59 } 60 } 61 62 if (!c) { 63 printf("%llu Bytes%s", size, s); 64 return; 65 } 66 67 n = size >> d; 68 f = size & ((1ULL << d) - 1); 69 70 /* If there's a remainder, deal with it */ 71 if (f) { 72 m = (10ULL * f + (1ULL << (d - 1))) >> d; 73 74 if (m >= 10) { 75 m -= 10; 76 n += 1; 77 } 78 } 79 80 printf ("%lu", n); 81 if (m) { 82 printf (".%ld", m); 83 } 84 printf (" %ciB%s", c, s); 85 } 86 87 /* 88 * Print data buffer in hex and ascii form to the terminal. 89 * 90 * data reads are buffered so that each memory address is only read once. 91 * Useful when displaying the contents of volatile registers. 92 * 93 * parameters: 94 * addr: Starting address to display at start of line 95 * data: pointer to data buffer 96 * width: data value width. May be 1, 2, or 4. 97 * count: number of values to display 98 * linelen: Number of values to print per line; specify 0 for default length 99 */ 100 #define MAX_LINE_LENGTH_BYTES (64) 101 #define DEFAULT_LINE_LENGTH_BYTES (16) 102 int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen) 103 { 104 /* linebuf as a union causes proper alignment */ 105 union linebuf { 106 uint32_t ui[MAX_LINE_LENGTH_BYTES/sizeof(uint32_t) + 1]; 107 uint16_t us[MAX_LINE_LENGTH_BYTES/sizeof(uint16_t) + 1]; 108 uint8_t uc[MAX_LINE_LENGTH_BYTES/sizeof(uint8_t) + 1]; 109 } lb; 110 int i; 111 112 if (linelen*width > MAX_LINE_LENGTH_BYTES) 113 linelen = MAX_LINE_LENGTH_BYTES / width; 114 if (linelen < 1) 115 linelen = DEFAULT_LINE_LENGTH_BYTES / width; 116 117 while (count) { 118 printf("%08lx:", addr); 119 120 /* check for overflow condition */ 121 if (count < linelen) 122 linelen = count; 123 124 /* Copy from memory into linebuf and print hex values */ 125 for (i = 0; i < linelen; i++) { 126 uint32_t x; 127 if (width == 4) 128 x = lb.ui[i] = *(volatile uint32_t *)data; 129 else if (width == 2) 130 x = lb.us[i] = *(volatile uint16_t *)data; 131 else 132 x = lb.uc[i] = *(volatile uint8_t *)data; 133 printf(" %0*x", width * 2, x); 134 data += width; 135 } 136 137 /* Print data in ASCII characters */ 138 for (i = 0; i < linelen * width; i++) { 139 if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80) 140 lb.uc[i] = '.'; 141 } 142 lb.uc[i] = '\0'; 143 printf(" %s\n", lb.uc); 144 145 /* update references */ 146 addr += linelen * width; 147 count -= linelen; 148 149 if (ctrlc()) 150 return -1; 151 } 152 153 return 0; 154 } 155