elks-enhanced

publicRead
Owner: themasterBranch: masterCommits: 6893Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL

Commit diff

Commit 2082e133f48a97d4351ac46324b8032bd82fbb2
commit 2082e133f48a97d4351ac46324b8032bd82fbb25
Author: Greg Haerr <greg@censoft.com>
Date:   Thu Feb 19 18:01:02 2026 -0700

    [kernel] Prevent potential hang on 16550A UART by loop-reading FIFO each interrupt
---
 elks/arch/i86/drivers/char/serfast.S     | 19 ++++++++++++++-----
 elks/arch/i86/drivers/char/serial-8250.c |  4 ++--
 elks/arch/i86/mm/malloc.c                |  3 +++
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/elks/arch/i86/drivers/char/serfast.S b/elks/arch/i86/drivers/char/serfast.S
index 94fefe2f..5600291a 100644
--- a/elks/arch/i86/drivers/char/serfast.S
+++ b/elks/arch/i86/drivers/char/serfast.S
@@ -27,6 +27,7 @@
 //     struct ch_queue *q = &sp->tty->inq;
 //     unsigned char c;
 //
+//   do {
 //     c = INB(sp->io + UART_RX);       // Read received data
 //     if (q->len < q->size) {
 //         q->base[q->head] = c;
@@ -36,6 +37,7 @@
 //     }
 //     if (c == 03)                     // assumes VINTR = ^C and byte queued anyways
 //         sp->intrchar = c;
+//   } while (INB(sp->io + UART_LSR) & UART_LSR_DR);
 // }
 
 //
@@ -62,7 +64,7 @@ common_entry:
         mov     %cx,%bx                 // bx = sp = &ports[n]
         mov     (%bx),%si               // si = q = &sp->tty->inq
         mov     0x4(%bx),%dx            // dx = sp->io + UART_RX
-        in      (%dx),%al
+0:      in      (%dx),%al               // do {
         mov     %al,%dl                 // dl = c = INB(sp->io+UART_RX)
         mov     (%si),%ax               // ax = q->len
         cmp     0x2(%si),%ax            // if (ax >= q->size)
@@ -76,12 +78,19 @@ common_entry:
         cmp     0x2(%si),%ax            // if (q->size < q->head)
         jl      1f
         movw    $0x0,0x4(%si)           // q->head = 0
-1:      incw    (%si)
-2:      cmp     $0x3,%dl                // if (c == 03)
+1:      incw    (%si)                   // q->len++
+2:      mov     %cx,%bx                 // bx = sp
+        cmp     $0x3,%dl                // if (c == 03)
         jne     3f
-        mov     %cx,%bx                 // bx = sp
         movw    $0x3,2(%bx)             // sp->intrchar = c
-3:      pop     %di
+3:      mov     0x4(%bx),%dx            // dx = sp->io
+        add     $5,%dx                  // dx = sp->io + UART_LSR
+        in      (%dx),%al               // al = INB(sp->io + UART_LSR)
+        test    $1,%al                  // while (al & UART_LSR_DR)
+        jz      4f
+        sub     $5,%dx                  // dx = sp->io + UART_RX
+        jmp     0b
+4:      pop     %di
         pop     %si
 
         mov     $0x20,%al               // EOI on primary controller
diff --git a/elks/arch/i86/drivers/char/serial-8250.c b/elks/arch/i86/drivers/char/serial-8250.c
index d8f42ee9..b6d41133 100644
--- a/elks/arch/i86/drivers/char/serial-8250.c
+++ b/elks/arch/i86/drivers/char/serial-8250.c
@@ -103,7 +103,7 @@ static void flush_input(register struct serial_info *sp)
 #endif
 }
 
-static int rs_probe(register struct serial_info *sp)
+static int INITPROC rs_probe(register struct serial_info *sp)
 {
     int status, type;
     unsigned char scratch;
@@ -479,7 +479,7 @@ static int rs_ioctl(struct tty *tty, int cmd, char *arg)
     return retval;
 }
 
-static void rs_init(void)
+static void INITPROC rs_init(void)
 {
     register struct serial_info *sp = ports;
     register struct tty *tty = ttys + NR_CONSOLES;
diff --git a/elks/arch/i86/mm/malloc.c b/elks/arch/i86/mm/malloc.c
index 09c51a7b..f08dd90e 100644
--- a/elks/arch/i86/mm/malloc.c
+++ b/elks/arch/i86/mm/malloc.c
@@ -291,6 +291,9 @@ static int set_brk(segoff_t brk, int increment)
     stacklow = current->t_begstack - current->t_minstack;
     if (newbrk > stacklow) {
         printk("(%P)SBRK %d FAIL, OUT OF HEAP SPACE\n", increment);
+        /*printk("BEGSTK %x MINSTK %x LOWSTK %x NEWBRK %x CURBRK %x\n",
+            current->t_begstack, current->t_minstack, stacklow, newbrk,
+            current->t_endbrk);*/
         return -ENOMEM;
     }
     if (newbrk > current->t_regs.sp) {