/* 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[0];
}  __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;
}
