From ef1e15adc91cd0d26fe70df00ec7d94b1417fa87 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 30 Mar 2012 14:44:03 -0700 Subject: pxe: Unmask the cascade if applicable, handle bad IRQ numbers IRQ 2 is really IRQ 9; if IRQ > 15 then it is meaningless. Also, since we enable the IRQ at the PIC "just in case", we might also have to enable the cascade for IRQ 8-15. Signed-off-by: H. Peter Anvin --- core/fs/pxe/isr.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c index 15287247..0c0b8991 100644 --- a/core/fs/pxe/isr.c +++ b/core/fs/pxe/isr.c @@ -21,7 +21,6 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old) far_ptr_t *entry; unsigned int vec; uint8_t mask; - uint16_t maskreg; irq_state_t irqstate; if (irq < 8) @@ -38,10 +37,18 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old) entry->ptr = (uint32_t)isr; /* Enable this interrupt at the PIC level, just in case... */ - maskreg = 0x21 + ((irq & 8) << (7-3)); - mask = inb(maskreg); - mask &= ~(1 << (irq & 3)); - outb(mask, maskreg); + if (irq >= 8) { + mask = inb(0x21); + mask &= ~(1 << 2); /* Enable cascade */ + outb(mask, 0x21); + mask = inb(0xa1); + mask &= ~(1 << (irq & 3)); + outb(0xa1, mask); + } else { + mask = inb(0x21); + mask &= ~(1 << (irq & 3)); + outb(0x21, mask); + } irq_restore(irqstate); @@ -185,13 +192,19 @@ void pxe_init_isr(void) */ void pxe_start_isr(void) { - pxe_irq_vector = pxe_undi_info.IntNumber; /* Used in 16-bit code */ + int irq = pxe_undi_info.IntNumber; + + if (irq == 2) + irq = 9; /* IRQ 2 is really IRQ 9 */ + else if (irq > 15) + irq = 0; /* Invalid IRQ */ + + pxe_irq_vector = irq; - if (pxe_undi_info.IntNumber) - install_irq_vector(pxe_undi_info.IntNumber, pxe_isr, &pxe_irq_chain); + if (irq) + install_irq_vector(irq, pxe_isr, &pxe_irq_chain); - if (!pxe_undi_info.IntNumber || - !(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ)) + if (!irq || !(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ)) poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY, pxe_poll_thread, NULL); } @@ -210,8 +223,8 @@ int reset_pxe(void) if (undi_close.Status) printf("PXENV_UNDI_CLOSE failed: 0x%x\n", undi_close.Status); - if (pxe_undi_info.IntNumber) - uninstall_irq_vector(pxe_undi_info.IntNumber, pxe_isr, &pxe_irq_chain); + if (pxe_irq_vector) + uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain); if (poll_thread) kill_thread(poll_thread); -- cgit v1.2.1