/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpi.h>
#include <amdblocks/apob_cache.h>
#include <assert.h>
#include <boot_device.h>
#include <bootstate.h>
#include <commonlib/helpers.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <fmap.h>
#include <spi_flash.h>
#include <stdint.h>
#include <string.h>
#include <thread.h>
#include <timestamp.h>

#define DEFAULT_MRC_CACHE "RW_MRC_CACHE"
/* PSP requires this value to be 64KiB */
#define DEFAULT_MRC_CACHE_SIZE 0x10000

#if !CONFIG_PSP_APOB_DRAM_ADDRESS
#error Incorrect APOB configuration setting(s)
#endif

#define APOB_SIGNATURE 0x424F5041	/* 'APOB' */

/* APOB_BASE_HEADER from AGESA */
struct apob_base_header {
	uint32_t   signature;			/* APOB signature */
	uint32_t   version;			/* Version */
	uint32_t   size;			/* APOB Size */
	uint32_t   offset_of_first_entry;	/* APOB Header Size */
};

static bool apob_header_valid(const struct apob_base_header *apob_header_ptr, const char *where)
{
	if (apob_header_ptr->signature != APOB_SIGNATURE) {
		printk(BIOS_WARNING, "Invalid %s APOB signature %x\n",
			where, apob_header_ptr->signature);
		return false;
	}

	if (apob_header_ptr->size == 0 || apob_header_ptr->size > DEFAULT_MRC_CACHE_SIZE) {
		printk(BIOS_WARNING, "%s APOB data is too large %x > %x\n",
			where, apob_header_ptr->size, DEFAULT_MRC_CACHE_SIZE);
		return false;
	}

	return true;
}

static void *get_apob_dram_address(void)
{
	/*
	 * TODO: Find the APOB destination by parsing the PSP's tables
	 * (once vboot is implemented).
	 */
	void *apob_src_ram = (void *)(uintptr_t)CONFIG_PSP_APOB_DRAM_ADDRESS;

	if (apob_header_valid(apob_src_ram, "RAM") == false)
		return NULL;

	return apob_src_ram;
}

static int get_nv_rdev(struct region_device *r)
{
	if  (fmap_locate_area_as_rdev(DEFAULT_MRC_CACHE, r) < 0) {
		printk(BIOS_ERR, "Error: No APOB NV region is found in flash\n");
		return -1;
	}

	return 0;
}

static struct apob_thread_context {
	uint8_t buffer[DEFAULT_MRC_CACHE_SIZE] __attribute__((aligned(64)));
	struct thread_handle handle;
	struct region_device apob_rdev;
} global_apob_thread;

static enum cb_err apob_thread_entry(void *arg)
{
	ssize_t size;
	struct apob_thread_context *thread = arg;

	printk(BIOS_DEBUG, "APOB thread running\n");
	size = rdev_readat(&thread->apob_rdev, thread->buffer, 0,
		    region_device_sz(&thread->apob_rdev));

	printk(BIOS_DEBUG, "APOB thread done\n");

	if (size == region_device_sz(&thread->apob_rdev))
		return CB_SUCCESS;

	return CB_ERR;
}

void start_apob_cache_read(void)
{
	struct apob_thread_context *thread = &global_apob_thread;

	if (!CONFIG(COOP_MULTITASKING))
		return;

	/* We don't perform any comparison on S3 resume */
	if (acpi_is_wakeup_s3())
		return;

	if (get_nv_rdev(&thread->apob_rdev) != 0)
		return;

	assert(ARRAY_SIZE(thread->buffer) == region_device_sz(&thread->apob_rdev));

	printk(BIOS_DEBUG, "Starting APOB preload\n");
	if (thread_run(&thread->handle, apob_thread_entry, thread))
		printk(BIOS_ERR, "Failed to start APOB preload thread\n");
}

static void *get_apob_from_nv_rdev(struct region_device *read_rdev)
{
	struct apob_base_header apob_header;

	if (rdev_readat(read_rdev, &apob_header, 0, sizeof(apob_header)) < 0) {
		printk(BIOS_ERR, "Couldn't read APOB header!\n");
		return NULL;
	}

	if (apob_header_valid(&apob_header, "ROM") == false) {
		printk(BIOS_ERR, "No APOB NV data!\n");
		return NULL;
	}

	assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
	return rdev_mmap_full(read_rdev);
}

/* Save APOB buffer to flash */
static void soc_update_apob_cache(void *unused)
{
	struct apob_base_header *apob_rom;
	struct region_device read_rdev, write_rdev;
	bool update_needed = false;
	const struct apob_base_header *apob_src_ram;

	/* Nothing to update in case of S3 resume. */
	if (acpi_is_wakeup_s3())
		return;

	apob_src_ram = get_apob_dram_address();
	if (apob_src_ram == NULL)
		return;

	if (get_nv_rdev(&read_rdev) != 0)
		return;

	timestamp_add_now(TS_AMD_APOB_READ_START);

	if (CONFIG(COOP_MULTITASKING) && thread_join(&global_apob_thread.handle) == CB_SUCCESS)
		apob_rom = (struct apob_base_header *)global_apob_thread.buffer;
	else
		apob_rom = get_apob_from_nv_rdev(&read_rdev);

	if (apob_rom == NULL) {
		update_needed = true;
	} else if (memcmp(apob_src_ram, apob_rom, apob_src_ram->size)) {
		printk(BIOS_INFO, "APOB RAM copy differs from flash\n");
		update_needed = true;
	} else
		printk(BIOS_DEBUG, "APOB valid copy is already in flash\n");

	if (!update_needed) {
		timestamp_add_now(TS_AMD_APOB_DONE);
		return;
	}

	printk(BIOS_SPEW, "Copy APOB from RAM %p/%#x to flash %#zx/%#zx\n",
		apob_src_ram, apob_src_ram->size,
		region_device_offset(&read_rdev), region_device_sz(&read_rdev));

	if  (fmap_locate_area_as_rdev_rw(DEFAULT_MRC_CACHE, &write_rdev) < 0) {
		printk(BIOS_ERR, "Error: No RW APOB NV region is found in flash\n");
		return;
	}

	timestamp_add_now(TS_AMD_APOB_ERASE_START);

	/* write data to flash region */
	if (rdev_eraseat(&write_rdev, 0, DEFAULT_MRC_CACHE_SIZE) < 0) {
		printk(BIOS_ERR, "Error: APOB flash region erase failed\n");
		return;
	}

	timestamp_add_now(TS_AMD_APOB_WRITE_START);

	if (rdev_writeat(&write_rdev, apob_src_ram, 0, apob_src_ram->size) < 0) {
		printk(BIOS_ERR, "Error: APOB flash region update failed\n");
		return;
	}

	timestamp_add_now(TS_AMD_APOB_DONE);

	printk(BIOS_INFO, "Updated APOB in flash\n");
}

static void *get_apob_nv_address(void)
{
	struct region_device rdev;

	if (get_nv_rdev(&rdev) != 0)
		return NULL;

	return get_apob_from_nv_rdev(&rdev);
}

void *soc_fill_apob_cache(void)
{
	/* If this is non-S3 boot, then use the APOB data placed by PSP in DRAM. */
	if (!acpi_is_wakeup_s3())
		return get_apob_dram_address();

	/*
	 * In case of S3 resume, PSP does not copy APOB data to DRAM. Thus, coreboot needs to
	 * provide the APOB NV data from RW_MRC_CACHE on SPI flash so that FSP can use it
	 * without having to traverse the BIOS directory table.
	 */
	return get_apob_nv_address();
}

/*
 * BS_POST_DEVICE was chosen because this gives start_apob_cache_read plenty of time to read
 * the APOB from SPI.
 */
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, soc_update_apob_cache, NULL);
