/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <device/mmio.h>
#include <arch/ioapic.h>
#include <console/console.h>
#include <cpu/x86/lapic.h>
#include <inttypes.h>
#include <types.h>

#define ALL		(0xff << 24)
#define NONE		(0)
#define INT_DISABLED	(1 << 16)
#define INT_ENABLED	(0 << 16)
#define TRIGGER_EDGE	(0 << 15)
#define TRIGGER_LEVEL	(1 << 15)
#define POLARITY_HIGH	(0 << 13)
#define POLARITY_LOW	(1 << 13)
#define PHYSICAL_DEST	(0 << 11)
#define LOGICAL_DEST	(1 << 11)
#define ExtINT		(7 << 8)
#define NMI		(4 << 8)
#define SMI		(2 << 8)
#define INT		(1 << 8)

static u32 io_apic_read(uintptr_t ioapic_base, u32 reg)
{
	write32p(ioapic_base, reg);
	return read32p(ioapic_base + 0x10);
}

static void io_apic_write(uintptr_t ioapic_base, u32 reg, u32 value)
{
	write32p(ioapic_base, reg);
	write32p(ioapic_base + 0x10, value);
}

static void write_vector(uintptr_t ioapic_base, u8 vector, u32 high, u32 low)
{
	io_apic_write(ioapic_base, vector * 2 + 0x10, low);
	io_apic_write(ioapic_base, vector * 2 + 0x11, high);

	printk(BIOS_SPEW, "IOAPIC: vector 0x%02x value 0x%08x 0x%08x\n",
	       vector, high, low);
}

/* Bits 23-16 of register 0x01 specify the maximum redirection entry, which
 * is the number of interrupts minus 1. */
unsigned int ioapic_get_max_vectors(uintptr_t ioapic_base)
{
	u32 reg;
	u8 count;

	reg = io_apic_read(ioapic_base, 0x01);
	count = (reg >> 16) & 0xff;

	if (count == 0xff)
		count = 23;
	count++;

	printk(BIOS_DEBUG, "IOAPIC: %d interrupts\n", count);
	return count;
}

/* Set maximum number of redirection entries (MRE). It is write-once register
 * for some chipsets, and a negative mre_count will lock it to the number
 * of vectors read from the register. */
void ioapic_set_max_vectors(uintptr_t ioapic_base, int mre_count)
{
	u32 reg;
	u8 count;

	reg = io_apic_read(ioapic_base, 0x01);
	count = (reg >> 16) & 0xff;
	if (mre_count > 0)
		count = mre_count - 1;
	reg &= ~(0xff << 16);
	reg |= count << 16;
	io_apic_write(ioapic_base, 0x01, reg);
}

void ioapic_lock_max_vectors(uintptr_t ioapic_base)
{
	ioapic_set_max_vectors(ioapic_base, -1);
}

static void clear_vectors(uintptr_t ioapic_base, u8 first, u8 last)
{
	u32 low, high;
	u8 i;

	printk(BIOS_DEBUG, "IOAPIC: Clearing IOAPIC at %" PRIxPTR "\n", ioapic_base);

	low = INT_DISABLED;
	high = NONE;

	for (i = first; i <= last; i++)
		write_vector(ioapic_base, i, high, low);

	if (io_apic_read(ioapic_base, 0x10) == 0xffffffff) {
		printk(BIOS_WARNING, "IOAPIC not responding.\n");
		return;
	}
}

static void route_i8259_irq0(uintptr_t ioapic_base)
{
	u32 bsp_lapicid = lapicid();
	u32 low, high;

	ASSERT(bsp_lapicid < 255);

	printk(BIOS_DEBUG, "IOAPIC: Bootstrap Processor Local APIC = 0x%02x\n",
	       bsp_lapicid);

	/* Enable Virtual Wire Mode. Should this be LOGICAL_DEST instead? */
	low = INT_ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
	high = bsp_lapicid << (56 - 32);

	write_vector(ioapic_base, 0, high, low);

	if (io_apic_read(ioapic_base, 0x10) == 0xffffffff) {
		printk(BIOS_WARNING, "IOAPIC not responding.\n");
		return;
	}
}

static void set_ioapic_id(uintptr_t ioapic_base, u8 ioapic_id)
{
	int i;

	printk(BIOS_DEBUG, "IOAPIC: Initializing IOAPIC at %" PRIxPTR "\n",
	       ioapic_base);
	printk(BIOS_DEBUG, "IOAPIC: ID = 0x%02x\n", ioapic_id);

	io_apic_write(ioapic_base, 0x00,
		      (io_apic_read(ioapic_base, 0x00) & 0xf0ffffff) | (ioapic_id << 24));

	printk(BIOS_SPEW, "IOAPIC: Dumping registers\n");
	for (i = 0; i < 3; i++)
		printk(BIOS_SPEW, "  reg 0x%04x: 0x%08x\n", i,
		       io_apic_read(ioapic_base, i));
}

u8 get_ioapic_id(uintptr_t ioapic_base)
{
	/*
	 * According to 82093AA I/O ADVANCED PROGRAMMABLE INTERRUPT CONTROLLER (IOAPIC)
	 * only 4 bits (24:27) are used for the ID. In practice the upper bits are either
	 * always 0 or used for larger IDs.
	 */
	return (io_apic_read(ioapic_base, 0x00) >> 24) & 0xff;
}

u8 get_ioapic_version(uintptr_t ioapic_base)
{
	return io_apic_read(ioapic_base, 0x01) & 0xff;
}

void ioapic_set_boot_config(uintptr_t ioapic_base, bool irq_on_fsb)
{
	if (irq_on_fsb) {
		/*
		 * For the Pentium 4 and above APICs deliver their interrupts
		 * on the front side bus, enable that.
		 */
		printk(BIOS_DEBUG, "IOAPIC: Enabling interrupts on FSB\n");
		io_apic_write(ioapic_base, 0x03,
			      io_apic_read(ioapic_base, 0x03) | (1 << 0));
	} else {
		printk(BIOS_DEBUG,
			"IOAPIC: Enabling interrupts on APIC serial bus\n");
		io_apic_write(ioapic_base, 0x03, 0);
	}
}

void setup_ioapic(uintptr_t ioapic_base, u8 ioapic_id)
{
	set_ioapic_id(ioapic_base, ioapic_id);
	clear_vectors(ioapic_base, 0, ioapic_get_max_vectors(ioapic_base) - 1);
	route_i8259_irq0(ioapic_base);
}

void register_new_ioapic_gsi0(uintptr_t ioapic_base)
{
	setup_ioapic(ioapic_base, 0);
}

void register_new_ioapic(uintptr_t ioapic_base)
{
	static u8 ioapic_id;
	ioapic_id++;
	set_ioapic_id(ioapic_base, ioapic_id);
	clear_vectors(ioapic_base, 0, ioapic_get_max_vectors(ioapic_base) - 1);
}
