static ushort irqmask =0xFFFF&~(1<<IRQ_SLAVE);
static void
pic_setmask(ushort mask)
{
irqmask=mask;
outb(IO_PIC1+1);
outb(IO_PIC2+1,mask >>8);
}
void
pic_enable(int irq)
{
pic_setmask(irqmask&~(1<<irq));
}
//Initialize the 8259A interrupt controllers
void
pic_init(void)
{
//mask all interrupt
outb(IO_PIC1+1,0xff);
outb(IO_PIC2+1,0xff);
//set up master (8259A-1)
//ICW1:0001g0hi
//g:0=edge triggering 1= level triggering
//h:0=cascaded PICs 1=master only
//i:0=no iCW4,1=ICW4 required
outb(IO_PIC1,0x11);
//iCW2:vector offset
outb(IO_PIC1+1,IRQ_OFFSET);
//ICW3:(master PIC )bit mask of IR lines connected to slave
(slave PIC) 3-bit #of slave's connection to master
outb(IO_PIC1,1<<IRQ_offset);
//icw4: 000nbmap
//n:1=special fully nested mode
//b: 1=buffered mode
//m:0=slave PICs, 1=master PIC
(ignored when b is 0, as the master/slave role
can be hardwired)
a: 1=Automatic EOI mode
p:0=MCS-80/85 mode ,1=intel x86 mode
outb(IO_PIC1+1,0x3);
//set up slave (8259A-2)
outb(IO_PIC2,0x11);
outb(IO_PIC2+1,IRQ_OFFSET+8);
outb(IO_PIC2+1,IRQ_SLAVE);
//NB Automatic EOI mode doesnot tend to work on the slave ;
//Linux source code says it to be investigate
outb(IO_PIC+1,0x3);
//ocw3:0ef01prs
//ef:0x =NOP,10=clear specific mask 11=set specific mask
//p: 0=no polling ,1=polling mode
//rs:0x=NOP,10=read IRR,11=read ISR
outb(IO_PIC1,0x68); //clear specfic mask
outb(IO_PIC1,0x0a); //read IRR by fault