/*
 * Read a coreboot rmodule and execute it.
 * The rmodule_header struct is from coreboot.
 *
 * Copyright (c) 2016 Google, Inc
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <errno.h>
#include <asm/arch/pei_data.h>

#define RMODULE_MAGIC		0xf8fe
#define RMODULE_VERSION_1	1

/*
 * All fields with '_offset' in the name are byte offsets into the flat blob.
 * The linker and the linker script takes are of assigning the values.
 */
struct rmodule_header {
	uint16_t magic;
	uint8_t version;
	uint8_t type;
	/* The payload represents the program's loadable code and data */
	uint32_t payload_begin_offset;
	uint32_t payload_end_offset;
	/* Begin and of relocation information about the program module */
	uint32_t relocations_begin_offset;
	uint32_t relocations_end_offset;
	/*
	 * The starting address of the linked program. This address is vital
	 * for determining relocation offsets as the relocation info and other
	 * symbols (bss, entry point) need this value as a basis to calculate
	 * the offsets.
	 */
	uint32_t module_link_start_address;
	/*
	 * The module_program_size is the size of memory used while running
	 * the program. The program is assumed to consume a contiguous amount
	 * of memory
	 */
	uint32_t module_program_size;
	/* This is program's execution entry point */
	uint32_t module_entry_point;
	/*
	 * Optional parameter structure that can be used to pass data into
	 * the module
	 */
	uint32_t parameters_begin;
	uint32_t parameters_end;
	/* BSS section information so the loader can clear the bss */
	uint32_t bss_begin;
	uint32_t bss_end;
	/* Add some room for growth */
	uint32_t padding[4];
} __packed;

int cpu_run_reference_code(void)
{
	struct pei_data _pei_data __aligned(8);
	struct pei_data *pei_data = &_pei_data;
	asmlinkage int (*func)(void *);
	struct rmodule_header *hdr;
	char *src, *dest;
	int ret, dummy;
	int size;

	hdr = (struct rmodule_header *)CONFIG_X86_REFCODE_ADDR;
	debug("Extracting code from rmodule at %p\n", hdr);
	if (hdr->magic != RMODULE_MAGIC) {
		debug("Invalid rmodule magic\n");
		return -EINVAL;
	}
	if (hdr->module_link_start_address != 0) {
		debug("Link start address must be 0\n");
		return -EPERM;
	}
	if (hdr->module_entry_point != 0) {
		debug("Entry point must be 0\n");
		return -EPERM;
	}

	memset(pei_data, '\0', sizeof(struct pei_data));
	broadwell_fill_pei_data(pei_data);
	mainboard_fill_pei_data(pei_data);
	pei_data->saved_data = (void *)&dummy;

	src = (char *)hdr + hdr->payload_begin_offset;
	dest = (char *)CONFIG_X86_REFCODE_RUN_ADDR;

	size = hdr->payload_end_offset - hdr->payload_begin_offset;
	debug("Copying refcode from %p to %p, size %x\n", src, dest, size);
	memcpy(dest, src, size);

	size = hdr->bss_end - hdr->bss_begin;
	debug("Zeroing BSS at %p, size %x\n", dest + hdr->bss_begin, size);
	memset(dest + hdr->bss_begin, '\0', size);

	func = (asmlinkage int (*)(void *))dest;
	debug("Running reference code at %p\n", func);
#ifdef DEBUG
	print_buffer(CONFIG_X86_REFCODE_RUN_ADDR, (void *)func, 1, 0x40, 0);
#endif
	ret = func(pei_data);
	if (ret != 0) {
		debug("Reference code returned %d\n", ret);
		return -EL2HLT;
	}
	debug("Refereence code completed\n");

	return 0;
}
