Use level-triggered ISA interrupts.
diff --git a/init.c b/init.c index 65a0909..76f2d59 100644 --- a/init.c +++ b/init.c
@@ -234,6 +234,11 @@ static void init_i8259 (void) { + /* ??? MILO initializes the PIC as edge triggered; I do not know how SRM + initializes them. However, Linux seems to expect that these are level + triggered. That may be a kernel bug, but level triggers are more + reliable anyway so lets go with that. */ + /* Initialize the slave PIC. */ outb(0x11, PORT_PIC2_CMD); /* ICW1: edge trigger, cascade, ICW4 req */ outb(0x08, PORT_PIC2_DATA); /* ICW2: irq offset = 8 */ @@ -246,6 +251,12 @@ outb(0x04, PORT_PIC1_DATA); /* ICW3: slave control INTC2 */ outb(0x01, PORT_PIC1_DATA); /* ICW4 */ + /* Initialize level triggers. The CY82C693UB that's on real alpha + hardware doesn't have this; this is a PIIX extension. However, + QEMU doesn't implement regular level triggers. */ + outb(0xff, PORT_PIC2_ELCR); + outb(0xff, PORT_PIC1_ELCR); + /* Disable all interrupts. */ outb(0xff, PORT_PIC2_DATA); outb(0xff, PORT_PIC1_DATA);
diff --git a/ioport.h b/ioport.h index 0876c2a..b1bb4b3 100644 --- a/ioport.h +++ b/ioport.h
@@ -53,6 +53,8 @@ #define PORT_HD_DATA 0x03f6 #define PORT_FD_DIR 0x03f7 #define PORT_SERIAL1 0x03f8 +#define PORT_PIC1_ELCR 0x04d0 +#define PORT_PIC2_ELCR 0x04d1 #define PORT_PCI_CMD 0x0cf8 #define PORT_PCI_REBOOT 0x0cf9 #define PORT_PCI_DATA 0x0cfc