diff options
author | H. Peter Anvin <hpa@zytor.com> | 2012-05-29 19:33:20 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2012-05-29 19:33:20 -0700 |
commit | 7699e996c613e51049e0bad6ade32215ac263289 (patch) | |
tree | dd30bd90519c6eb731440580898fbbd8910c98b9 /core | |
parent | 4645f42100d2d11fa0281dbdc5431882e4cac69b (diff) | |
download | syslinux-4.10-pre21.tar.gz syslinux-4.10-pre21.tar.xz syslinux-4.10-pre21.zip |
pxe: always start the idle thread, in case we need itsyslinux-4.10-pre21
Always start the idle thread, but leave it blocked unless we have an
indication that interrupts are not working.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/fs/pxe/isr.c | 36 | ||||
-rw-r--r-- | core/pxeisr.inc | 7 | ||||
-rw-r--r-- | core/thread/idle_thread.c | 7 |
3 files changed, 39 insertions, 11 deletions
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c index e2bf2f67..69cfe9f1 100644 --- a/core/fs/pxe/isr.c +++ b/core/fs/pxe/isr.c @@ -13,8 +13,9 @@ #include <sys/io.h> extern uint8_t pxe_irq_pending; -extern volatile uint8_t pxe_irq_timeout; +extern volatile uint8_t pxe_need_poll; static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0); +static DECLARE_INIT_SEMAPHORE(pxe_poll_thread_sem, 0); static struct thread *pxe_thread, *poll_thread; /* @@ -26,6 +27,7 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old) unsigned int vec; uint8_t mask, mymask; uint32_t now; + bool ok; if (irq < 8) vec = irq + 0x08; @@ -36,6 +38,11 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old) cli(); + if (pxe_need_poll) { + sti(); + return false; + } + entry = (far_ptr_t *)(vec << 2); *old = *entry; entry->ptr = (uint32_t)isr; @@ -60,16 +67,16 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old) now = jiffies(); /* Some time to watch for stuck interrupts */ - while (jiffies() - now < 4 && !pxe_irq_timeout) + while (jiffies() - now < 4 && (ok = !pxe_need_poll)) hlt(); - if (pxe_irq_timeout) + if (!ok) *entry = *old; /* Restore the old vector */ printf("UNDI: IRQ %d(0x%02x): %04x:%04x -> %04x:%04x\n", irq, vec, old->seg, old->offs, entry->seg, entry->offs); - return !pxe_irq_timeout; + return ok; } static bool uninstall_irq_vector(uint8_t irq, void (*isr), far_ptr_t *old) @@ -108,6 +115,12 @@ static void pxe_poll_wakeups(void) static jiffies_t last_jiffies = 0; jiffies_t now = jiffies(); + if (pxe_need_poll == 1) { + /* If we need polling now, activate polling */ + pxe_need_poll = 3; + sem_up(&pxe_poll_thread_sem); + } + if (now != last_jiffies) { last_jiffies = now; __thread_process_timeouts(); @@ -183,11 +196,15 @@ static void pxe_poll_thread(void *dummy) { (void)dummy; + /* Block indefinitely unless activated */ + sem_down(&pxe_poll_thread_sem, 0); + for (;;) { cli(); if (pxe_receive_thread_sem.count < 0 && pxe_isr_poll()) sem_up(&pxe_receive_thread_sem); - __schedule(); + else + __schedule(); sti(); cpu_relax(); } @@ -206,9 +223,10 @@ void pxe_init_isr(void) * avoid packet loss we need to move it into memory that we ourselves * manage, as soon as possible. */ + core_pm_hook = __schedule; + pxe_thread = start_thread("pxe receive", 16384, -20, pxe_receive_thread, NULL); - core_pm_hook = __schedule; } /* @@ -230,9 +248,11 @@ void pxe_start_isr(void) irq = 0; /* Install failed or stuck interrupt */ } + poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY, + pxe_poll_thread, NULL); + 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); + pxe_need_poll |= 1; } int reset_pxe(void) diff --git a/core/pxeisr.inc b/core/pxeisr.inc index 6f9844e0..5bcb9244 100644 --- a/core/pxeisr.inc +++ b/core/pxeisr.inc @@ -95,7 +95,7 @@ pxe_irq_chain equ $-4 in al,dx or al,ch out dx,al - mov byte [pxe_irq_timeout],1 + or byte [pxe_need_poll],1 jmp .exit @@ -162,7 +162,8 @@ pxeirq_count resw 1 pxe_irq_vector resb 1 ; PXE IRQ vector global pxe_irq_pending pxe_irq_pending resb 1 ; IRQ pending flag - global pxe_irq_timeout -pxe_irq_timeout resb 1 ; Stuck IRQs, disabled timeout + global pxe_need_poll +pxe_need_poll resb 1 ; Bit 0 = need polling + ; Bit 1 = polling active section .text16 diff --git a/core/thread/idle_thread.c b/core/thread/idle_thread.c index 4555333a..8faa0719 100644 --- a/core/thread/idle_thread.c +++ b/core/thread/idle_thread.c @@ -2,12 +2,19 @@ #include <limits.h> #include <sys/cpu.h> +static void default_idle_thread_hook(void) +{ +} + +void (*idle_thread_hook)(void) = default_idle_thread_hook; + static void idle_thread_func(void *dummy) { (void)dummy; for (;;) { cli(); + idle_thread_hook(); __schedule(); asm volatile("sti ; hlt" : : : "memory"); } |