Minix1.5/kernel/i8259.c
/* This file contains routines for initializing the 8259 interrupt controller:
* enable_irq: enable an interrupt line. The cim...() functions in
* klib88 are specialized versions of this
* init_8259: initialize the 8259(s), since the BIOS does it poorly
*/
#include "kernel.h"
#define ICW1_AT 0x11 /* edge triggered, cascade, need ICW4 */
#define ICW1_PC 0x13 /* edge triggered, no cascade, need ICW4 */
#define ICW1_PS 0x19 /* level triggered, cascade, need ICW4 */
#define ICW3_M 0x04 /* bit 2 for slave on channel 2 */
#define ICW3_S 0x02 /* slave identity is 2 */
#define ICW4_AT 0x01 /* not SFNM, not buffered, normal EOI, 8086 */
#define ICW4_PC 0x09 /* not SFNM, buffered, normal EOI, 8086 */
/*==========================================================================*
* enable_irq *
*==========================================================================*/
PUBLIC void enable_irq(irq_nr)
unsigned irq_nr;
{
/* Clear the corresponding 8259 register bit.
* Be careful not to call this early from main() since it calls unlock().
*/
lock();
if (irq_nr < 8)
out_byte(INT_CTLMASK, in_byte(INT_CTLMASK) & ~(1 << irq_nr));
else
out_byte(INT2_MASK, in_byte(INT2_MASK) & ~(1 << (irq_nr - 8)));
unlock();
}
/*==========================================================================*
* init_8259 *
*==========================================================================*/
PUBLIC void init_8259(master_base, slave_base)
unsigned master_base;
unsigned slave_base;
{
/* Initialize the 8259(s), finishing with all interrupts disabled. */
if (pc_at) {
out_byte(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT);
out_byte(INT_CTLMASK, master_base); /* ICW2 for master */
out_byte(INT_CTLMASK, ICW3_M);
out_byte(INT_CTLMASK, ICW4_AT);
out_byte(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT);
out_byte(INT2_MASK, slave_base); /* ICW2 for slave */
out_byte(INT2_MASK, ICW3_S);
out_byte(INT2_MASK, ICW4_AT);
out_byte(INT2_MASK, ~0);
} else {
out_byte(INT_CTL, ICW1_PC);
out_byte(INT_CTLMASK, master_base); /* no slave */
out_byte(INT_CTLMASK, ICW4_PC);
}
out_byte(INT_CTLMASK, ~0);
}