Commit Diff


commit - 11244300a5210268239c9b0962a5886da0a15d0a
commit + 881c6377d4b550f742935f30340d6a2fc92426f0
blob - 345b414e121360deb8d2863df854cf784d8336f7
blob + d2f8c1fdb899a833e10af3bccfc4d275b6f63e82
--- changelog.md
+++ changelog.md
@@ -11,6 +11,7 @@
 - Fixed x86_64 timer and IPI interrupt returns overwriting the restored `%rax` register before `iretq`, which caused intermittent user-mode faults during service startup.
 - Made scheduler block, wake, and timed-sleep transitions atomic with interrupt state, preventing lost wakeups and invalid task-state transitions.
 - Updated blockd to poll one representative portal because portals owned by one task share the same mailbox, preventing duplicate readiness handling.
+- Fixed shell input executing one command late by removing the raw serial stdin fallback and duplicate architecture receive rings. Interactive input now reaches tasks only through the console line discipline and PTY mailbox.
 - Verified the Clang 21.1.8 Mercuron build, six x86_64 UEFI boots to the shell, and one legacy boot to the shell. The SMP test build completes, but the existing AP trampoline startup still blocks SMP boot before userland.
 
 # 2025-12-09
blob - 86a959ebb7aef8409e867a903c6982f9f5e63562
blob + d62639eb01a80c90d20f0aae4b00aa755c0aa206
--- kernel/arch/arm64/serial.c
+++ kernel/arch/arm64/serial.c
@@ -6,11 +6,6 @@
 #include "log/printk.h"
 #include "console/line.h"
 
-#define SERIAL_RX_BUFSZ 256
-static volatile char serial_rx_buf[SERIAL_RX_BUFSZ];
-static volatile unsigned int serial_rx_head;
-static volatile unsigned int serial_rx_tail;
-
 #define PL011_BASE      0x09000000UL
 #define PL011_DR        0x000
 #define PL011_FR        0x018
@@ -39,15 +34,10 @@ uart_read(uintptr_t reg)
 }
 
 static void
-serial_buffer_push(char c)
+serial_receive_char(char c)
 {
-	unsigned int next = (serial_rx_head + 1U) % SERIAL_RX_BUFSZ;
 	static int serial_rx_debug;
 
-	if (next == serial_rx_tail)
-		return;
-	serial_rx_buf[serial_rx_head] = c;
-	serial_rx_head = next;
 	if (serial_rx_debug < 8) {
 		const char hex[] = "0123456789abcdef";
 		char buf[3];
@@ -117,21 +107,11 @@ serial_write(const char *s, size_t n)
 		serial_putc(s[i]);
 }
 
-int
-serial_getc_nonblock(char *c)
-{
-	if (serial_rx_head == serial_rx_tail)
-		return 0;
-	*c = serial_rx_buf[serial_rx_tail];
-	serial_rx_tail = (serial_rx_tail + 1U) % SERIAL_RX_BUFSZ;
-	return 1;
-}
-
 void
 serial_irq(void)
 {
 	while ((uart_read(PL011_FR) & PL011_FR_RXFE) == 0) {
-		serial_buffer_push((char)uart_read(PL011_DR));
+		serial_receive_char((char)uart_read(PL011_DR));
 	}
 	uart_write(PL011_ICR, PL011_IMSC_RXIM);
 }
@@ -140,6 +120,6 @@ void
 serial_poll_rx(void)
 {
 	while ((uart_read(PL011_FR) & PL011_FR_RXFE) == 0) {
-		serial_buffer_push((char)uart_read(PL011_DR));
+		serial_receive_char((char)uart_read(PL011_DR));
 	}
 }
blob - 1ca53ff2e1283aaa0ad036ef2170da5afda5b6a5
blob + 2dbbeecb2b6794f1744db62b0631b3d4f748493e
--- kernel/arch/x86_64/serial.c
+++ kernel/arch/x86_64/serial.c
@@ -26,11 +26,6 @@ extern void x86_serial_isr(void);
 #define SERIAL_WITH_IRQ	1
 #define COM1_IRQ	4
 #define COM1_VECTOR	(32 + COM1_IRQ)
-#define SERIAL_RX_BUFSZ 256
-
-static volatile char serial_rx_buf[SERIAL_RX_BUFSZ];
-static volatile unsigned int serial_rx_head;
-static volatile unsigned int serial_rx_tail;
 #endif
 
 #define COM1 0x3F8
@@ -59,18 +54,12 @@ serial_outb(unsigned short port, unsigned char value)
 
 #if SERIAL_WITH_IRQ
 static void
-serial_buffer_push(char c)
+serial_receive_char(char c)
 {
-	unsigned int next;
 #if SERIAL_DEBUG_RX
 	static int serial_rx_debug;
 #endif
 
-	next = (serial_rx_head + 1U) % SERIAL_RX_BUFSZ;
-	if (next == serial_rx_tail)
-		return;
-	serial_rx_buf[serial_rx_head] = c;
-	serial_rx_head = next;
 #if SERIAL_DEBUG_RX && !defined(UEFI_BUILD)
 	if (serial_rx_debug < 8) {
 		const char hex[] = "0123456789abcdef";
@@ -174,16 +163,7 @@ serial_write(const char *s, size_t n)
 		serial_putc(s[i]);
 }
 
-int
-serial_getc_nonblock(char *c)
 #if SERIAL_WITH_IRQ
-{
-	if (serial_rx_head == serial_rx_tail)
-		return 0;
-	*c = serial_rx_buf[serial_rx_tail];
-	serial_rx_tail = (serial_rx_tail + 1U) % SERIAL_RX_BUFSZ;
-	return 1;
-}
 void
 serial_irq(void)
 {
@@ -235,7 +215,7 @@ serial_irq(void)
 			}
 			printk("\n");
 		}
-		serial_buffer_push(ch);
+		serial_receive_char(ch);
 	}
 }
 
@@ -315,20 +295,10 @@ serial_poll_rx(void)
 			serial_poll_debug++;
 		}
 #endif
-		serial_buffer_push(ch);
+		serial_receive_char(ch);
 	}
 }
 #else
-{
-	if ((serial_inb(COM1 + 5) & 0x01) == 0)
-		return 0;
-	*c = (char)serial_inb(COM1 + 0);
-#ifndef UEFI_BUILD
-	console_line_rx(*c);
-#endif
-	return 1;
-}
-
 void
 serial_irq(void)
 {
blob - a6b3abb5e512e27986266b281e2aeb4940e4cb1d
blob + c88cdd588bda2ad2877381f7c08dcb5f6ee4dac6
--- kernel/log/serial.h
+++ kernel/log/serial.h
@@ -7,6 +7,5 @@ int  serial_ready(void);
 void serial_putc(char c);
 void serial_write(const char *s, size_t n);
 static inline void serial_write_string(const char *s, size_t n) { serial_write(s, n); }
-int  serial_getc_nonblock(char *c);
 void serial_irq(void);
 void serial_poll_rx(void);
blob - 14e2d19d0193143deb01bc709aa969391c47876b
blob + 58abc97dbe1f732713866996c62e648b8b9f265e
--- kernel/sys/syscall.c
+++ kernel/sys/syscall.c
@@ -1385,24 +1385,6 @@ sys_read_impl(uint64_t fd, uint64_t buf_addr, uint64_t
 			return syscall_make_result(copied, 0);
 		}
 
-		/* Fallback: try to pull characters directly from serial if mailbox is empty.
-		 * NOTE: serial_getc_nonblock() only READS characters without processing.
-		 * serial_poll_rx() handles line discipline processing. */
-		/* DISABLED: Only console task should poll serial */
-		/* serial_poll_rx(); */
-		#if 1  /* Re-enable: getc no longer processes, just reads */
-		{
-			char tmpc;
-			while (copied < n && serial_getc_nonblock(&tmpc)) {
-				if (syscall_copy_to_user(buf_addr + copied, &tmpc, 1) != 0)
-					return syscall_make_result(-SYSCALL_EFAULT, 0);
-				copied++;
-			}
-			if (copied > 0)
-				return syscall_make_result(copied, 0);
-		}
-		#endif
-
 		if (mbox == NULL)
 			return syscall_make_result(-SYSCALL_EBADF, 0);
 		deadlock_recv_start(task, 5000);