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

/*
 * This file provides a custom boot media device for the platforms that support additional
 * window for BIOS regions greater than 16MiB. If the mainboard uses a smaller BIOS region, then
 * the additional window is unused.
 */

#include <boot_device.h>
#include <commonlib/region.h>
#include <console/console.h>
#include <fmap.h>
#include <intelblocks/fast_spi.h>
#include <spi_flash.h>

enum window_type {
	/* Fixed decode window of max 16MiB size just below 4G boundary */
	FIXED_DECODE_WINDOW,
	/* Additional decode window for mapping BIOS region greater than 16MiB */
	EXT_BIOS_DECODE_WINDOW,
	TOTAL_DECODE_WINDOWS,
};

static struct xlate_region_device real_dev;
static struct mem_region_device shadow_devs[TOTAL_DECODE_WINDOWS];
static struct xlate_window real_dev_windows[TOTAL_DECODE_WINDOWS];

static void initialize_window(enum window_type type, uintptr_t host_base,
			      uintptr_t flash_base, size_t size)
{
	mem_region_device_ro_init(&shadow_devs[type], (void *)host_base, size);
	xlate_window_init(&real_dev_windows[type], &shadow_devs[type].rdev,
			  flash_base, size);
	printk(BIOS_INFO, "MMAP window: SPI flash base=0x%lx, Host base=0x%lx, Size=0x%zx\n",
	       flash_base, host_base, size);
}

/*
 *
 *                                                                      +--------------+
 *                                                                      |              |
 *                                                                      |              |
 *                                                                      |              |
 *      ^     +------------+--------------------------^--------------------------------+ 0xffffffff
 *      |     |            |                          |                 |              |
 *      |     |            |                          |                 |              |
 *      |     |            |                          +                 | FIXED        |
 *      |     |            |                     fixed_win_size         | DECODE       |
 *      |     |  BIOS      |                          +                 | WINDOW       |
 *      +     |  region    |                          |                 |              |
 *  bios_size | (Region 1) |                          |                 |              |
 *      +     |            |                          |                 |              |
 *      |     |            |                          |                 |              |
 *      |     |            | fixed_win_flash_base+----v--------------------------------+ fixed_win_host_base
 *      |     |            |                     |                      |              |
 *      |     |            |                     |                      |              |
 *      |     |            |                     |                      | Other MMIO   |
 *      v     |            |                     |                      |              |
 * bios_start +------------+ ext_win_flash_base  |                      |              |
 *            |            |            +        |                      |              |
 *            |            |            |        |                      |              |
 *            |            |            |        |                      |              |
 *            |            |            |        +-----^------------------------------------------------------------^
 *          0 +------------+            |              |                |              |                            |
 *                                      |              +                | EXT_BIOS     |                            |
 *            SPI flash                 |         ext_win_size          | DECODE       |                            |
 *            address                   |              +                | WINDOW       |                            +
 *            space                     |              |                |              |                    CONFIG_EXT_BIOS_WIN_SIZE
 *                                      +--------------v-------------------------------+ ext_win_host_base          +
 *                                                                      |              |                            |
 *                                                                      | Unused       |                            |
 *                                                                      |              |                            |
 *                                                                      +--------------+ CONFIG_EXT_BIOS_WIN_BASE+--v
 *                                                                      |              |
 *                                                                      |              |
 *                                                                      |              |
 *                                                                      +--------------+
 *
 *                                                                       Host address
 *                                                                       space
 */
static void bios_mmap_init(void)
{
	static bool init_done;

	size_t bios_size, bios_start;

	uintptr_t fixed_win_host_base, fixed_win_flash_base;
	uintptr_t ext_win_host_base, ext_win_flash_base;
	size_t fixed_win_size, ext_win_size;

	size_t win_count = 0;

	if (init_done)
		return;

	/* Read the offset and size of BIOS region in the SPI flash address space. */
	bios_start = fast_spi_get_bios_region(&bios_size);

	/*
	 * By default, fixed decode window (maximum size 16MiB) is mapped just below the 4G
	 * boundary. This window maps the top part of the BIOS region in the SPI flash address
	 * space to the host address space.
	 */
	fixed_win_size = MIN(16 * MiB, bios_size);
	fixed_win_host_base = 4ULL * GiB - fixed_win_size;
	fixed_win_flash_base = bios_start + bios_size - fixed_win_size;

	initialize_window(FIXED_DECODE_WINDOW, fixed_win_host_base, fixed_win_flash_base,
			  fixed_win_size);
	win_count++;

	_Static_assert(CONFIG_EXT_BIOS_WIN_BASE != 0, "Extended BIOS window base cannot be 0!");
	_Static_assert(CONFIG_EXT_BIOS_WIN_SIZE != 0, "Extended BIOS window size cannot be 0!");

	/*
	 * Remaining portion of the BIOS region up to a maximum of CONFIG_EXT_BIOS_WIN_SIZE is
	 * mapped at the top of the extended window if the BIOS region is greater than 16MiB.
	 *
	 * If the BIOS region is not greater than 16MiB, then the extended window is not
	 * enabled.
	 */
	ext_win_size = MIN(CONFIG_EXT_BIOS_WIN_SIZE, bios_size - fixed_win_size);

	if (ext_win_size) {
		ext_win_host_base = CONFIG_EXT_BIOS_WIN_BASE + CONFIG_EXT_BIOS_WIN_SIZE -
			ext_win_size;
		ext_win_flash_base = fixed_win_flash_base - ext_win_size;
		initialize_window(EXT_BIOS_DECODE_WINDOW, ext_win_host_base,
				  ext_win_flash_base, ext_win_size);
		win_count++;
	}

	xlate_region_device_ro_init(&real_dev, win_count, real_dev_windows, CONFIG_ROM_SIZE);

	init_done = true;
}

const struct region_device *boot_device_ro(void)
{
	bios_mmap_init();

	return &real_dev.rdev;
}

void fast_spi_get_ext_bios_window(uintptr_t *base, size_t *size)
{
	const struct region_device *rd = &shadow_devs[EXT_BIOS_DECODE_WINDOW].rdev;

	bios_mmap_init();

	*size = region_device_sz(rd);

	if (*size == 0) {
		*base = 0;
	} else {
		/*
		 * This is a memory region device. So, mmap returns the base address of the
		 * device. Also, as this is a memory region device, unmap is a no-op.
		 */
		*base = (uintptr_t)rdev_mmap_full(rd);
	}
}

uint32_t spi_flash_get_mmap_windows(struct flash_mmap_window *table)
{
	int i;
	uint32_t count = 0;

	bios_mmap_init();

	for (i = 0; i < TOTAL_DECODE_WINDOWS; i++) {

		if (region_sz(&real_dev_windows[i].sub_region) == 0)
			continue;

		count++;
		table->flash_base = region_offset(&real_dev_windows[i].sub_region);
		table->host_base = (uintptr_t)rdev_mmap_full(&shadow_devs[i].rdev);
		table->size = region_sz(&real_dev_windows[i].sub_region);

		table++;
	}

	return count;
}
