summaryrefslogtreecommitdiff
path: root/core/fs/pxe/isr.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-05-09 20:35:35 -0700
committerH. Peter Anvin <hpa@zytor.com>2011-05-09 20:35:35 -0700
commitcd89ddbde2e1680f537a32010d64fd5465330122 (patch)
tree6f1f4f6f465e6d3013ba7405d62301b1c765f4ae /core/fs/pxe/isr.c
parent47688fb9b6c645fbc62ebe341a415043fad7283a (diff)
downloadsyslinux-cd89ddbde2e1680f537a32010d64fd5465330122.tar.gz
pxe: when hooking an interrupt, explicitly enable it at the PIC
At least gPXE/iPXE apparently enters the NBP with the interrupt line disabled at the PIC; explicitly enable it instead. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'core/fs/pxe/isr.c')
-rw-r--r--core/fs/pxe/isr.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index bbad372e..be8d38f8 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -9,6 +9,8 @@
#include "thread.h"
#include "pxe.h"
#include <string.h>
+#include <sys/cpu.h>
+#include <sys/io.h>
extern uint8_t pxe_irq_pending;
static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
@@ -18,6 +20,9 @@ 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)
vec = irq + 0x08;
@@ -26,10 +31,20 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
else
return false;
+ irqstate = irq_save();
+
entry = (far_ptr_t *)(vec << 2);
*old = *entry;
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);
+
+ irq_restore(irqstate);
+
printf("UNDI: IRQ %d(0x%02x): %04x:%04x -> %04x:%04x\n", irq, vec,
old->seg, old->offs, entry->seg, entry->offs);