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)
{
* 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);
+}
* 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);
extern void getlinsec(void);
/* pm.inc */
+void core_pm_null_hook(void);
extern void (*core_pm_hook)(void);
/* getc.inc */
#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. */
* @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)
{
/* 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 */
; threaded derivatives to run the scheduler, or examine the result from
; interrupt routines.
;
+ global core_pm_null_hook
core_pm_null_hook:
ret