/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootstate.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
#include <soc/intel/common/mma.h>
#include <string.h>

#define MMA_TEST_METADATA_FILENAME	"mma_test_metadata.bin"
#define MMA_TEST_NAME_TAG		"MMA_TEST_NAME"
#define MMA_TEST_PARAM_TAG		"MMA_TEST_PARAM"
#define TEST_NAME_MAX_SIZE		30
#define TEST_PARAM_MAX_SIZE		100
#define MMA_DATA_SIGNATURE		(('M' << 0) | ('M' << 8) | \
					('A' << 16) | ('D' << 24))

struct mma_data_container {
	uint32_t mma_signature; /* "MMAD" */
	uint8_t mma_data[0]; /* Variable size, platform/run time dependent. */
} __packed;

/*
 * Format of the MMA test metadata file, stored under CBFS
 * MMA_TEST_NAME=xxxxxx.efi;MMA_TEST_PARAM=xxxxxx.bin;
 */

/* Returns index in haystack after 'LABEL='
 * string is found, < 0 on error.
 */
static int find_label(const char *haystack, size_t haystack_sz,
		const char *label)
{
	size_t label_sz;
	size_t i;
	size_t search_sz;

	label_sz = strlen(label);

	if (label_sz + 1 >= haystack_sz)
		return -1;

	/* Handle '=' follow label. i.e. LABEL= */
	search_sz = haystack_sz - label_sz - 1;
	for (i = 0; i < search_sz; i++) {
		if (!strncmp(&haystack[i], label, label_sz))
			break;
	}

	if (i == search_sz)
		return -1;

	if (haystack[i + label_sz] != '=')
		return -1;

	return i + label_sz + 1;
}

/*
 * Fill in value in dest field located by LABEL=.
 * Returns 0 on success, < 0 on  error.
 */
static int label_value(const char *haystack, size_t haystack_sz,
		const char *label, char *dest, size_t dest_sz)
{
	size_t val_begin;
	size_t val_end;
	size_t val_sz;
	int val_index;

	memset(dest, 0, dest_sz);

	/* Allow for NULL termination. */
	dest_sz--;
	val_index = find_label(haystack, haystack_sz, label);
	if (val_index < 0)
		return -1;

	val_begin = val_index;
	val_end = val_begin;
	val_sz = 0;

	for (val_end = val_begin; val_end < haystack_sz; val_end++) {
		if (haystack[val_end] == ';') {
			val_sz = val_end - val_begin;
			break;
		}
	}

	if (val_end == haystack_sz)
		return -1;

	if (dest_sz < val_sz)
		return -1;

	memcpy(dest, &haystack[val_begin], val_sz);

	return 0;
}

int mma_map_param(struct mma_config_param *mma_cfg)
{
	void *mma_test_metadata;
	size_t mma_test_metadata_file_len;
	char test_filename[TEST_NAME_MAX_SIZE],
		test_param_filename[TEST_PARAM_MAX_SIZE];
	bool metadata_parse_flag = true;

	printk(BIOS_DEBUG, "MMA: Entry %s\n", __func__);

	mma_test_metadata = cbfs_ro_map(MMA_TEST_METADATA_FILENAME,
					&mma_test_metadata_file_len);
	if (!mma_test_metadata) {
		printk(BIOS_DEBUG, "MMA: Failed to map %s\n",
				MMA_TEST_METADATA_FILENAME);
		return -1;
	}

	if (label_value(mma_test_metadata, mma_test_metadata_file_len,
			MMA_TEST_NAME_TAG, test_filename,
				TEST_NAME_MAX_SIZE)) {
		printk(BIOS_DEBUG, "MMA: Failed to get %s\n",
				MMA_TEST_NAME_TAG);
		metadata_parse_flag = false;
	}

	if (metadata_parse_flag &&
		label_value(mma_test_metadata, mma_test_metadata_file_len,
			MMA_TEST_PARAM_TAG, test_param_filename,
				TEST_PARAM_MAX_SIZE)) {
		printk(BIOS_DEBUG, "MMA: Failed to get %s\n",
			MMA_TEST_PARAM_TAG);
		metadata_parse_flag = false;
	}

	cbfs_unmap(mma_test_metadata);

	if (!metadata_parse_flag)
		return -1;

	printk(BIOS_DEBUG, "MMA: Got MMA_TEST_NAME=%s MMA_TEST_PARAM=%s\n",
			test_filename, test_param_filename);

	mma_cfg->test_content = cbfs_ro_map(test_filename, &mma_cfg->test_content_size);
	if (!mma_cfg->test_content) {
		printk(BIOS_DEBUG, "MMA: Failed to map %s\n", test_filename);
		return -1;
	}

	mma_cfg->test_param = cbfs_ro_map(test_param_filename, &mma_cfg->test_param_size);
	if (!mma_cfg->test_param) {
		printk(BIOS_DEBUG, "MMA: Failed to map %s\n", test_param);
		return -1;
	}

	printk(BIOS_DEBUG, "MMA: %s exit success\n", __func__);

	return 0;
}

static void save_mma_results_data(void *unused)
{
	const void *mma_hob;
	size_t mma_hob_size;
	struct mma_data_container *mma_data;
	size_t mma_data_size;

	printk(BIOS_DEBUG, "MMA: Entry %s\n", __func__);

	if (fsp_locate_mma_results(&mma_hob, &mma_hob_size)) {
		printk(BIOS_DEBUG,
				"MMA: results data Hob not present\n");
		return;
	}

	mma_data_size = ALIGN(mma_hob_size, 16) +
			sizeof(struct mma_data_container);

	mma_data = cbmem_add(CBMEM_ID_MMA_DATA, mma_data_size);

	if (mma_data == NULL) {
		printk(BIOS_DEBUG,
			"MMA: CBMEM was not available to save the MMA data.\n");
		return;
	}

	/*clear the mma_data before coping the actual data */
	memset(mma_data, 0, mma_data_size);

	printk(BIOS_DEBUG,
		"MMA: copy MMA data to CBMEM(src %p, dest %p, %u bytes)\n",
			mma_hob, mma_data, mma_hob_size);

	mma_data->mma_signature = MMA_DATA_SIGNATURE;
	memcpy(mma_data->mma_data, mma_hob, mma_hob_size);

	printk(BIOS_DEBUG, "MMA: %s exit successfully\n", __func__);
}

BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
			save_mma_results_data, NULL);
