/* Copyright (c) 2009, 2014 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * PIC: 8259 interrupt controller */

#include <arch/pic.h>
#include <arch/x86.h>
#include <atomic.h>
#include <assert.h>
#include <stdio.h>

spinlock_t piclock = SPINLOCK_INITIALIZER_IRQSAVE;

/* Remaps the Programmable Interrupt Controller to use IRQs 32-47
 * http://wiki.osdev.org/PIC
 * Check osdev for a more thorough explanation/implementation.
 * http://bochs.sourceforge.net/techspec/PORTS.LST  */
void pic_remap(void)
{
	spin_lock_irqsave(&piclock);
	/* start initialization (ICW1) */
	outb(PIC1_CMD, 0x11);
	outb(PIC2_CMD, 0x11);
	/* set new offsets (ICW2) */
	outb(PIC1_DATA, PIC1_OFFSET);
	outb(PIC2_DATA, PIC2_OFFSET);
	/* set up cascading (ICW3) */
	outb(PIC1_DATA, 0x04);
	outb(PIC2_DATA, 0x02);
	/* other stuff (put in 8086/88 mode, or whatever) (ICW4) */
	outb(PIC1_DATA, 0x01);
	outb(PIC2_DATA, 0x01);
	/* Init done, further data R/W access the interrupt mask */
	/* set masks, defaulting to all masked for now */
	outb(PIC1_DATA, 0xff);
	outb(PIC2_DATA, 0xff);
	spin_unlock_irqsave(&piclock);
}

void pic_mask_irq(struct irq_handler *unused, int trap_nr)
{
	int irq = trap_nr - PIC1_OFFSET;

	spin_lock_irqsave(&piclock);
	if (irq > 7)
		outb(PIC2_DATA, inb(PIC2_DATA) | (1 << (irq - 8)));
	else
		outb(PIC1_DATA, inb(PIC1_DATA) | (1 << irq));
	spin_unlock_irqsave(&piclock);
}

void pic_unmask_irq(struct irq_handler *unused, int trap_nr)
{
	int irq = trap_nr - PIC1_OFFSET;
	printd("PIC unmask for TRAP %d, IRQ %d\n", trap_nr, irq);
	spin_lock_irqsave(&piclock);
	if (irq > 7) {
		outb(PIC2_DATA, inb(PIC2_DATA) & ~(1 << (irq - 8)));
		// make sure irq2 is unmasked
		outb(PIC1_DATA, inb(PIC1_DATA) & 0xfb);
	} else
		outb(PIC1_DATA, inb(PIC1_DATA) & ~(1 << irq));
	spin_unlock_irqsave(&piclock);
}

void pic_mask_all(void)
{
	for (int i = 0 + PIC1_OFFSET; i < 16 + PIC1_OFFSET; i++)
		pic_mask_irq(0, i);
}

/* Aka, the IMR.  Simply reading the data port are OCW1s. */
uint16_t pic_get_mask(void)
{
	uint16_t ret;

	spin_lock_irqsave(&piclock);
	ret = (inb(PIC2_DATA) << 8) | inb(PIC1_DATA);
	spin_unlock_irqsave(&piclock);
	return ret;
}

static uint16_t __pic_get_irq_reg(int ocw3)
{
	uint16_t ret;

	spin_lock_irqsave(&piclock);
	/* OCW3 to PIC CMD to get the register values.  PIC2 is chained, and
	 * represents IRQs 8-15.  PIC1 is IRQs 0-7, with 2 being the chain */
	outb(PIC1_CMD, ocw3);
	outb(PIC2_CMD, ocw3);
	ret = (inb(PIC2_CMD) << 8) | inb(PIC1_CMD);
	spin_unlock_irqsave(&piclock);
	return ret;
}

/* Returns the combined value of the cascaded PICs irq request register */
uint16_t pic_get_irr(void)
{
	return __pic_get_irq_reg(PIC_READ_IRR);
}

/* Returns the combined value of the cascaded PICs irq service register */
uint16_t pic_get_isr(void)
{
	return __pic_get_irq_reg(PIC_READ_ISR);
}

/* Takes a raw vector/trap number (32-47), not a device IRQ (0-15) */
bool pic_check_spurious(int trap_nr)
{
	/* the PIC may send spurious irqs via one of the chips irq 7.  if the
	 * isr doesn't show that irq, then it was spurious, and we don't send an
	 * eoi.  Check out http://wiki.osdev.org/8259_PIC#Spurious_IRQs */
	if ((trap_nr == PIC1_SPURIOUS) && !(pic_get_isr() & (1 << 7))) {
		/* want to know if this happens */
		printd("Spurious PIC1 irq!\n");
		return TRUE;
	}
	if ((trap_nr == PIC2_SPURIOUS) && !(pic_get_isr() & (1 << 15))) {
		/* want to know if this happens */
		printd("Spurious PIC2 irq!\n");
		/* for the cascaded PIC, we *do* need to send an EOI to the
		 * master's cascade irq (2). */
		pic_send_eoi(2 + PIC1_OFFSET);
		return TRUE;
	}
	return FALSE;
}

void pic_send_eoi(int trap_nr)
{
	int irq = trap_nr - PIC1_OFFSET;

	spin_lock_irqsave(&piclock);
	// all irqs beyond the first seven need to be chained to the slave
	if (irq > 7)
		outb(PIC2_CMD, PIC_EOI);
	outb(PIC1_CMD, PIC_EOI);
	spin_unlock_irqsave(&piclock);
}
