// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000-2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#include <common.h>
#include <compiler.h>
#include <console.h>
#include <div64.h>
#include <version_string.h>
#include <linux/ctype.h>
#include <asm/io.h>

char *display_options_get_banner_priv(bool newlines, const char *build_tag,
				      char *buf, int size)
{
	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;
}

void print_freq(uint64_t freq, const char *s)
{
	unsigned long m = 0;
	uint32_t f;
	static const char names[] = {'G', 'M', 'k'};
	unsigned long d = 1e9;
	char c = 0;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(names); i++, d /= 1000) {
		if (freq >= d) {
			c = names[i];
			break;
		}
	}

	if (!c) {
		printf("%llu Hz%s", freq, s);
		return;
	}

	f = do_div(freq, d);

	/* If there's a remainder, show the first few digits */
	if (f) {
		m = f;
		while (m > 1000)
			m /= 10;
		while (m && !(m % 10))
			m /= 10;
		if (m >= 100)
			m = (m / 10) + (m % 100 >= 50);
	}

	printf("%lu", (unsigned long) freq);
	if (m)
		printf(".%ld", m);
	printf(" %cHz%s", c, s);
}

void print_size(uint64_t size, const char *s)
{
	unsigned long m = 0, n;
	uint64_t f;
	static const char names[] = {'E', 'P', 'T', 'G', 'M', 'K'};
	unsigned long d = 10 * ARRAY_SIZE(names);
	char c = 0;
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(names); i++, d -= 10) {
		if (size >> d) {
			c = names[i];
			break;
		}
	}

	if (!c) {
		/*
		 * 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;
	}

	n = size >> d;
	f = size & ((1ULL << d) - 1);

	/* If there's a remainder, deal with it */
	if (f) {
		m = (10ULL * f + (1ULL << (d - 1))) >> d;

		if (m >= 10) {
			m -= 10;
			n += 1;
		}
	}

	printf ("%lu", n);
	if (m) {
		printf (".%ld", m);
	}
	printf (" %ciB%s", c, s);
}

#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 {
		uint64_t uq[MAX_LINE_LENGTH_BYTES/sizeof(uint64_t) + 1];
		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;
	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;
		char buf[HEXDUMP_MAX_BUF_LENGTH(width * linelen)];

		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 (!IS_ENABLED(CONFIG_SPL_BUILD) && ctrlc())
			return -EINTR;
	}

	return 0;
}
