+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2000-2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
-#include <config.h>
#include <common.h>
+#include <compiler.h>
#include <console.h>
#include <div64.h>
-#include <inttypes.h>
-#include <version.h>
+#include <version_string.h>
#include <linux/ctype.h>
#include <asm/io.h>
-int display_options (void)
+char *display_options_get_banner_priv(bool newlines, const char *build_tag,
+ char *buf, int size)
{
-#if defined(BUILD_TAG)
- printf ("\n\n%s, Build: %s\n\n", version_string, BUILD_TAG);
-#else
- printf ("\n\n%s\n\n", version_string);
+ int len;
+
+ len = snprintf(buf, size, "%s%s", newlines ? "\n\n" : "",
+ version_string);
+ if (build_tag && len < size)
+ len += snprintf(buf + len, size - len, ", Build: %s",
+ build_tag);
+ if (len > size - 3)
+ len = size - 3;
+ if (len < 0)
+ len = 0;
+ snprintf(buf + len, size - len, "\n\n");
+
+ return buf;
+}
+
+#ifndef BUILD_TAG
+#define BUILD_TAG NULL
#endif
+
+char *display_options_get_banner(bool newlines, char *buf, int size)
+{
+ return display_options_get_banner_priv(newlines, BUILD_TAG, buf, size);
+}
+
+int display_options(void)
+{
+ char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
+
+ display_options_get_banner(true, buf, sizeof(buf));
+ printf("%s", buf);
+
return 0;
}
{
unsigned long m = 0;
uint32_t f;
- static const char names[] = {'G', 'M', 'K'};
+ static const char names[] = {'G', 'M', 'k'};
unsigned long d = 1e9;
char c = 0;
unsigned int i;
}
if (!c) {
- printf("%" PRIu64 " Hz%s", freq, s);
+ printf("%llu Hz%s", freq, s);
return;
}
}
if (!c) {
- printf("%" PRIu64 " Bytes%s", size, s);
+ /*
+ * SPL tiny-printf is not capable for printing uint64_t.
+ * We have just checked that the size is small enought to fit
+ * unsigned int safely.
+ */
+ printf("%u Bytes%s", (unsigned int)size, s);
return;
}
printf (" %ciB%s", c, s);
}
-#define MAX_LINE_LENGTH_BYTES (64)
-#define DEFAULT_LINE_LENGTH_BYTES (16)
-int print_buffer(ulong addr, const void *data, uint width, uint count,
- uint linelen)
+#define MAX_LINE_LENGTH_BYTES 64
+#define DEFAULT_LINE_LENGTH_BYTES 16
+
+int hexdump_line(ulong addr, const void *data, uint width, uint count,
+ uint linelen, char *out, int size)
{
/* linebuf as a union causes proper alignment */
union linebuf {
-#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1];
-#endif
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;
+ uint thislinelen;
int i;
-#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
- uint64_t __maybe_unused x;
-#else
- uint32_t __maybe_unused x;
-#endif
+ ulong x;
+
+ if (linelen * width > MAX_LINE_LENGTH_BYTES)
+ linelen = MAX_LINE_LENGTH_BYTES / width;
+ if (linelen < 1)
+ linelen = DEFAULT_LINE_LENGTH_BYTES / width;
+
+ /*
+ * Check the size here so that we don't need to use snprintf(). This
+ * helps to reduce code size
+ */
+ if (size < HEXDUMP_MAX_BUF_LENGTH(linelen * width))
+ return -ENOSPC;
+
+ thislinelen = linelen;
+ out += sprintf(out, "%08lx:", addr);
+
+ /* check for overflow condition */
+ if (count < thislinelen)
+ thislinelen = count;
+
+ /* Copy from memory into linebuf and print hex values */
+ for (i = 0; i < thislinelen; i++) {
+ if (width == 4)
+ x = lb.ui[i] = *(volatile uint32_t *)data;
+ else if (MEM_SUPPORT_64BIT_DATA && width == 8)
+ x = lb.uq[i] = *(volatile ulong *)data;
+ else if (width == 2)
+ x = lb.us[i] = *(volatile uint16_t *)data;
+ else
+ x = lb.uc[i] = *(volatile uint8_t *)data;
+ if (CONFIG_IS_ENABLED(USE_TINY_PRINTF))
+ out += sprintf(out, " %x", (uint)x);
+ else
+ out += sprintf(out, " %0*lx", width * 2, x);
+ data += width;
+ }
+ /* fill line with whitespace for nice ASCII print */
+ for (i = 0; i < (linelen - thislinelen) * (width * 2 + 1); i++)
+ *out++ = ' ';
+
+ /* Print data in ASCII characters */
+ for (i = 0; i < thislinelen * width; i++) {
+ if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
+ lb.uc[i] = '.';
+ }
+ lb.uc[i] = '\0';
+ out += sprintf(out, " %s", lb.uc);
+
+ return thislinelen;
+}
+
+int print_buffer(ulong addr, const void *data, uint width, uint count,
+ uint linelen)
+{
if (linelen*width > MAX_LINE_LENGTH_BYTES)
linelen = MAX_LINE_LENGTH_BYTES / width;
if (linelen < 1)
linelen = DEFAULT_LINE_LENGTH_BYTES / width;
while (count) {
- uint thislinelen = linelen;
- printf("%08lx:", addr);
-
- /* check for overflow condition */
- if (count < thislinelen)
- thislinelen = count;
-
- /* Copy from memory into linebuf and print hex values */
- for (i = 0; i < thislinelen; i++) {
- if (width == 4)
- x = lb.ui[i] = *(volatile uint32_t *)data;
-#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
- else if (width == 8)
- x = lb.uq[i] = *(volatile uint64_t *)data;
-#endif
- else if (width == 2)
- x = lb.us[i] = *(volatile uint16_t *)data;
- else
- x = lb.uc[i] = *(volatile uint8_t *)data;
-#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
- printf(" %0*llx", width * 2, (long long)x);
-#else
- printf(" %0*x", width * 2, x);
-#endif
- data += width;
- }
-
- while (thislinelen < linelen) {
- /* fill line with whitespace for nice ASCII print */
- for (i=0; i<width*2+1; i++)
- puts(" ");
- linelen--;
- }
+ uint thislinelen;
+ char buf[HEXDUMP_MAX_BUF_LENGTH(width * linelen)];
- /* Print data in ASCII characters */
- for (i = 0; i < thislinelen * width; i++) {
- if (!isprint(lb.uc[i]) || lb.uc[i] >= 0x80)
- lb.uc[i] = '.';
- }
- lb.uc[i] = '\0';
- printf(" %s\n", lb.uc);
+ thislinelen = hexdump_line(addr, data, width, count, linelen,
+ buf, sizeof(buf));
+ assert(thislinelen >= 0);
+ puts(buf);
+ putc('\n');
/* update references */
+ data += thislinelen * width;
addr += thislinelen * width;
count -= thislinelen;
- if (ctrlc())
- return -1;
+ if (!IS_ENABLED(CONFIG_SPL_BUILD) && ctrlc())
+ return -EINTR;
}
return 0;