/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2014 The ChromiumOS Authors.  All rights reserved.
 *
 * 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 <assert.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
#include <reset.h>
#include <string.h>
#include <vb2_api.h>
#include <security/vboot/misc.h>
#include <security/vboot/symbols.h>
#include <security/vboot/vboot_common.h>

struct selected_region {
	uint32_t offset;
	uint32_t size;
};

/*
 * this is placed at the start of the vboot work buffer. selected_region is used
 * for the verstage to return the location of the selected slot. buffer is used
 * by the vboot2 core. Keep the struct CPU architecture agnostic as it crosses
 * stage boundaries.
 */
struct vb2_working_data {
	struct selected_region selected_region;
	/* offset of the buffer from the start of this struct */
	uint32_t buffer_offset;
	uint32_t buffer_size;
};

static const size_t vb_work_buf_size = 16 * KiB;

static struct vb2_working_data * const vboot_get_working_data(void)
{
	if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
		/* cbmem_add() does a cbmem_find() first. */
		return cbmem_add(CBMEM_ID_VBOOT_WORKBUF, vb_work_buf_size);
	else
		return (struct vb2_working_data *)_vboot2_work;
}

static size_t vb2_working_data_size(void)
{
	if (IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE))
		return vb_work_buf_size;
	else
		return _vboot2_work_size;
}

static struct selected_region *vb2_selected_region(void)
{
	struct selected_region *sel_reg = NULL;

	/* Ramstage and postcar always uses cbmem as a source of truth. */
	if (ENV_RAMSTAGE || ENV_POSTCAR)
		sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);
	else if (ENV_ROMSTAGE) {
		/* Try cbmem first. Fall back on working data if not found. */
		sel_reg = cbmem_find(CBMEM_ID_VBOOT_SEL_REG);

		if (sel_reg == NULL) {
			struct vb2_working_data *wd = vboot_get_working_data();
			sel_reg = &wd->selected_region;
		}
	} else {
		/* Stages such as bootblock and verstage use working data. */
		struct vb2_working_data *wd = vboot_get_working_data();
		sel_reg = &wd->selected_region;
	}

	return sel_reg;
}

void vb2_init_work_context(struct vb2_context *ctx)
{
	struct vb2_working_data *wd;
	size_t work_size;

	/* First initialize the working data region. */
	work_size = vb2_working_data_size();
	wd = vboot_get_working_data();
	memset(wd, 0, work_size);

	/*
	 * vboot prefers 16-byte alignment. This takes away 16 bytes
	 * from the VBOOT2_WORK region, but the vboot devs said that's okay.
	 */
	wd->buffer_offset = ALIGN_UP(sizeof(*wd), 16);
	wd->buffer_size = work_size - wd->buffer_offset;

	/* Initialize the vb2_context. */
	memset(ctx, 0, sizeof(*ctx));
	ctx->workbuf = (void *)vb2_get_shared_data();
	ctx->workbuf_size = wd->buffer_size;

}

struct vb2_shared_data *vb2_get_shared_data(void)
{
	struct vb2_working_data *wd = vboot_get_working_data();
	return (void *)((uintptr_t)wd + wd->buffer_offset);
}

int vb2_get_selected_region(struct region *region)
{
	const struct selected_region *reg = vb2_selected_region();

	if (reg == NULL)
		return -1;

	if (reg->offset == 0 && reg->size == 0)
		return -1;

	region->offset = reg->offset;
	region->size = reg->size;

	return 0;
}

void vb2_set_selected_region(const struct region *region)
{
	struct selected_region *reg = vb2_selected_region();

	assert(reg != NULL);

	reg->offset = region_offset(region);
	reg->size = region_sz(region);
}

int vb2_is_slot_selected(void)
{
	const struct selected_region *reg = vb2_selected_region();

	assert(reg != NULL);

	return reg->size > 0;
}

void vb2_store_selected_region(void)
{
	const struct vb2_working_data *wd;
	struct selected_region *sel_reg;

	/* Always use the working data in this path since it's the object
	 * which has the result.. */
	wd = vboot_get_working_data();

	sel_reg = cbmem_add(CBMEM_ID_VBOOT_SEL_REG, sizeof(*sel_reg));

	assert(sel_reg != NULL);

	sel_reg->offset = wd->selected_region.offset;
	sel_reg->size = wd->selected_region.size;
}

/*
 * For platforms that employ VBOOT_STARTS_IN_ROMSTAGE, the vboot
 * verification doesn't happen until after cbmem is brought online.
 * Therefore, the selected region contents would not be initialized
 * so don't automatically add results when cbmem comes online.
 */
#if !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_ROMSTAGE)
static void vb2_store_selected_region_cbmem(int unused)
{
	vb2_store_selected_region();
}
ROMSTAGE_CBMEM_INIT_HOOK(vb2_store_selected_region_cbmem)
#endif
