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

#include <stdbool.h>

#include <arch_helpers.h>
#include <bl31/ea_handle.h>
#include <bl31/ehf.h>
#include <common/debug.h>
#include <lib/extensions/ras.h>
#include <lib/extensions/ras_arch.h>
#include <plat/common/platform.h>

#ifndef PLAT_RAS_PRI
# error Platform must define RAS priority value
#endif

/*
 * Function to convert architecturally-defined primary error code SERR,
 * bits[7:0] from ERR<n>STATUS to its corresponding error string.
 */
const char *ras_serr_to_str(unsigned int serr)
{
	const char *str[ERROR_STATUS_NUM_SERR] = {
		"No error",
		"IMPLEMENTATION DEFINED error",
		"Data value from (non-associative) internal memory",
		"IMPLEMENTATION DEFINED pin",
		"Assertion failure",
		"Error detected on internal data path",
		"Data value from associative memory",
		"Address/control value from associative memory",
		"Data value from a TLB",
		"Address/control value from a TLB",
		"Data value from producer",
		"Address/control value from producer",
		"Data value from (non-associative) external memory",
		"Illegal address (software fault)",
		"Illegal access (software fault)",
		"Illegal state (software fault)",
		"Internal data register",
		"Internal control register",
		"Error response from slave",
		"External timeout",
		"Internal timeout",
		"Deferred error from slave not supported at master"
	};

	/*
	 * All other values are reserved. Reserved values might be defined
	 * in a future version of the architecture
	 */
	if (serr >= ERROR_STATUS_NUM_SERR)
		return "unknown SERR";

	return str[serr];
}

/* Handler that receives External Aborts on RAS-capable systems */
int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
		void *handle, uint64_t flags)
{
	unsigned int i, n_handled = 0;
	int probe_data, ret;
	struct err_record_info *info;

	const struct err_handler_data err_data = {
		.version = ERR_HANDLER_VERSION,
		.ea_reason = ea_reason,
		.interrupt = 0,
		.syndrome = (uint32_t) syndrome,
		.flags = flags,
		.cookie = cookie,
		.handle = handle
	};

	for_each_err_record_info(i, info) {
		assert(info->probe != NULL);
		assert(info->handler != NULL);

		/* Continue probing until the record group signals no error */
		while (true) {
			if (info->probe(info, &probe_data) == 0)
				break;

			/* Handle error */
			ret = info->handler(info, probe_data, &err_data);
			if (ret != 0)
				return ret;

			n_handled++;
		}
	}

	return (n_handled != 0U) ? 1 : 0;
}

#if ENABLE_ASSERTIONS
static void assert_interrupts_sorted(void)
{
	unsigned int i, last;
	struct ras_interrupt *start = ras_interrupt_mappings.intrs;

	if (ras_interrupt_mappings.num_intrs == 0UL)
		return;

	last = start[0].intr_number;
	for (i = 1; i < ras_interrupt_mappings.num_intrs; i++) {
		assert(start[i].intr_number > last);
		last = start[i].intr_number;
	}
}
#endif

/*
 * Given an RAS interrupt number, locate the registered handler and call it. If
 * no handler was found for the interrupt number, this function panics.
 */
static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags,
		void *handle, void *cookie)
{
	struct ras_interrupt *ras_inrs = ras_interrupt_mappings.intrs;
	struct ras_interrupt *selected = NULL;
	int probe_data = 0;
	int start, end, mid, ret __unused;

	const struct err_handler_data err_data = {
		.version = ERR_HANDLER_VERSION,
		.interrupt = intr_raw,
		.flags = flags,
		.cookie = cookie,
		.handle = handle
	};

	assert(ras_interrupt_mappings.num_intrs > 0UL);

	start = 0;
	end = (int)ras_interrupt_mappings.num_intrs - 1;
	while (start <= end) {
		mid = ((end + start) / 2);
		if (intr_raw == ras_inrs[mid].intr_number) {
			selected = &ras_inrs[mid];
			break;
		} else if (intr_raw < ras_inrs[mid].intr_number) {
			/* Move left */
			end = mid - 1;
		} else {
			/* Move right */
			start = mid + 1;
		}
	}

	if (selected == NULL) {
		ERROR("RAS interrupt %u has no handler!\n", intr_raw);
		panic();
	}

	if (selected->err_record->probe != NULL) {
		ret = selected->err_record->probe(selected->err_record, &probe_data);
		assert(ret != 0);
	}

	/* Call error handler for the record group */
	assert(selected->err_record->handler != NULL);
	(void) selected->err_record->handler(selected->err_record, probe_data,
			&err_data);

	return 0;
}

void __init ras_init(void)
{
#if ENABLE_ASSERTIONS
	/* Check RAS interrupts are sorted */
	assert_interrupts_sorted();
#endif

	/* Register RAS priority handler */
	ehf_register_priority_handler(PLAT_RAS_PRI, ras_interrupt_handler);
}
