[syslinux:lwip] pxe: when hooking an interrupt, explicitly enable it at the PIC

syslinux-bot for H. Peter Anvin hpa at zytor.com
Mon May 9 20:49:32 PDT 2011


Commit-ID:  cd89ddbde2e1680f537a32010d64fd5465330122
Gitweb:     http://syslinux.zytor.com/commit/cd89ddbde2e1680f537a32010d64fd5465330122
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Mon, 9 May 2011 20:35:35 -0700
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Mon, 9 May 2011 20:35:35 -0700

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 at zytor.com>


---
 com32/include/sys/cpu.h |   23 +++++++++++++++++++++++
 core/fs/pxe/isr.c       |   15 +++++++++++++++
 core/include/thread.h   |   23 -----------------------
 3 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/com32/include/sys/cpu.h b/com32/include/sys/cpu.h
index 53a6250..695ff29 100644
--- a/com32/include/sys/cpu.h
+++ b/com32/include/sys/cpu.h
@@ -139,4 +139,27 @@ static inline void sti(void)
     asm volatile("sti");
 }
 
+typedef unsigned long irq_state_t;
+
+static inline irq_state_t irq_state(void)
+{
+    irq_state_t __st;
+
+    asm volatile("pushfl ; popl %0" : "=rm" (__st));
+    return __st;
+}
+
+static inline irq_state_t irq_save(void)
+{
+    irq_state_t __st = irq_state();
+    cli();
+    return __st;
+}
+
+static inline void irq_restore(irq_state_t __st)
+{
+    asm volatile("pushl %0 ; popfl" : : "rm" (__st));
+}
+
+
 #endif
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index bbad372..be8d38f 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);
 
diff --git a/core/include/thread.h b/core/include/thread.h
index 73e8824..213fb44 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -80,29 +80,6 @@ mstime_t sem_down(struct semaphore *, mstime_t);
 void sem_up(struct semaphore *);
 void sem_init(struct semaphore *, int);
 
-typedef unsigned long irq_state_t;
-
-static inline irq_state_t irq_state(void)
-{
-    irq_state_t __st;
-
-    asm volatile("pushfl ; popl %0" : "=rm" (__st));
-    return __st;
-}
-
-static inline irq_state_t irq_save(void)
-{
-    irq_state_t __st;
-
-    asm volatile("pushfl ; popl %0 ; cli" : "=rm" (__st));
-    return __st;
-}
-
-static inline void irq_restore(irq_state_t __st)
-{
-    asm volatile("pushl %0 ; popfl" : : "rm" (__st));
-}
-
 struct thread *start_thread(const char *name, size_t stack_size, int prio,
 			    void (*start_func)(void *), void *func_arg);
 void __exit_thread(void);



More information about the Syslinux-commits mailing list