/*
 * Copyright (c) 2020-2021, NVIDIA Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>

#include <common/debug.h>
#include <lib/bakery_lock.h>
#include <lib/cassert.h>
#include <lib/extensions/ras.h>
#include <lib/utils_def.h>
#include <services/sdei.h>

#include <plat/common/platform.h>
#include <platform_def.h>
#include <tegra194_ras_private.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>

/*
 * ERR<n>FR bits[63:32], it indicates supported RAS errors which can be enabled
 * by setting corresponding bits in ERR<n>CTLR
 */
#define ERR_FR_EN_BITS_MASK	0xFFFFFFFF00000000ULL

/*
 * Number of RAS errors will be cleared per 'tegra194_ras_corrected_err_clear'
 * function call.
 */
#define RAS_ERRORS_PER_CALL	8

/*
 * the max possible RAS node index value.
 */
#define RAS_NODE_INDEX_MAX	0x1FFFFFFFU

/* bakery lock for platform RAS handler. */
static DEFINE_BAKERY_LOCK(ras_handler_lock);
#define ras_lock()		bakery_lock_get(&ras_handler_lock)
#define ras_unlock()		bakery_lock_release(&ras_handler_lock)

/*
 * Function to handle an External Abort received at EL3.
 * This function is invoked by RAS framework.
 */
static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome,
		void *cookie, void *handle, uint64_t flags)
{
	int32_t ret;

	ras_lock();

	ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%" PRIx64 "\n",
		read_mpidr(), ea_reason, syndrome);

	/* Call RAS EA handler */
	ret = ras_ea_handler(ea_reason, syndrome, cookie, handle, flags);
	if (ret != 0) {
		ERROR("RAS error handled!\n");
		ret = sdei_dispatch_event(TEGRA_SDEI_EP_EVENT_0 +
				plat_my_core_pos());
		if (ret != 0)
			ERROR("sdei_dispatch_event returned %d\n", ret);
	} else {
		ERROR("Not a RAS error!\n");
	}

	ras_unlock();
}

/*
 * Function to enable all supported RAS error report.
 *
 * Uncorrected errors are set to report as External abort (SError)
 * Corrected errors are set to report as interrupt.
 */
void tegra194_ras_enable(void)
{
	VERBOSE("%s\n", __func__);

	/* skip RAS enablement if not a silicon platform. */
	if (!tegra_platform_is_silicon()) {
		return;
	}

	/*
	 * Iterate for each group(num_idx ERRSELRs starting from idx_start)
	 * use normal for loop instead of for_each_err_record_info to get rid
	 * of MISRA noise..
	 */
	for (uint32_t i = 0U; i < err_record_mappings.num_err_records; i++) {

		const struct err_record_info *info = &err_record_mappings.err_records[i];

		uint32_t idx_start = info->sysreg.idx_start;
		uint32_t num_idx = info->sysreg.num_idx;
		const struct ras_aux_data *aux_data = (const struct ras_aux_data *)info->aux_data;

		assert(aux_data != NULL);

		for (uint32_t j = 0; j < num_idx; j++) {

			/* ERR<n>CTLR register value. */
			uint64_t err_ctrl = 0ULL;
			/* all supported errors for this node. */
			uint64_t err_fr;
			/* uncorrectable errors */
			uint64_t uncorr_errs;
			/* correctable errors */
			uint64_t corr_errs;

			/*
			 * Catch error if something wrong with the RAS aux data
			 * record table.
			 */
			assert(aux_data[j].err_ctrl != NULL);

			/*
			 * Write to ERRSELR_EL1 to select the RAS error node.
			 * Always program this at first to select corresponding
			 * RAS node before any other RAS register r/w.
			 */
			ser_sys_select_record(idx_start + j);

			err_fr = read_erxfr_el1() & ERR_FR_EN_BITS_MASK;
			uncorr_errs = aux_data[j].err_ctrl();
			corr_errs = ~uncorr_errs & err_fr;

			/* enable error reporting */
			ERR_CTLR_ENABLE_FIELD(err_ctrl, ED);

			/* enable SError reporting for uncorrectable errors */
			if ((uncorr_errs & err_fr) != 0ULL) {
				ERR_CTLR_ENABLE_FIELD(err_ctrl, UE);
			}

			/* generate interrupt for corrected errors. */
			if (corr_errs != 0ULL) {
				ERR_CTLR_ENABLE_FIELD(err_ctrl, CFI);
			}

			/* enable the supported errors */
			err_ctrl |= err_fr;

			VERBOSE("errselr_el1:0x%x, erxfr:0x%" PRIx64 ", err_ctrl:0x%" PRIx64 "\n",
				idx_start + j, err_fr, err_ctrl);

			/* enable specified errors, or set to 0 if no supported error */
			write_erxctlr_el1(err_ctrl);
		}
	}
}

/*
 * Function to clear RAS ERR<n>STATUS for corrected RAS error.
 *
 * This function clears number of 'RAS_ERRORS_PER_CALL' RAS errors at most.
 * 'cookie' - in/out cookie parameter to specify/store last visited RAS
 *            error record index. it is set to '0' to indicate no more RAS
 *            error record to clear.
 */
void tegra194_ras_corrected_err_clear(uint64_t *cookie)
{
	/*
	 * 'last_node' and 'last_idx' represent last visited RAS node index from
	 * previous function call. they are set to 0 when first smc call is made
	 * or all RAS error are visited by followed multipile smc calls.
	 */
	union prev_record {
		struct record {
			uint32_t last_node;
			uint32_t last_idx;
		} rec;
		uint64_t value;
	} prev;

	uint64_t clear_ce_status = 0ULL;
	int32_t nerrs_per_call = RAS_ERRORS_PER_CALL;
	uint32_t i;

	if (cookie == NULL) {
		return;
	}

	prev.value = *cookie;

	if ((prev.rec.last_node >= RAS_NODE_INDEX_MAX) ||
		(prev.rec.last_idx >= RAS_NODE_INDEX_MAX)) {
		return;
	}

	ERR_STATUS_SET_FIELD(clear_ce_status, AV, 0x1UL);
	ERR_STATUS_SET_FIELD(clear_ce_status, V, 0x1UL);
	ERR_STATUS_SET_FIELD(clear_ce_status, OF, 0x1UL);
	ERR_STATUS_SET_FIELD(clear_ce_status, MV, 0x1UL);
	ERR_STATUS_SET_FIELD(clear_ce_status, CE, 0x3UL);


	for (i = prev.rec.last_node; i < err_record_mappings.num_err_records; i++) {

		const struct err_record_info *info = &err_record_mappings.err_records[i];
		uint32_t idx_start = info->sysreg.idx_start;
		uint32_t num_idx = info->sysreg.num_idx;

		uint32_t j;

		j = (i == prev.rec.last_node && prev.value != 0UL) ?
				(prev.rec.last_idx + 1U) : 0U;

		for (; j < num_idx; j++) {

			uint64_t status;
			uint32_t err_idx = idx_start + j;

			if (err_idx >= RAS_NODE_INDEX_MAX) {
				return;
			}

			write_errselr_el1(err_idx);
			status = read_erxstatus_el1();

			if (ERR_STATUS_GET_FIELD(status, CE) != 0U) {
				write_erxstatus_el1(clear_ce_status);
			}

			--nerrs_per_call;

			/* only clear 'nerrs_per_call' errors each time. */
			if (nerrs_per_call <= 0) {
				prev.rec.last_idx = j;
				prev.rec.last_node = i;
				/* save last visited error record index
				 * into cookie.
				 */
				*cookie = prev.value;

				return;
			}
		}
	}

	/*
	 * finish if all ras error records are checked or provided index is out
	 * of range.
	 */
	*cookie = 0ULL;
}

/* Function to probe an error from error record group. */
static int32_t tegra194_ras_record_probe(const struct err_record_info *info,
		int *probe_data)
{
	/* Skip probing if not a silicon platform */
	if (!tegra_platform_is_silicon()) {
		return 0;
	}

	return ser_probe_sysreg(info->sysreg.idx_start, info->sysreg.num_idx, probe_data);
}

/* Function to handle error from one given node */
static int32_t tegra194_ras_node_handler(uint32_t errselr, const char *name,
		const struct ras_error *errors, uint64_t status)
{
	bool found = false;
	uint32_t ierr = (uint32_t)ERR_STATUS_GET_FIELD(status, IERR);
	uint32_t serr = (uint32_t)ERR_STATUS_GET_FIELD(status, SERR);
	uint64_t val = 0;

	/* not a valid error. */
	if (ERR_STATUS_GET_FIELD(status, V) == 0U) {
		return 0;
	}

	ERR_STATUS_SET_FIELD(val, V, 1);

	/* keep the log print same as linux arm64_ras driver. */
	ERROR("**************************************\n");
	ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr);
	ERROR("\tStatus = 0x%" PRIx64 "\n", status);

	/* Print uncorrectable error information. */
	if (ERR_STATUS_GET_FIELD(status, UE) != 0U) {

		ERR_STATUS_SET_FIELD(val, UE, 1);
		ERR_STATUS_SET_FIELD(val, UET, 1);

		/* IERR to error message */
		for (uint32_t i = 0; errors[i].error_msg != NULL; i++) {
			if (ierr == errors[i].error_code) {
				ERROR("\tIERR = %s: 0x%x\n",
					errors[i].error_msg, ierr);

				found = true;
				break;
			}
		}

		if (!found) {
			ERROR("\tUnknown IERR: 0x%x\n", ierr);
		}

		ERROR("SERR = %s: 0x%x\n", ras_serr_to_str(serr), serr);

		/* Overflow, multiple errors have been detected. */
		if (ERR_STATUS_GET_FIELD(status, OF) != 0U) {
			ERROR("\tOverflow (there may be more errors) - "
				"Uncorrectable\n");
			ERR_STATUS_SET_FIELD(val, OF, 1);
		}

		ERROR("\tUncorrectable (this is fatal)\n");

		/* Miscellaneous Register Valid. */
		if (ERR_STATUS_GET_FIELD(status, MV) != 0U) {
			ERROR("\tMISC0 = 0x%lx\n", read_erxmisc0_el1());
			ERROR("\tMISC1 = 0x%lx\n", read_erxmisc1_el1());
			ERR_STATUS_SET_FIELD(val, MV, 1);
		}

		/* Address Valid. */
		if (ERR_STATUS_GET_FIELD(status, AV) != 0U) {
			ERROR("\tADDR = 0x%lx\n", read_erxaddr_el1());
			ERR_STATUS_SET_FIELD(val, AV, 1);
		}

		/* Deferred error */
		if (ERR_STATUS_GET_FIELD(status, DE) != 0U) {
			ERROR("\tDeferred error\n");
			ERR_STATUS_SET_FIELD(val, DE, 1);
		}

	} else {
		/* For corrected error, simply clear it. */
		VERBOSE("corrected RAS error is cleared: ERRSELR_EL1:0x%x, "
			"IERR:0x%x, SERR:0x%x\n", errselr, ierr, serr);
		ERR_STATUS_SET_FIELD(val, CE, 1);
	}

	ERROR("**************************************\n");

	/* Write to clear reported errors. */
	write_erxstatus_el1(val);

	/* error handled */
	return 0;
}

/* Function to handle one error node from an error record group. */
static int32_t tegra194_ras_record_handler(const struct err_record_info *info,
		int probe_data, const struct err_handler_data *const data __unused)
{
	uint32_t num_idx = info->sysreg.num_idx;
	uint32_t idx_start = info->sysreg.idx_start;
	const struct ras_aux_data *aux_data = info->aux_data;
	const struct ras_error *errors;
	uint32_t offset;
	const char *node_name;

	uint64_t status = 0ULL;

	VERBOSE("%s\n", __func__);

	assert(probe_data >= 0);
	assert((uint32_t)probe_data < num_idx);

	offset = (uint32_t)probe_data;
	errors = aux_data[offset].error_records;
	node_name = aux_data[offset].name;

	assert(errors != NULL);

	/* Write to ERRSELR_EL1 to select the error record */
	ser_sys_select_record(idx_start + offset);

	/* Retrieve status register from the error record */
	status = read_erxstatus_el1();

	return tegra194_ras_node_handler(idx_start + offset, node_name,
			errors, status);
}


/* Instantiate RAS nodes */
PER_CORE_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
PER_CLUSTER_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
SCF_L3_BANK_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)
CCPLEX_RAS_NODE_LIST(DEFINE_ONE_RAS_NODE)

/* Instantiate RAS node groups */
static struct ras_aux_data per_core_ras_group[] = {
	PER_CORE_RAS_GROUP_NODES
};
CASSERT(ARRAY_SIZE(per_core_ras_group) < RAS_NODE_INDEX_MAX,
	assert_max_per_core_ras_group_size);

static struct ras_aux_data per_cluster_ras_group[] = {
	PER_CLUSTER_RAS_GROUP_NODES
};
CASSERT(ARRAY_SIZE(per_cluster_ras_group) < RAS_NODE_INDEX_MAX,
	assert_max_per_cluster_ras_group_size);

static struct ras_aux_data scf_l3_ras_group[] = {
	SCF_L3_BANK_RAS_GROUP_NODES
};
CASSERT(ARRAY_SIZE(scf_l3_ras_group) < RAS_NODE_INDEX_MAX,
	assert_max_scf_l3_ras_group_size);

static struct ras_aux_data ccplex_ras_group[] = {
    CCPLEX_RAS_GROUP_NODES
};
CASSERT(ARRAY_SIZE(ccplex_ras_group) < RAS_NODE_INDEX_MAX,
	assert_max_ccplex_ras_group_size);

/*
 * We have same probe and handler for each error record group, use a macro to
 * simply the record definition.
 */
#define ADD_ONE_ERR_GROUP(errselr_start, group) \
	ERR_RECORD_SYSREG_V1((errselr_start), (uint32_t)ARRAY_SIZE((group)), \
			&tegra194_ras_record_probe, \
			&tegra194_ras_record_handler, (group))

/* RAS error record group information */
static struct err_record_info carmel_ras_records[] = {
	/*
	 * Per core ras error records
	 * ERRSELR starts from 0*256 + Logical_CPU_ID*16 + 0 to
	 * 0*256 + Logical_CPU_ID*16 + 5 for each group.
	 * 8 cores/groups, 6 * 8 nodes in total.
	 */
	ADD_ONE_ERR_GROUP(0x000, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x010, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x020, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x030, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x040, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x050, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x060, per_core_ras_group),
	ADD_ONE_ERR_GROUP(0x070, per_core_ras_group),

	/*
	 * Per cluster ras error records
	 * ERRSELR starts from 2*256 + Logical_Cluster_ID*16 + 0 to
	 * 2*256 + Logical_Cluster_ID*16 + 3.
	 * 4 clusters/groups, 3 * 4 nodes in total.
	 */
	ADD_ONE_ERR_GROUP(0x200, per_cluster_ras_group),
	ADD_ONE_ERR_GROUP(0x210, per_cluster_ras_group),
	ADD_ONE_ERR_GROUP(0x220, per_cluster_ras_group),
	ADD_ONE_ERR_GROUP(0x230, per_cluster_ras_group),

	/*
	 * SCF L3_Bank ras error records
	 * ERRSELR: 3*256 + L3_Bank_ID, L3_Bank_ID: 0-3
	 * 1 groups, 4 nodes in total.
	 */
	ADD_ONE_ERR_GROUP(0x300, scf_l3_ras_group),

	/*
	 * CCPLEX ras error records
	 * ERRSELR: 4*256 + Unit_ID, Unit_ID: 0 - 4
	 * 1 groups, 5 nodes in total.
	 */
	ADD_ONE_ERR_GROUP(0x400, ccplex_ras_group),
};

CASSERT(ARRAY_SIZE(carmel_ras_records) < RAS_NODE_INDEX_MAX,
	assert_max_carmel_ras_records_size);

REGISTER_ERR_RECORD_INFO(carmel_ras_records);

/* dummy RAS interrupt */
static struct ras_interrupt carmel_ras_interrupts[] = {};
REGISTER_RAS_INTERRUPTS(carmel_ras_interrupts);

/*******************************************************************************
 * RAS handler for the platform
 ******************************************************************************/
void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
		void *handle, uint64_t flags)
{
#if ENABLE_FEAT_RAS
	tegra194_ea_handler(ea_reason, syndrome, cookie, handle, flags);
#else
	plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags);
#endif
}
