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

#include <cbfs.h>
#include <console/console.h>
#include <cpu/x86/cr.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <device/mmio.h>
#include <lib.h>
#include <smp/node.h>
#include <string.h>
#include <types.h>

#if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
#include <soc/intel/common/reset.h>
#else
#if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
#include <southbridge/intel/common/me.h>
#endif
#include <cf9_reset.h>
#endif

#include "txt.h"
#include "txt_register.h"
#include "txt_getsec.h"

/* Usual security practice: if an unexpected error happens, reboot */
void __noreturn txt_reset_platform(void)
{
#if CONFIG(SOC_INTEL_COMMON_BLOCK_SA)
	global_reset();
#else
#if CONFIG(SOUTHBRIDGE_INTEL_COMMON_ME)
	set_global_reset(1);
#endif
	full_reset();
#endif
}

/**
 * Dump the ACM error status bits.
 *
 * @param  acm_error The status register to dump
 * @return -1 on error (register is not valid)
 *	  0 on error (Class > 0 and Major > 0)
 *	  1 on success (Class == 0 and Major == 0 and progress > 0)
 */
int intel_txt_log_acm_error(const uint32_t acm_error)
{
	if (!(acm_error & ACMERROR_TXT_VALID))
		return -1;

	const uint8_t type = (acm_error & ACMERROR_TXT_TYPE_CODE)
			      >> ACMERROR_TXT_TYPE_SHIFT;

	switch (type) {
	case ACMERROR_TXT_AC_MODULE_TYPE_BIOS:
		printk(BIOS_ERR, "BIOSACM");
		break;
	case ACMERROR_TXT_AC_MODULE_TYPE_SINIT:
		printk(BIOS_ERR, "SINIT");
		break;
	default:
		printk(BIOS_ERR, "ACM");
		break;
	}
	printk(BIOS_ERR, ": Error code valid\n");

	if (acm_error & ACMERROR_TXT_EXTERNAL)
		printk(BIOS_ERR, " Caused by: External\n");
	else
		printk(BIOS_ERR, " Caused by: Processor\n");

	const uint32_t class = (acm_error & ACMERROR_TXT_CLASS_CODE)
							>> ACMERROR_TXT_CLASS_SHIFT;
	const uint32_t major = (acm_error & ACMERROR_TXT_MAJOR_CODE)
							>> ACMERROR_TXT_MAJOR_SHIFT;
	const uint32_t minor = (acm_error & ACMERROR_TXT_MINOR_CODE)
							>> ACMERROR_TXT_MINOR_SHIFT;
	const uint32_t progress = (acm_error & ACMERROR_TXT_PROGRESS_CODE)
							>> ACMERROR_TXT_PROGRESS_SHIFT;

	if (!minor) {
		if (class == 0 && major == 0 && progress > 0) {
			printk(BIOS_ERR, " Execution successful\n");
			printk(BIOS_ERR, " Progress code 0x%x\n", progress);
		} else {
			printk(BIOS_ERR, " Error Class: %x\n", class);
			printk(BIOS_ERR, " Error: %x.%x\n", major, progress);
		}
	} else {
		printk(BIOS_ERR, " ACM didn't start\n");
		printk(BIOS_ERR, " Error Type: 0x%x\n", acm_error & 0xffffff);
		return -1;
	}

	return (acm_error & ACMERROR_TXT_EXTERNAL) && class == 0 && major == 0 && progress > 0;
}

void intel_txt_log_spad(void)
{
	const uint64_t acm_status = read64p(TXT_SPAD);

	printk(BIOS_INFO, "TXT-STS: ACM verification ");

	if (acm_status & ACMSTS_VERIFICATION_ERROR)
		printk(BIOS_INFO, "error\n");
	else
		printk(BIOS_INFO, "successful\n");

	printk(BIOS_INFO, "TXT-STS: IBB ");

	if (acm_status & ACMSTS_IBB_MEASURED)
		printk(BIOS_INFO, "measured\n");
	else
		printk(BIOS_INFO, "not measured\n");

	printk(BIOS_INFO, "TXT-STS: TXT is ");

	if (acm_status & ACMSTS_TXT_DISABLED)
		printk(BIOS_INFO, "disabled\n");
	else
		printk(BIOS_INFO, "not disabled\n");

	printk(BIOS_INFO, "TXT-STS: BIOS is ");

	if (acm_status & ACMSTS_BIOS_TRUSTED)
		printk(BIOS_INFO, "trusted\n");
	else
		printk(BIOS_INFO, "not trusted\n");
}

/* Returns true if secrets might be in memory */
bool intel_txt_memory_has_secrets(void)
{
	bool ret;
	if (!CONFIG(INTEL_TXT))
		return false;

	ret = (read8p(TXT_ESTS) & TXT_ESTS_WAKE_ERROR_STS) ||
	      (read64p(TXT_E2STS) & TXT_E2STS_SECRET_STS);

	if (ret)
		printk(BIOS_CRIT, "TXT-STS: Secrets in memory!\n");
	return ret;
}

bool intel_txt_chipset_is_production_fused(void)
{
	/*
	 * Certain chipsets report production fused information in either
	 * TXT.VER.FSBIF or TXT.VER.EMIF/TXT.VER.QPIIF.
	 * Chapter B.1.7 and B.1.9
	 * Intel TXT Software Development Guide (Document: 315168-015)
	 */
	uint32_t reg = read32p(TXT_VER_FSBIF);

	if (reg == 0 || reg == UINT32_MAX)
		reg = read32p(TXT_VER_QPIIF);

	return (reg & TXT_VER_PRODUCTION_FUSED) ? true : false;
}

static struct acm_info_table *find_info_table(const void *ptr)
{
	const struct acm_header_v0 *acm_header = (struct acm_header_v0 *)ptr;

	return (struct acm_info_table *)(ptr +
		(acm_header->header_len + acm_header->scratch_size) * sizeof(uint32_t));
}

/**
 * Validate that the provided ACM is usable on this platform.
 */
static int validate_acm(const void *ptr)
{
	const struct acm_header_v0 *acm_header = (struct acm_header_v0 *)ptr;
	uint32_t max_size_acm_area = 0;

	if (acm_header->module_type != CHIPSET_ACM)
		return ACM_E_TYPE_NOT_MATCH;

	/* Seems inconsistent across generations. */
	if (acm_header->module_sub_type != 0 && acm_header->module_sub_type != 1)
		return ACM_E_MODULE_SUB_TYPE_WRONG;

	if (acm_header->module_vendor != INTEL_ACM_VENDOR)
		return ACM_E_MODULE_VENDOR_NOT_INTEL;

	if (acm_header->size == 0)
		return ACM_E_SIZE_INCORRECT;

	if (((acm_header->header_len + acm_header->scratch_size) * sizeof(uint32_t) +
	    sizeof(struct acm_info_table)) > (acm_header->size & 0xffffff) * sizeof(uint32_t)) {
		return ACM_E_SIZE_INCORRECT;
	}

	if (!getsec_parameter(NULL, NULL, &max_size_acm_area, NULL, NULL, NULL))
		return ACM_E_CANT_CALL_GETSEC;

	/*
	 * Causes #GP if acm_header->size > processor internal authenticated
	 * code area capacity.
	 * SAFER MODE EXTENSIONS REFERENCE.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 */
	const size_t acm_len = 1UL << log2_ceil((acm_header->size & 0xffffff) << 2);
	if (max_size_acm_area < acm_len) {
		printk(BIOS_ERR, "TEE-TXT: BIOS ACM doesn't fit into AC execution region\n");
		return ACM_E_NOT_FIT_INTO_CPU_ACM_MEM;
	}

	struct acm_info_table *info = find_info_table(ptr);
	if (!info)
		return ACM_E_NO_INFO_TABLE;
	if (info->chipset_acm_type != BIOS)
		return ACM_E_NOT_BIOS_ACM;

	static const u8 acm_uuid[] = {
		0xaa, 0x3a, 0xc0, 0x7f, 0xa7, 0x46, 0xdb, 0x18,
		0x2e, 0xac, 0x69, 0x8f, 0x8d, 0x41, 0x7f, 0x5a,
	};
	if (memcmp(acm_uuid, info->uuid, sizeof(acm_uuid)) != 0)
		return ACM_E_UUID_NOT_MATCH;

	const bool production_acm = !(acm_header->flags & ACM_FORMAT_FLAGS_DEBUG);
	if (production_acm != intel_txt_chipset_is_production_fused())
		return ACM_E_PLATFORM_IS_NOT_PROD;

	return 0;
}

/*
 * Prepare to run the BIOS ACM: mmap it from the CBFS and verify that it
 * can be launched. Returns pointer to ACM on success, NULL on failure.
 */
static void *intel_txt_prepare_bios_acm(size_t *acm_len)
{
	void *acm_data = NULL;

	if (!acm_len)
		return NULL;

	acm_data = cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_ACM, acm_len);
	if (!acm_data) {
		printk(BIOS_ERR, "TEE-TXT: Couldn't locate BIOS ACM in CBFS.\n");
		return NULL;
	}

	/*
	 * CPU enforces only 4KiB alignment.
	 * Chapter A.1.1
	 * Intel TXT Software Development Guide (Document: 315168-015)
	 */
	if (!IS_ALIGNED((uintptr_t)acm_data, 4096)) {
		printk(BIOS_ERR, "TEE-TXT: BIOS ACM isn't mapped at page boundary.\n");
		cbfs_unmap(acm_data);
		return NULL;
	}

	/*
	 * Causes #GP if not multiple of 64.
	 * SAFER MODE EXTENSIONS REFERENCE.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 */
	if (!IS_ALIGNED(*acm_len, 64)) {
		printk(BIOS_ERR, "TEE-TXT: BIOS ACM size isn't multiple of 64.\n");
		cbfs_unmap(acm_data);
		return NULL;
	}

	/*
	 * The ACM should be aligned to it's size, but that's not possible, as
	 * some ACMs are not power of two. Use the next power of two for verification.
	 */
	if (!IS_ALIGNED((uintptr_t)acm_data, (1UL << log2_ceil(*acm_len)))) {
		printk(BIOS_ERR, "TEE-TXT: BIOS ACM isn't aligned to its size.\n");
		cbfs_unmap(acm_data);
		return NULL;
	}

	/*
	 * When setting up the MTRRs to cache the BIOS ACM, one must cache less than
	 * a page (4 KiB) of unused memory after the BIOS ACM. On Haswell, failure
	 * to do so will cause a TXT reset with Class Code 5, Major Error Code 2.
	 */
	if (popcnt(ALIGN_UP(*acm_len, 4096)) > get_var_mtrr_count()) {
		printk(BIOS_ERR, "TEE-TXT: Not enough MTRRs to cache this BIOS ACM's size.\n");
		cbfs_unmap(acm_data);
		return NULL;
	}

	if (CONFIG(INTEL_TXT_LOGGING))
		txt_dump_acm_info(acm_data);

	const int ret = validate_acm(acm_data);
	if (ret < 0) {
		printk(BIOS_ERR, "TEE-TXT: Validation of ACM failed with: %d\n", ret);
		cbfs_unmap(acm_data);
		return NULL;
	}

	return acm_data;
}

#define MCU_BASE_ADDR	(TXT_BASE + 0x278)
#define BIOACM_ADDR	(TXT_BASE + 0x27c)
#define APINIT_ADDR	(TXT_BASE + 0x290)
#define SEMAPHORE	(TXT_BASE + 0x294)

/* Returns on failure, resets the computer on success */
void intel_txt_run_sclean(void)
{
	size_t acm_len;

	void *acm_data = intel_txt_prepare_bios_acm(&acm_len);

	if (!acm_data)
		return;

	/* FIXME: Do we need to program these two? */
	//write32p(MCU_BASE_ADDR, 0xffe1a990);
	//write32p(APINIT_ADDR, 0xfffffff0);

	write32p(BIOACM_ADDR, (uintptr_t)acm_data);
	write32p(SEMAPHORE, 0);

	/*
	 * The time SCLEAN will take depends on the installed RAM size.
	 * On Haswell with 8 GiB of DDR3, it takes five or ten minutes. (rough estimate)
	 */
	printk(BIOS_ALERT, "TEE-TXT: Invoking SCLEAN. This can take several minutes.\n");

	/*
	 * Invoke the BIOS ACM. If successful, the system will reset with memory unlocked.
	 */
	getsec_sclean((uintptr_t)acm_data, acm_len);

	/*
	 * However, if this function returns, the BIOS ACM could not be invoked. This is bad.
	 */
	printk(BIOS_CRIT, "TEE-TXT: getsec_sclean could not launch the BIOS ACM.\n");

	cbfs_unmap(acm_data);
}

/*
 * Test all bits for TXT execution.
 *
 * @return 0 on success
 */
int intel_txt_run_bios_acm(const u8 input_params)
{
	size_t acm_len;

	void *acm_data = intel_txt_prepare_bios_acm(&acm_len);

	if (!acm_data)
		return -1;

	/* Call into assembly which invokes the referenced ACM */
	getsec_enteraccs(input_params, (uintptr_t)acm_data, acm_len);

	cbfs_unmap(acm_data);

	const uint64_t acm_status = read64p(TXT_SPAD);
	if (acm_status & ACMERROR_TXT_VALID) {
		printk(BIOS_ERR, "TEE-TXT: FATAL ACM launch error !\n");
		/*
		 * WARNING !
		 * To clear TXT.BIOSACM.ERRORCODE you must issue a cold reboot!
		 */
		intel_txt_log_acm_error(read32p(TXT_BIOSACM_ERRORCODE));
		return -1;
	}

	return 0;
}

 /* Returns true if cond is not met */
static bool check_precondition(const int cond)
{
	printk(BIOS_DEBUG, "%s\n", cond ? "true" : "false");
	return !cond;
}

/*
 * Test all bits that are required for Intel TXT.
 * Enable SMX if available.
 *
 * @return 0 on success
 */
bool intel_txt_prepare_txt_env(void)
{
	bool failure = false;
	uint32_t txt_feature_flags = 0;

	unsigned int ecx = cpuid_ecx(1);

	printk(BIOS_DEBUG, "TEE-TXT: CPU supports SMX: ");
	failure |= check_precondition(ecx & CPUID_SMX);

	printk(BIOS_DEBUG, "TEE-TXT: CPU supports VMX: ");
	failure |= check_precondition(ecx & CPUID_VMX);

	msr_t msr = rdmsr(IA32_FEATURE_CONTROL);
	if (!(msr.lo & BIT(0))) {
		printk(BIOS_ERR, "TEE-TXT: IA32_FEATURE_CONTROL is not locked\n");
		txt_reset_platform();
	}

	printk(BIOS_DEBUG, "TEE-TXT: IA32_FEATURE_CONTROL\n");
	printk(BIOS_DEBUG, " VMXON in SMX enable: ");
	failure |= check_precondition(msr.lo & BIT(1));

	printk(BIOS_DEBUG, " VMXON outside SMX enable: ");
	failure |= check_precondition(msr.lo & FEATURE_ENABLE_VMX);

	printk(BIOS_DEBUG, " register is locked: ");
	failure |= check_precondition(msr.lo & BIT(0));

	/* IA32_FEATURE_CONTROL enables getsec instructions */
	printk(BIOS_DEBUG, " GETSEC (all instructions) is enabled: ");
	failure |= check_precondition((msr.lo & 0xff00) == 0xff00);

	/* Prevent crash and opt out early */
	if (failure)
		return true;

	uint32_t eax = 0;
	/*
	 * GetSec[CAPABILITIES]
	 * SAFER MODE EXTENSIONS REFERENCE.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 * Must check BIT0 of TXT chipset has been detected by CPU.
	 */
	if (!getsec_capabilities(&eax))
		return true;

	printk(BIOS_DEBUG, "TEE-TXT: GETSEC[CAPABILITIES] returned:\n");
	printk(BIOS_DEBUG, " TXT capable chipset:  %s\n", (eax & BIT(0)) ? "true" : "false");

	printk(BIOS_DEBUG, " ENTERACCS available:  %s\n", (eax & BIT(2)) ? "true" : "false");
	printk(BIOS_DEBUG, " EXITAC available:     %s\n", (eax & BIT(3)) ? "true" : "false");
	printk(BIOS_DEBUG, " SENTER available:     %s\n", (eax & BIT(4)) ? "true" : "false");
	printk(BIOS_DEBUG, " SEXIT available:      %s\n", (eax & BIT(5)) ? "true" : "false");
	printk(BIOS_DEBUG, " PARAMETERS available: %s\n", (eax & BIT(6)) ? "true" : "false");
	printk(BIOS_DEBUG, " SMCTRL available:     %s\n", (eax & BIT(7)) ? "true" : "false");
	printk(BIOS_DEBUG, " WAKEUP available:     %s\n", (eax & BIT(8)) ? "true" : "false");

	txt_dump_getsec_parameters();

	/*
	 * Causes #GP if function is not supported by getsec.
	 * SAFER MODE EXTENSIONS REFERENCE.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 * Order Number:  325383-060US
	 */
	if ((eax & 0x7d) != 0x7d)
		failure = true;

	const uint64_t status = read64p(TXT_SPAD);

	if (status & ACMSTS_TXT_DISABLED) {
		printk(BIOS_INFO, "TEE-TXT: TXT disabled by BIOS policy in FIT.\n");
		failure = true;
	}

	/*
	 * Only the BSP must call getsec[ENTERACCS].
	 * SAFER MODE EXTENSIONS REFERENCE.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 * Order Number:  325383-060US
	 */
	if (!boot_cpu()) {
		printk(BIOS_ERR, "TEE-TXT: BSP flag not set in APICBASE_MSR.\n");
		failure = true;
	}

	/*
	 * There must be no MCEs pending.
	 * Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
	 * Order Number:  325383-060US
	 */
	msr = rdmsr(IA32_MCG_STATUS);
	if (msr.lo & 0x4) {
		printk(BIOS_ERR, "TEE-TXT: IA32_MCG_STATUS.MCIP is set.\n");
		failure = true;
	}

	if (!getsec_parameter(NULL, NULL, NULL, NULL, NULL, &txt_feature_flags))
		return true;

	printk(BIOS_DEBUG, "TEE-TXT: Machine Check Register: ");
	if (txt_feature_flags & GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK)
		printk(BIOS_DEBUG, "preserved\n");
	else
		printk(BIOS_DEBUG, "must be clear\n");

	if (!(txt_feature_flags & GETSEC_PARAMS_TXT_EXT_MACHINE_CHECK)) {
		/*
		* Make sure there are no uncorrectable MCE errors.
		* Intel 64 and IA-32 Architectures Software Developer Manuals Vol 2D
		*/
		size_t max_mc_msr = mca_get_bank_count();
		for (size_t i = 0; i < max_mc_msr; i++) {
			msr = rdmsr(IA32_MC_STATUS(i));
			if (!(msr.hi & MCA_STATUS_HI_UC))
				continue;

			printk(BIOS_ERR, "TEE-TXT: IA32_MC%zd_STATUS.UC is set.\n", i);
			failure = true;
			break;
		}
	}

	/* Need to park all APs. */
	if (CONFIG(PARALLEL_MP_AP_WORK))
		mp_park_aps();

	return failure;
}
