aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2011-04-11 22:47:31 -0700
committerEric W. Biederman <ebiederm@xmission.com>2011-04-12 14:41:18 -0700
commitabf7a9d75878f7eac2fc363d934fce52fa33f532 (patch)
treec3251790c58afa5d6c5e08e4b8b0c77ad5940529 /core
parentbbbe225aebfe764428f9bc021e2b64a363dfe41b (diff)
downloadsyslinux-abf7a9d75878f7eac2fc363d934fce52fa33f532.tar.gz
syslinux-abf7a9d75878f7eac2fc363d934fce52fa33f532.tar.xz
syslinux-abf7a9d75878f7eac2fc363d934fce52fa33f532.zip
core: pxe: Improve the situation with installing and uninstalling irq handlers
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'core')
-rw-r--r--core/fs/pxe/isr.c56
-rw-r--r--core/fs/pxe/pxe.h8
-rw-r--r--core/include/core.h1
-rw-r--r--core/lwip/src/netif/undiif.c22
-rw-r--r--core/pm.inc1
5 files changed, 67 insertions, 21 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index 4eac5aaf..4dcadc18 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -12,6 +12,46 @@
extern uint8_t pxe_irq_pending;
static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
+static struct thread *pxe_thread;
+
+bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
+{
+ far_ptr_t *entry;
+ unsigned int vec;
+
+ if (irq < 8)
+ vec = irq + 0x08;
+ else if (irq < 16)
+ vec = (irq - 8) + 0x70;
+ else
+ return false;
+
+ entry = (far_ptr_t *)(vec << 2);
+ *old = *entry;
+ entry->ptr = (uint32_t)isr;
+ return true;
+}
+
+bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old)
+{
+ far_ptr_t *entry;
+ unsigned int vec;
+
+ if (irq < 8)
+ vec = irq + 0x08;
+ else if (irq < 16)
+ vec = (irq - 8) + 0x70;
+ else
+ return false;
+
+ entry = (far_ptr_t *)(vec << 2);
+
+ if (entry->ptr != (uint32_t)isr)
+ return false;
+
+ *entry = *old;
+ return true;
+}
static void pm_return(void)
{
@@ -99,6 +139,20 @@ void pxe_init_isr(void)
* avoid packet loss we need to move it into memory that we ourselves
* manage, as soon as possible.
*/
- start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL);
+ pxe_thread = start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL);
core_pm_hook = pm_return;
}
+
+
+void pxe_cleanup_isr(void)
+{
+ static __lowmem struct s_PXENV_UNDI_CLOSE undi_close;
+ int err;
+
+ core_pm_hook = core_pm_null_hook;
+ kill_thread(pxe_thread);
+
+ memset(&undi_close, 0, sizeof(undi_close));
+ err = pxe_call(PXENV_UNDI_CLOSE, &undi_close);
+ uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
+}
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index f41bf828..810646ea 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -236,9 +236,17 @@ static inline uint32_t gateway(uint32_t ip)
* functions
*/
+/* pxeisr.inc */
+extern uint8_t pxe_irq_vector;
+extern void pxe_isr(void);
+extern far_ptr_t pxe_irq_chain;
+
/* isr.c */
void pxe_init_isr(void);
+void pxe_cleanup_isr(void);
void pxe_poll(void);
+bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old);
+bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old);
/* pxe.c */
bool ip_ok(uint32_t);
diff --git a/core/include/core.h b/core/include/core.h
index 034e9965..46c41bc0 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -21,6 +21,7 @@ extern char ConfigFile[];
extern void getlinsec(void);
/* pm.inc */
+void core_pm_null_hook(void);
extern void (*core_pm_hook)(void);
/* getc.inc */
diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c
index 1baeb975..a925e289 100644
--- a/core/lwip/src/netif/undiif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -57,13 +57,13 @@
#include "netif/ppp_oe.h"
#include "lwip/netifapi.h"
#include "lwip/tcpip.h"
+#include "../../../fs/pxe/pxe.h"
#include <inttypes.h>
#include <string.h>
#include <syslinux/pxe_api.h>
#include <dprintf.h>
-int pxe_call(int, void *);
#define PKTBUF_SIZE 2048
/* Define those to better describe your network interface. */
@@ -79,24 +79,6 @@ static struct netif undi_netif;
* @param netif the already initialized lwip network interface structure
* for this undiif
*/
-extern uint8_t pxe_irq_vector;
-extern void pxe_isr(void);
-
-/* XXX: move this somewhere sensible */
-static void install_irq_vector(uint8_t irq, void (*isr)(void))
-{
- unsigned int vec;
-
- if (irq < 8)
- vec = irq + 0x08;
- else if (irq < 16)
- vec = (irq - 8) + 0x70;
- else
- return; /* ERROR */
-
- *(uint32_t *)(vec << 2) = (uint32_t)isr;
-}
-
static void
low_level_init(struct netif *netif)
{
@@ -131,7 +113,7 @@ low_level_init(struct netif *netif)
/* Install the interrupt vector */
pxe_irq_vector = undi_info.IntNumber;
- install_irq_vector(pxe_irq_vector, pxe_isr);
+ install_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
/* Open the UNDI stack - you'd think the BC would have done this... */
undi_open.PktFilter = 0x0003; /* FLTR_DIRECTED | FLTR_BRDCST */
diff --git a/core/pm.inc b/core/pm.inc
index 80685e59..8690cabe 100644
--- a/core/pm.inc
+++ b/core/pm.inc
@@ -222,6 +222,7 @@ pm_irq:
; threaded derivatives to run the scheduler, or examine the result from
; interrupt routines.
;
+ global core_pm_null_hook
core_pm_null_hook:
ret