/*
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/arch/vm/interrupts_gicv3.h"

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

#include "hf/arch/cpu.h"

#include "hf/dlog.h"

#include "../msr.h"

extern uint8_t vector_table_el1;
static void (*irq_callback)(void);

void irq_current(void)
{
	if (irq_callback != NULL) {
		irq_callback();
	}
}

void exception_setup(void (*irq)(void))
{
	irq_callback = irq;

	/* Set exception vector table. */
	write_msr(VBAR_EL1, &vector_table_el1);

	write_msr(ICC_CTLR_EL1, 0);
}

void interrupt_gic_setup(void)
{
	GICD_CTLR = 1u << 4    /* Enable affinity routing. */
		    | 1u << 1; /* Enable group 1 non-secure interrupts. */

	/* Mark CPU as awake. */
	GICR_WAKER &= ~(1u << 1);
	while ((GICR_WAKER & (1u << 2)) != 0) {
		dlog("Waiting for ChildrenAsleep==0\n");
	}

	/* Put interrupts into non-secure group 1. */
	dlog("GICR_IGROUPR0 was %x\n", 0xffffffff, GICR_IGROUPR0);
	GICR_IGROUPR0 = 0xffffffff;
	dlog("wrote %x to GICR_IGROUPR0, got back %x\n", 0xffffffff,
	     GICR_IGROUPR0);
	/* Enable non-secure group 1. */
	write_msr(ICC_IGRPEN1_EL1, 0x00000001);
	dlog("wrote %x to ICC_IGRPEN1_EL1, got back %x\n", 0x00000001,
	     read_msr(ICC_IGRPEN1_EL1));
}

void interrupt_enable(uint32_t intid, bool enable)
{
	if (enable) {
		GICD_ISENABLER(intid / 32) |= 1 << (intid % 32);
		if (intid < 32) {
			GICR_ISENABLER0 |= 1 << intid;
		}
	} else {
		GICD_ICENABLER(intid / 32) |= 1 << (intid % 32);
		if (intid < 32) {
			GICR_ICENABLER0 |= 1 << intid;
		}
	}
}

void interrupt_enable_all(bool enable)
{
	uint32_t i;

	if (enable) {
		GICR_ISENABLER0 = 0xffffffff;
		for (i = 0; i < 32; ++i) {
			GICD_ISENABLER(i) = 0xffffffff;
		}
	} else {
		GICR_ICENABLER0 = 0x00000000;
		for (i = 0; i < 32; ++i) {
			GICD_ICENABLER(i) = 0x00000000;
		}
	}
}

void interrupt_set_priority_mask(uint8_t min_priority)
{
	write_msr(ICC_PMR_EL1, min_priority);
}

void interrupt_set_priority(uint32_t intid, uint8_t priority)
{
	GICD_IPRIORITYR(intid) = priority;
}

void interrupt_set_edge_triggered(uint32_t intid, bool edge_triggered)
{
	uint32_t bit = 1u << (intid % 16 * 2 + 1);

	if (intid < 32) {
		if (edge_triggered) {
			GICR_ICFGR(intid / 16) |= bit;
		} else {
			GICR_ICFGR(intid / 16) &= ~bit;
		}
	} else {
		if (edge_triggered) {
			GICD_ICFGR(intid / 16) |= bit;
		} else {
			GICD_ICFGR(intid / 16) &= ~bit;
		}
	}
}

void interrupt_send_sgi(uint8_t intid, bool irm, uint8_t affinity3,
			uint8_t affinity2, uint8_t affinity1,
			uint16_t target_list)
{
	uint64_t sgi_register =
		((uint64_t)target_list) | ((uint64_t)affinity1 << 16) |
		(((uint64_t)intid & 0x0f) << 24) | ((uint64_t)affinity2 << 32) |
		((uint64_t)irm << 40) | ((uint64_t)affinity3 << 48);

	write_msr(ICC_SGI1R_EL1, sgi_register);
}

uint32_t interrupt_get_and_acknowledge(void)
{
	return read_msr(ICC_IAR1_EL1);
}

void interrupt_end(uint32_t intid)
{
	write_msr(ICC_EOIR1_EL1, intid);
}

void sync_current_exception(uintreg_t esr, uintreg_t elr)
{
	switch (esr >> 26) {
	case 0x25: /* EC = 100101, Data abort. */
		dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", elr, esr,
		     esr >> 26);
		if (!(esr & (1u << 10))) { /* Check FnV bit. */
			dlog(", far=0x%x", read_msr(far_el1));
		} else {
			dlog(", far=invalid");
		}

		dlog("\n");
		break;

	default:
		dlog("Unknown current sync exception pc=0x%x, esr=0x%x, "
		     "ec=0x%x\n",
		     elr, esr, esr >> 26);
	}

	for (;;) {
		/* do nothing */
	}
}

void interrupt_wait(void)
{
	__asm__ volatile("wfi");
}
