/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/cbmem_console.h>
#include <console/console.h>
#include <console/uart.h>
#include <cbmem.h>
#include <symbols.h>
#include <types.h>

/*
 * Structure describing console buffer. It is overlaid on a flat memory area,
 * with body covering the extent of the memory. Once the buffer is full,
 * output will wrap back around to the start of the buffer. The high bit of the
 * cursor field gets set to indicate that this happened. If the underlying
 * storage allows this, the buffer will persist across multiple boots and append
 * to the previous log.
 *
 * NOTE: These are known implementations accessing this console that need to be
 * updated in case of structure/API changes:
 *
 * cbmem:	[coreboot]/src/util/cbmem/cbmem.c
 * libpayload:	[coreboot]/payloads/libpayload/drivers/cbmem_console.c
 * coreinfo:	[coreboot]/payloads/coreinfo/bootlog_module.c
 * Linux:	drivers/firmware/google/memconsole-coreboot.c
 * SeaBIOS:	src/firmware/coreboot.c
 * GRUB:	grub-core/term/i386/coreboot/cbmemc.c
 */
struct cbmem_console {
	u32 size;
	u32 cursor;
	u8  body[];
}  __packed;

#define MAX_SIZE (1 << 28)	/* can't be changed without breaking readers! */
#define CURSOR_MASK (MAX_SIZE - 1)	/* bits 31-28 are reserved for flags */
#define OVERFLOW (1UL << 31)		/* set if in ring-buffer mode */
_Static_assert(CONFIG_CONSOLE_CBMEM_BUFFER_SIZE <= MAX_SIZE,
	"cbmem_console format cannot support buffers larger than 256MB!");

static struct cbmem_console *current_console;

static bool console_paused;

/*
 * While running from ROM, before DRAM is initialized, some area in cache as
 * RAM space is used for the console buffer storage. The size and location of
 * the area are defined by the linker script with _(e)preram_cbmem_console.
 *
 * When running from RAM, some console output is generated before CBMEM is
 * reinitialized. This static buffer is used to store that output temporarily,
 * to be concatenated with the CBMEM console buffer contents accumulated
 * during the ROM stage, once CBMEM becomes available at RAM stage.
 */

#define STATIC_CONSOLE_SIZE 1024
static u8 static_console[STATIC_CONSOLE_SIZE];

static int buffer_valid(struct cbmem_console *cbm_cons_p, u32 total_space)
{
	return (cbm_cons_p->cursor & CURSOR_MASK) < cbm_cons_p->size &&
	       cbm_cons_p->size <= MAX_SIZE &&
	       cbm_cons_p->size == total_space - sizeof(struct cbmem_console);
}

static void init_console_ptr(void *storage, u32 total_space)
{
	struct cbmem_console *cbm_cons_p = storage;

	if (!cbm_cons_p || total_space <= sizeof(struct cbmem_console)) {
		current_console = NULL;
		return;
	}

	if (!buffer_valid(cbm_cons_p, total_space)) {
		cbm_cons_p->size = total_space - sizeof(struct cbmem_console);
		cbm_cons_p->cursor = 0;
	}

	current_console = cbm_cons_p;
}

void cbmemc_init(void)
{
	if (ENV_ROMSTAGE_OR_BEFORE) {
		/* Pre-RAM environments use special buffer placed by linker script. */
		init_console_ptr(_preram_cbmem_console, REGION_SIZE(preram_cbmem_console));
	} else if (ENV_SMM) {
		void *cbmemc = NULL;
		size_t cbmemc_size = 0;

		smm_get_cbmemc_buffer(&cbmemc, &cbmemc_size);

		init_console_ptr(cbmemc, cbmemc_size);
	} else {
		/* Post-RAM uses static (BSS) buffer before CBMEM is reinitialized. */
		init_console_ptr(static_console, sizeof(static_console));
	}
}

void cbmemc_tx_byte(unsigned char data)
{
	if (!current_console || !current_console->size || console_paused)
		return;

	u32 flags = current_console->cursor & ~CURSOR_MASK;
	u32 cursor = current_console->cursor & CURSOR_MASK;

	current_console->body[cursor++] = data;
	if (cursor >= current_console->size) {
		cursor = 0;
		flags |= OVERFLOW;
	}

	current_console->cursor = flags | cursor;
}

/*
 * Copy the current console buffer (either from the cache as RAM area or from
 * the static buffer, pointed at by src_cons_p) into the newly initialized CBMEM
 * console. The use of cbmemc_tx_byte() ensures that all special cases for the
 * target console (e.g. overflow) will be handled. If there had been an
 * overflow in the source console, log a message to that effect.
 */
static void copy_console_buffer(struct cbmem_console *src_cons_p)
{
	u32 c;

	if (!src_cons_p)
		return;

	if (src_cons_p->cursor & OVERFLOW) {
		const char overflow_warning[] = "\n*** Pre-CBMEM " ENV_STRING
			" console overflowed, log truncated! ***\n";
		for (c = 0; c < sizeof(overflow_warning) - 1; c++)
			cbmemc_tx_byte(overflow_warning[c]);
		for (c = src_cons_p->cursor & CURSOR_MASK;
		     c < src_cons_p->size; c++)
			cbmemc_tx_byte(src_cons_p->body[c]);
	}

	for (c = 0; c < (src_cons_p->cursor & CURSOR_MASK); c++)
		cbmemc_tx_byte(src_cons_p->body[c]);

	/* Invalidate the source console, so it will be reinitialized on the
	   next reboot. Otherwise, we might copy the same bytes again. */
	src_cons_p->size = 0;
}

void cbmemc_copy_in(void *buffer, size_t size)
{
	struct cbmem_console *previous = (void *)buffer;

	if (!buffer_valid(previous, size))
		return;

	copy_console_buffer(previous);
}

static void cbmemc_reinit(int is_recovery)
{
	const size_t size = CONFIG_CONSOLE_CBMEM_BUFFER_SIZE;
	/* If CBMEM entry already existed, old contents are not altered. */
	struct cbmem_console *cbmem_cons_p = cbmem_add(CBMEM_ID_CONSOLE, size);
	struct cbmem_console *previous_cons_p = current_console;

	init_console_ptr(cbmem_cons_p, size);
	copy_console_buffer(previous_cons_p);
}

/* Run this hook early so that the console region is one of the earliest created, and
   therefore more likely to stay in the same place even across different boot modes where some
   other regions may sometimes not get created (e.g. RW_MCACHE in vboot recovery mode). */
CBMEM_READY_HOOK_EARLY(cbmemc_reinit);

#if CONFIG(CONSOLE_CBMEM_DUMP_TO_UART)
void cbmem_dump_console_to_uart(void)
{
	u32 cursor;
	unsigned int console_index;

	if (!current_console)
		return;

	console_index = get_uart_for_console();

	uart_init(console_index);
	if (current_console->cursor & OVERFLOW) {
		for (cursor = current_console->cursor & CURSOR_MASK;
		     cursor < current_console->size; cursor++) {
			if (BIOS_LOG_IS_MARKER(current_console->body[cursor]))
				continue;
			if (current_console->body[cursor] == '\n')
				uart_tx_byte(console_index, '\r');
			uart_tx_byte(console_index, current_console->body[cursor]);
		}
	}
	for (cursor = 0; cursor < (current_console->cursor & CURSOR_MASK); cursor++) {
		if (BIOS_LOG_IS_MARKER(current_console->body[cursor]))
			continue;
		if (current_console->body[cursor] == '\n')
			uart_tx_byte(console_index, '\r');
		uart_tx_byte(console_index, current_console->body[cursor]);
	}
}
#endif

void cbmem_dump_console(void)
{
	u32 cursor;
	if (!current_console)
		return;

	console_paused = true;

	if (current_console->cursor & OVERFLOW)
		for (cursor = current_console->cursor & CURSOR_MASK;
		     cursor < current_console->size; cursor++)
			if (!BIOS_LOG_IS_MARKER(current_console->body[cursor]))
				do_putchar(current_console->body[cursor]);
	for (cursor = 0; cursor < (current_console->cursor & CURSOR_MASK); cursor++)
		if (!BIOS_LOG_IS_MARKER(current_console->body[cursor]))
			do_putchar(current_console->body[cursor]);

	console_paused = false;
}
