/*
 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>

#include <arch.h>
#include <arch_helpers.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <context.h>
#include <denver.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <lib/mmio.h>

#include <mce.h>
#include <mce_private.h>
#include <t18x_ari.h>
#include <tegra_def.h>
#include <tegra_platform.h>

/* NVG functions handlers */
static arch_mce_ops_t nvg_mce_ops = {
	.enter_cstate = nvg_enter_cstate,
	.update_cstate_info = nvg_update_cstate_info,
	.update_crossover_time = nvg_update_crossover_time,
	.read_cstate_stats = nvg_read_cstate_stats,
	.write_cstate_stats = nvg_write_cstate_stats,
	.call_enum_misc = ari_enumeration_misc,
	.is_ccx_allowed = nvg_is_ccx_allowed,
	.is_sc7_allowed = nvg_is_sc7_allowed,
	.online_core = nvg_online_core,
	.cc3_ctrl = nvg_cc3_ctrl,
	.update_reset_vector = ari_reset_vector_update,
	.roc_flush_cache = ari_roc_flush_cache,
	.roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
	.roc_clean_cache = ari_roc_clean_cache,
	.read_write_mca = ari_read_write_mca,
	.update_ccplex_gsc = ari_update_ccplex_gsc,
	.enter_ccplex_state = ari_enter_ccplex_state,
	.read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
	.misc_ccplex = ari_misc_ccplex
};

/* ARI functions handlers */
static arch_mce_ops_t ari_mce_ops = {
	.enter_cstate = ari_enter_cstate,
	.update_cstate_info = ari_update_cstate_info,
	.update_crossover_time = ari_update_crossover_time,
	.read_cstate_stats = ari_read_cstate_stats,
	.write_cstate_stats = ari_write_cstate_stats,
	.call_enum_misc = ari_enumeration_misc,
	.is_ccx_allowed = ari_is_ccx_allowed,
	.is_sc7_allowed = ari_is_sc7_allowed,
	.online_core = ari_online_core,
	.cc3_ctrl = ari_cc3_ctrl,
	.update_reset_vector = ari_reset_vector_update,
	.roc_flush_cache = ari_roc_flush_cache,
	.roc_flush_cache_trbits = ari_roc_flush_cache_trbits,
	.roc_clean_cache = ari_roc_clean_cache,
	.read_write_mca = ari_read_write_mca,
	.update_ccplex_gsc = ari_update_ccplex_gsc,
	.enter_ccplex_state = ari_enter_ccplex_state,
	.read_write_uncore_perfmon = ari_read_write_uncore_perfmon,
	.misc_ccplex = ari_misc_ccplex
};

typedef struct {
	uint32_t ari_base;
	arch_mce_ops_t *ops;
} mce_config_t;

/* Table to hold the per-CPU ARI base address and function handlers */
static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = {
	{
		/* A57 Core 0 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_0_OFFSET,
		.ops = &ari_mce_ops,
	},
	{
		/* A57 Core 1 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_1_OFFSET,
		.ops = &ari_mce_ops,
	},
	{
		/* A57 Core 2 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_2_OFFSET,
		.ops = &ari_mce_ops,
	},
	{
		/* A57 Core 3 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_3_OFFSET,
		.ops = &ari_mce_ops,
	},
	{
		/* D15 Core 0 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_4_OFFSET,
		.ops = &nvg_mce_ops,
	},
	{
		/* D15 Core 1 */
		.ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_5_OFFSET,
		.ops = &nvg_mce_ops,
	}
};

static uint32_t mce_get_curr_cpu_ari_base(void)
{
	uint64_t mpidr = read_mpidr();
	uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;

	/*
	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
	 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
	 * numbers start from 0. In order to get the proper arch_mce_ops_t
	 * struct, we have to convert the Denver CPU ids to the corresponding
	 * indices in the mce_ops_table array.
	 */
	if (impl == DENVER_IMPL) {
		cpuid |= 0x4U;
	}

	return mce_cfg_table[cpuid].ari_base;
}

static arch_mce_ops_t *mce_get_curr_cpu_ops(void)
{
	uint64_t mpidr = read_mpidr();
	uint64_t cpuid = mpidr & MPIDR_CPU_MASK;
	uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) &
			MIDR_IMPL_MASK;

	/*
	 * T186 has 2 CPU clusters, one with Denver CPUs and the other with
	 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU
	 * numbers start from 0. In order to get the proper arch_mce_ops_t
	 * struct, we have to convert the Denver CPU ids to the corresponding
	 * indices in the mce_ops_table array.
	 */
	if (impl == DENVER_IMPL) {
		cpuid |= 0x4U;
	}

	return mce_cfg_table[cpuid].ops;
}

/*******************************************************************************
 * Common handler for all MCE commands
 ******************************************************************************/
int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
			uint64_t arg2)
{
	const arch_mce_ops_t *ops;
	gp_regs_t *gp_regs = get_gpregs_ctx(cm_get_context(NON_SECURE));
	uint32_t cpu_ari_base;
	uint64_t ret64 = 0, arg3, arg4, arg5;
	int32_t ret = 0;

	assert(gp_regs != NULL);

	/* get a pointer to the CPU's arch_mce_ops_t struct */
	ops = mce_get_curr_cpu_ops();

	/* get the CPU's ARI base address */
	cpu_ari_base = mce_get_curr_cpu_ari_base();

	switch (cmd) {
	case (uint64_t)MCE_CMD_ENTER_CSTATE:
		ret = ops->enter_cstate(cpu_ari_base, arg0, arg1);

		break;

	case (uint64_t)MCE_CMD_UPDATE_CSTATE_INFO:
		/*
		 * get the parameters required for the update cstate info
		 * command
		 */
		arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
		arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
		arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);

		ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0,
				(uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3,
				(uint32_t)arg4, (uint8_t)arg5);

		write_ctx_reg(gp_regs, CTX_GPREG_X4, (0ULL));
		write_ctx_reg(gp_regs, CTX_GPREG_X5, (0ULL));
		write_ctx_reg(gp_regs, CTX_GPREG_X6, (0ULL));

		break;

	case (uint64_t)MCE_CMD_UPDATE_CROSSOVER_TIME:
		ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1);

		break;

	case (uint64_t)MCE_CMD_READ_CSTATE_STATS:
		ret64 = ops->read_cstate_stats(cpu_ari_base, arg0);

		/* update context to return cstate stats value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
		write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64));

		break;

	case (uint64_t)MCE_CMD_WRITE_CSTATE_STATS:
		ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1);

		break;

	case (uint64_t)MCE_CMD_IS_CCX_ALLOWED:
		ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1);

		/* update context to return CCx status value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));

		break;

	case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
		ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1);

		/* update context to return SC7 status value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint64_t)(ret));
		write_ctx_reg(gp_regs, CTX_GPREG_X3, (uint64_t)(ret));

		break;

	case (uint64_t)MCE_CMD_ONLINE_CORE:
		ret = ops->online_core(cpu_ari_base, arg0);

		break;

	case (uint64_t)MCE_CMD_CC3_CTRL:
		ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2);

		break;

	case (uint64_t)MCE_CMD_ECHO_DATA:
		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO,
				arg0);

		/* update context to return if echo'd data matched source */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, ((ret64 == arg0) ?
			      1ULL : 0ULL));
		write_ctx_reg(gp_regs, CTX_GPREG_X2, ((ret64 == arg0) ?
			      1ULL : 0ULL));

		break;

	case (uint64_t)MCE_CMD_READ_VERSIONS:
		ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION,
			arg0);

		/*
		 * version = minor(63:32) | major(31:0). Update context
		 * to return major and minor version number.
		 */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
		write_ctx_reg(gp_regs, CTX_GPREG_X2, (ret64 >> 32ULL));

		break;

	case (uint64_t)MCE_CMD_ENUM_FEATURES:
		ret64 = ops->call_enum_misc(cpu_ari_base,
				TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0);

		/* update context to return features value */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));

		break;

	case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
		ret = ops->roc_flush_cache_trbits(cpu_ari_base);

		break;

	case (uint64_t)MCE_CMD_ROC_FLUSH_CACHE:
		ret = ops->roc_flush_cache(cpu_ari_base);

		break;

	case (uint64_t)MCE_CMD_ROC_CLEAN_CACHE:
		ret = ops->roc_clean_cache(cpu_ari_base);

		break;

	case (uint64_t)MCE_CMD_ENUM_READ_MCA:
		ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);

		/* update context to return MCA data/error */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
		write_ctx_reg(gp_regs, CTX_GPREG_X2, (arg1));
		write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));

		break;

	case (uint64_t)MCE_CMD_ENUM_WRITE_MCA:
		ret64 = ops->read_write_mca(cpu_ari_base, arg0, &arg1);

		/* update context to return MCA error */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (ret64));
		write_ctx_reg(gp_regs, CTX_GPREG_X3, (ret64));

		break;

#if ENABLE_CHIP_VERIFICATION_HARNESS
	case (uint64_t)MCE_CMD_ENABLE_LATIC:
		/*
		 * This call is not for production use. The constant value,
		 * 0xFFFF0000, is specific to allowing for enabling LATIC on
		 * pre-production parts for the chip verification harness.
		 *
		 * Enabling LATIC allows S/W to read the MINI ISPs in the
		 * CCPLEX. The ISMs are used for various measurements relevant
		 * to particular locations in the Silicon. They are small
		 * counters which can be polled to determine how fast a
		 * particular location in the Silicon is.
		 */
		ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(),
			0xFFFF0000);

		break;
#endif

	case (uint64_t)MCE_CMD_UNCORE_PERFMON_REQ:
		ret = ops->read_write_uncore_perfmon(cpu_ari_base, arg0, &arg1);

		/* update context to return data */
		write_ctx_reg(gp_regs, CTX_GPREG_X1, (arg1));
		break;

	case (uint64_t)MCE_CMD_MISC_CCPLEX:
		ops->misc_ccplex(cpu_ari_base, arg0, arg1);

		break;

	default:
		ERROR("unknown MCE command (%" PRIu64 ")\n", cmd);
		ret = EINVAL;
		break;
	}

	return ret;
}

/*******************************************************************************
 * Handler to update the reset vector for CPUs
 ******************************************************************************/
int32_t mce_update_reset_vector(void)
{
	const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();

	ops->update_reset_vector(mce_get_curr_cpu_ari_base());

	return 0;
}

static int32_t mce_update_ccplex_gsc(tegra_ari_gsc_index_t gsc_idx)
{
	const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();

	ops->update_ccplex_gsc(mce_get_curr_cpu_ari_base(), gsc_idx);

	return 0;
}

/*******************************************************************************
 * Handler to update carveout values for Video Memory Carveout region
 ******************************************************************************/
int32_t mce_update_gsc_videomem(void)
{
	return mce_update_ccplex_gsc(TEGRA_ARI_GSC_VPR_IDX);
}

/*******************************************************************************
 * Handler to update carveout values for TZDRAM aperture
 ******************************************************************************/
int32_t mce_update_gsc_tzdram(void)
{
	return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX);
}

/*******************************************************************************
 * Handler to shutdown/reset the entire system
 ******************************************************************************/
__dead2 void mce_enter_ccplex_state(uint32_t state_idx)
{
	const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();

	/* sanity check state value */
	if ((state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) &&
	    (state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT)) {
		panic();
	}

	ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), state_idx);

	/* wait till the CCPLEX powers down */
	for (;;) {
		;
	}

}

/*******************************************************************************
 * Handler to issue the UPDATE_CSTATE_INFO request
 ******************************************************************************/
void mce_update_cstate_info(const mce_cstate_info_t *cstate)
{
	const arch_mce_ops_t *ops = mce_get_curr_cpu_ops();

	/* issue the UPDATE_CSTATE_INFO request */
	ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster,
		cstate->ccplex, cstate->system, cstate->system_state_force,
		cstate->wake_mask, cstate->update_wake_mask);
}

/*******************************************************************************
 * Handler to read the MCE firmware version and check if it is compatible
 * with interface header the BL3-1 was compiled against
 ******************************************************************************/
void mce_verify_firmware_version(void)
{
	const arch_mce_ops_t *ops;
	uint32_t cpu_ari_base;
	uint64_t version;
	uint32_t major, minor;

	/*
	 * MCE firmware is not supported on simulation platforms.
	 */
	if (tegra_platform_is_emulation()) {

		INFO("MCE firmware is not supported\n");

	} else {
		/* get a pointer to the CPU's arch_mce_ops_t struct */
		ops = mce_get_curr_cpu_ops();

		/* get the CPU's ARI base address */
		cpu_ari_base = mce_get_curr_cpu_ari_base();

		/*
		 * Read the MCE firmware version and extract the major and minor
		 * version fields
		 */
		version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0);
		major = (uint32_t)version;
		minor = (uint32_t)(version >> 32);

		INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
			TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR);

		/*
		 * Verify that the MCE firmware version and the interface header
		 * match
		 */
		if (major != TEGRA_ARI_VERSION_MAJOR) {
			ERROR("ARI major version mismatch\n");
			panic();
		}

		if (minor < TEGRA_ARI_VERSION_MINOR) {
			ERROR("ARI minor version mismatch\n");
			panic();
		}
	}
}
