// SPDX-License-Identifier: GPL-2.0+
/*
 * EFI efi_selftest
 *
 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
 */

#include <efi_selftest.h>
#include <vsprintf.h>

struct efi_simple_text_output_protocol *con_out;
struct efi_simple_input_interface *con_in;

/*
 * Print a MAC address to an u16 string
 *
 * @pointer: mac address
 * @buf: pointer to buffer address
 * on return position of terminating zero word
 */
static void mac(void *pointer, u16 **buf)
{
	int i, j;
	u16 c;
	u8 *p = (u8 *)pointer;
	u8 byte;
	u16 *pos = *buf;

	for (i = 0; i < ARP_HLEN; ++i) {
		if (i)
			*pos++ = ':';
		byte = p[i];
		for (j = 4; j >= 0; j -= 4) {
			c = (byte >> j) & 0x0f;
			c += '0';
			if (c > '9')
				c += 'a' - '9' - 1;
			*pos++ = c;
		}
	}
	*pos = 0;
	*buf = pos;
}

/*
 * Print a pointer to an u16 string
 *
 * @pointer: pointer
 * @buf: pointer to buffer address
 * on return position of terminating zero word
 */
static void pointer(void *pointer, u16 **buf)
{
	int i;
	u16 c;
	uintptr_t p = (uintptr_t)pointer;
	u16 *pos = *buf;

	for (i = 8 * sizeof(p) - 4; i >= 0; i -= 4) {
		c = (p >> i) & 0x0f;
		c += '0';
		if (c > '9')
			c += 'a' - '9' - 1;
		*pos++ = c;
	}
	*pos = 0;
	*buf = pos;
}

/*
 * Print an unsigned 32bit value as decimal number to an u16 string
 *
 * @value: value to be printed
 * @buf: pointer to buffer address
 * on return position of terminating zero word
 */
static void uint2dec(u32 value, u16 **buf)
{
	u16 *pos = *buf;
	int i;
	u16 c;
	u64 f;

	/*
	 * Increment by .5 and multiply with
	 * (2 << 60) / 1,000,000,000 = 0x44B82FA0.9B5A52CC
	 * to move the first digit to bit 60-63.
	 */
	f = 0x225C17D0;
	f += (0x9B5A52DULL * value) >> 28;
	f += 0x44B82FA0ULL * value;

	for (i = 0; i < 10; ++i) {
		/* Write current digit */
		c = f >> 60;
		if (c || pos != *buf)
			*pos++ = c + '0';
		/* Eliminate current digit */
		f &= 0xfffffffffffffff;
		/* Get next digit */
		f *= 0xaULL;
	}
	if (pos == *buf)
		*pos++ = '0';
	*pos = 0;
	*buf = pos;
}

/*
 * Print a signed 32bit value as decimal number to an u16 string
 *
 * @value: value to be printed
 * @buf: pointer to buffer address
 * on return position of terminating zero word
 */
static void int2dec(s32 value, u16 **buf)
{
	u32 u;
	u16 *pos = *buf;

	if (value < 0) {
		*pos++ = '-';
		u = -value;
	} else {
		u = value;
	}
	uint2dec(u, &pos);
	*buf = pos;
}

/*
 * Print a colored formatted string to the EFI console
 *
 * @color	color, see constants in efi_api.h, use -1 for no color
 * @fmt		format string
 * @...		optional arguments
 */
void efi_st_printc(int color, const char *fmt, ...)
{
	va_list args;
	u16 buf[160];
	const char *c;
	u16 *pos = buf;
	const char *s;
	u16 *u;

	va_start(args, fmt);

	if (color >= 0)
		con_out->set_attribute(con_out, (unsigned long)color);
	c = fmt;
	for (; *c; ++c) {
		switch (*c) {
		case '\\':
			++c;
			switch (*c) {
			case '\0':
				--c;
				break;
			case 'n':
				*pos++ = '\n';
				break;
			case 'r':
				*pos++ = '\r';
				break;
			case 't':
				*pos++ = '\t';
				break;
			default:
				*pos++ = *c;
			}
			break;
		case '%':
			++c;
			switch (*c) {
			case '\0':
				--c;
				break;
			case 'd':
				int2dec(va_arg(args, s32), &pos);
				break;
			case 'p':
				++c;
				switch (*c) {
				/* MAC address */
				case 'm':
					mac(va_arg(args, void*), &pos);
					break;

				/* u16 string */
				case 's':
					u = va_arg(args, u16*);
					if (pos > buf) {
						*pos = 0;
						con_out->output_string(con_out,
								       buf);
					}
					con_out->output_string(con_out, u);
					pos = buf;
					break;
				default:
					--c;
					pointer(va_arg(args, void*), &pos);
				}
				break;
			case 's':
				s = va_arg(args, const char *);
				for (; *s; ++s)
					*pos++ = *s;
				break;
			case 'u':
				uint2dec(va_arg(args, u32), &pos);
				break;
			default:
				break;
			}
			break;
		default:
			*pos++ = *c;
		}
	}
	va_end(args);
	*pos = 0;
	con_out->output_string(con_out, buf);
	if (color >= 0)
		con_out->set_attribute(con_out, EFI_LIGHTGRAY);
}

/*
 * Reads an Unicode character from the input device.
 *
 * @return: Unicode character
 */
u16 efi_st_get_key(void)
{
	struct efi_input_key input_key;
	efi_status_t ret;

	/* Wait for next key */
	do {
		ret = con_in->read_key_stroke(con_in, &input_key);
	} while (ret == EFI_NOT_READY);
	return input_key.unicode_char;
}
