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