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

#include <arch_helpers.h>
#include <debug.h>
#include <ea_handle.h>
#include <ehf.h>
#include <platform.h>
#include <ras.h>
#include <ras_arch.h>

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

/* 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, ret;
	int probe_data;
	struct err_record_info *info;

	const struct err_handler_data err_data = {
		.version = ERR_HANDLER_VERSION,
		.ea_reason = ea_reason,
		.interrupt = 0,
		.syndrome = 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 (1) {
			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 != 0);
}

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

	if (ras_interrupt_mapping.num_intrs == 0)
		return;

	last = start[0].intr_number;
	for (i = 1; i < ras_interrupt_mapping.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_mapping.intrs;
	struct ras_interrupt *selected = NULL;
	int start, end, mid, probe_data, 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_mapping.num_intrs > 0);

	start = 0;
	end = ras_interrupt_mapping.num_intrs;
	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();
	}


	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);
	selected->err_record->handler(selected->err_record, probe_data,
			&err_data);

	return 0;
}

void 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);
}
