// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2020 IBM Corp. */
#include <skiboot.h>
#include "secboot_tpm.h"

/* Offset into the SECBOOT PNOR partition to write "TPMNV" data */
static size_t fakenv_offset = sizeof(struct secboot);

struct fake_tpmnv {
	struct {
		struct secboot_header header;
		char vars[2048]; // Hardcode the size to 2048 for now
	} vars;
	struct tpmnv_control control;
	int defined[2];
} __attribute__((packed));

static struct fake_tpmnv fakenv;
static int tpm_ready;


static inline void *nv_index_address(int index)
{
	switch (index) {
	case SECBOOT_TPMNV_VARS_INDEX:
		return &fakenv.vars;
	case SECBOOT_TPMNV_CONTROL_INDEX:
		return &fakenv.control;
	default:
		return 0;
	}
}


static int tpm_init(void)
{
	int rc;

	if (tpm_ready)
		return 0;

	rc = flash_secboot_read(&fakenv, fakenv_offset, sizeof(struct fake_tpmnv));
	if (rc)
		return rc;

	tpm_ready = 1;

	return 0;
}

static int fakenv_read(TPMI_RH_NV_INDEX nvIndex, void *buf,
		       size_t bufsize,  uint16_t off)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	memcpy(buf, nv_index_address(nvIndex) + off, bufsize);

	return 0;
}

static int fakenv_write(TPMI_RH_NV_INDEX nvIndex, void *buf,
			size_t bufsize, uint16_t off)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	memcpy(nv_index_address(nvIndex) + off, buf, bufsize);

	/* Just write the whole NV struct for now */
	return flash_secboot_write(fakenv_offset, &fakenv, sizeof(struct fake_tpmnv));
}

static int fakenv_definespace(TPMI_RH_NV_INDEX nvIndex, uint16_t dataSize)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	(void) dataSize;

	switch (nvIndex) {
	case SECBOOT_TPMNV_VARS_INDEX:
		fakenv.defined[0] = 1;
		return 0;
	case SECBOOT_TPMNV_CONTROL_INDEX:
		fakenv.defined[1] = 1;
		return 0;
	}

	return OPAL_INTERNAL_ERROR;
}

static int fakenv_writelock(TPMI_RH_NV_INDEX nvIndex)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	(void) nvIndex;

	return 0;
}

static int fakenv_get_defined_indices(TPMI_RH_NV_INDEX **indices, size_t *count)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	*indices = zalloc(sizeof(fakenv.defined));
	if (*indices == NULL)
		return OPAL_NO_MEM;

	*count = 0;

	if (fakenv.defined[0]) {
		*indices[0] = SECBOOT_TPMNV_VARS_INDEX;
		(*count)++;
	}
	if (fakenv.defined[1]) {
		*indices[1] = SECBOOT_TPMNV_CONTROL_INDEX;
		(*count)++;
	}

	return 0;
}

static int fakenv_undefinespace(TPMI_RH_NV_INDEX index)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	switch (index) {
	case SECBOOT_TPMNV_VARS_INDEX:
		fakenv.defined[0] = 0;
		memset(&fakenv.vars, 0, sizeof(fakenv.vars));
		return 0;
	case SECBOOT_TPMNV_CONTROL_INDEX:
		fakenv.defined[1] = 0;
		memset(&fakenv.control, 0, sizeof(fakenv.control));
		return 0;
	}

	return -1;
}

static int fakenv_readpublic(TPMI_RH_NV_INDEX index, TPMS_NV_PUBLIC *nv_public,
			     TPM2B_NAME *nv_name)
{
	if (tpm_init())
		return OPAL_INTERNAL_ERROR;

	(void) nv_public;

	switch (index) {
	case SECBOOT_TPMNV_VARS_INDEX:
		memcpy(&nv_name->t.name, tpmnv_vars_name, sizeof(tpmnv_vars_name));
		break;
	case SECBOOT_TPMNV_CONTROL_INDEX:
		memcpy(&nv_name->t.name, tpmnv_control_name, sizeof(tpmnv_control_name));
		break;
	default:
		return OPAL_INTERNAL_ERROR;
	}

	return 0;
}

struct tpmnv_ops_s tpmnv_ops = {
	.read = fakenv_read,
	.write = fakenv_write,
	.writelock = fakenv_writelock,
	.definespace = fakenv_definespace,
	.getindices = fakenv_get_defined_indices,
	.undefinespace = fakenv_undefinespace,
	.readpublic = fakenv_readpublic,
};
