/*
 * This file is part of the coreboot project.
 *
 * Copyright 2015 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <arch/early_variables.h>
#include <bootstate.h>
#include <cbmem.h>
#include <console/console.h>
#include <imd.h>
#include <rules.h>
#include <stage_cache.h>
#include <string.h>

static struct imd imd_stage_cache CAR_GLOBAL = { };

static inline struct imd *imd_get(void)
{
	return car_get_var_ptr(&imd_stage_cache);
}

static void stage_cache_create_empty(void)
{
	struct imd *imd;
	void *base;
	size_t size;

	imd = imd_get();
	stage_cache_external_region(&base, &size);
	imd_handle_init(imd, (void *)(size + (uintptr_t)base));

	printk(BIOS_DEBUG, "External stage cache:\n");
	imd_create_tiered_empty(imd, 4096, 4096, 1024, 32);
	if (imd_limit_size(imd, size))
		printk(BIOS_DEBUG, "Could not limit stage cache size.\n");
}

static void stage_cache_recover(void)
{
	struct imd *imd;
	void *base;
	size_t size;

	imd = imd_get();
	stage_cache_external_region(&base, &size);
	imd_handle_init(imd, (void *)(size + (uintptr_t)base));
	if (imd_recover(imd))
		printk(BIOS_DEBUG, "Unable to recover external stage cache.\n");
}

void stage_cache_add(int stage_id, const struct prog *stage)
{
	struct imd *imd;
	const struct imd_entry *e;
	struct stage_cache *meta;
	void *c;

	imd = imd_get();
	e = imd_entry_add(imd, CBMEM_ID_STAGEx_META + stage_id, sizeof(*meta));

	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't add %x metadata to imd\n",
				CBMEM_ID_STAGEx_META + stage_id);
		return;
	}

	meta = imd_entry_at(imd, e);

	meta->load_addr = (uintptr_t)prog_start(stage);
	meta->entry_addr = (uintptr_t)prog_entry(stage);
	meta->arg = (uintptr_t)prog_entry_arg(stage);

	e = imd_entry_add(imd, CBMEM_ID_STAGEx_CACHE + stage_id,
				prog_size(stage));

	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't add stage_cache %x to imd\n",
				CBMEM_ID_STAGEx_CACHE + stage_id);
		return;
	}

	c = imd_entry_at(imd, e);

	memcpy(c, prog_start(stage), prog_size(stage));
}

void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
{
	struct imd *imd;
	const struct imd_entry *e;
	void *c;

	imd = imd_get();
	e = imd_entry_add(imd, CBMEM_ID_STAGEx_RAW + stage_id, size);
	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't add %x raw data to imd\n",
				CBMEM_ID_STAGEx_RAW + stage_id);
		return;
	}

	c = imd_entry_at(imd, e);
	if (c == NULL) {
		printk(BIOS_DEBUG, "Error: Can't get %x raw entry in imd\n",
				CBMEM_ID_STAGEx_RAW + stage_id);
		return;
	}

	memcpy(c, base, size);
}

void stage_cache_get_raw(int stage_id, void **base, size_t *size)
{
	struct imd *imd;
	const struct imd_entry *e;

	imd = imd_get();
	e = imd_entry_find(imd, CBMEM_ID_STAGEx_RAW + stage_id);
	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't find %x raw data to imd\n",
				CBMEM_ID_STAGEx_RAW + stage_id);
		return;
	}

	*base = imd_entry_at(imd, e);
	*size = imd_entry_size(imd, e);
}

void stage_cache_load_stage(int stage_id, struct prog *stage)
{
	struct imd *imd;
	struct stage_cache *meta;
	const struct imd_entry *e;
	void *c;
	size_t size;

	imd = imd_get();
	e = imd_entry_find(imd, CBMEM_ID_STAGEx_META + stage_id);
	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't find %x metadata in imd\n",
				CBMEM_ID_STAGEx_META + stage_id);
		return;
	}

	meta = imd_entry_at(imd, e);

	e = imd_entry_find(imd, CBMEM_ID_STAGEx_CACHE + stage_id);

	if (e == NULL) {
		printk(BIOS_DEBUG, "Error: Can't find stage_cache %x in imd\n",
				CBMEM_ID_STAGEx_CACHE + stage_id);
		return;
	}

	c = imd_entry_at(imd, e);
	size = imd_entry_size(imd, e);

	memcpy((void *)(uintptr_t)meta->load_addr, c, size);

	prog_set_area(stage, (void *)(uintptr_t)meta->load_addr, size);
	prog_set_entry(stage, (void *)(uintptr_t)meta->entry_addr,
			(void *)(uintptr_t)meta->arg);
}

static void stage_cache_setup(int is_recovery)
{
	if (is_recovery)
		stage_cache_recover();
	else
		stage_cache_create_empty();
}

ROMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)
RAMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)
POSTCAR_CBMEM_INIT_HOOK(stage_cache_setup)
