#include <arch/linker.h>
#include <machine/io.h>
#include <plat/machine/hardware.h>
#include <plat/machine/pic.h>
#define PIC1_BASE 0x20
#define PIC2_BASE 0xa0
BOOT_CODE void
pic_remap_irqs(interrupt_t interrupt)
{
out8(PIC1_BASE, 0x11);
out8(PIC2_BASE, 0x11);
out8(PIC1_BASE + 1, interrupt);
out8(PIC2_BASE + 1, interrupt + 8);
out8(PIC1_BASE + 1, 0x04);
out8(PIC2_BASE + 1, 0x02);
out8(PIC1_BASE + 1, 0x01);
out8(PIC2_BASE + 1, 0x01);
out8(PIC1_BASE + 1, 0x0);
out8(PIC2_BASE + 1, 0x0);
}
BOOT_CODE void pic_disable(void)
{
out8(PIC1_BASE + 1, 0xff);
out8(PIC2_BASE + 1, 0xff);
}
#ifdef CONFIG_IRQ_PIC
void pic_mask_irq(bool_t mask, irq_t irq)
{
uint8_t bit_mask;
uint16_t pic_port;
assert(irq >= irq_isa_min);
assert(irq <= irq_isa_max);
if (irq < 8) {
bit_mask = BIT(irq);
pic_port = PIC1_BASE + 1;
} else {
bit_mask = BIT(irq - 8);
pic_port = PIC2_BASE + 1;
}
if (mask) {
out8(pic_port, (in8(pic_port) | bit_mask));
} else {
out8(pic_port, (in8(pic_port) & ~bit_mask));
}
}
bool_t pic_is_irq_pending(void)
{
uint8_t irr;
out8(PIC1_BASE, 0x0a);
irr = in8(PIC1_BASE);
return irr != 0;
}
static uint16_t pic_get_isr(void)
{
out8(PIC1_BASE, 0x0b);
out8(PIC2_BASE, 0x0b);
return (((uint16_t)in8(PIC2_BASE)) << 8) | in8(PIC1_BASE);
}
void pic_ack_active_irq(void)
{
irq_t irq = getActiveIRQ();
if (irq >= irq_isa_min + 8) {
if (irq != irq_isa_min + 15 || (pic_get_isr() & BIT(15))) {
out8(PIC2_BASE, 0x20);
}
}
if (irq != irq_isa_min + 7 || (pic_get_isr() & BIT(7))) {
out8(PIC1_BASE, 0x20);
}
}
#endif