Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Sep 2009 00:24:22 GMT
From:      Brad Huntting <huntting@glarp.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/138925: serial console option for memtest86+ 
Message-ID:  <200909180024.n8I0OMAO046002@www.freebsd.org>
Resent-Message-ID: <200909180030.n8I0U4Be059558@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         138925
>Category:       ports
>Synopsis:       serial console option for memtest86+
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 18 00:30:04 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Brad Huntting
>Release:        7.2-PRERELEASE
>Organization:
>Environment:
FreeBSD spork.glarp.com 7.2-PRERELEASE FreeBSD 7.2-PRERELEASE #0: Tue May  5 13:40:59 MDT 2009     root@:/.../src/sys/amd64/compile/SPORK  amd64

>Description:
memtest86+ already has most of the code to support a serial port console, but there's a small problem:  It still polls the keyboard controler.

If your system doesnt have a keyboard controler, this can be a problem.  Not only will memtest86+ be unable to reboot the system, it seems to have some sort of 'phantom key syndrome' which prevents it from ever polling the serial port at all.

The attached patch provides two port options:
   SERIAL - tells memtest86+ to default to serial port console (you can use command line defines to say which serial port and what baud rate)
   NOKBD  - removes support for the keyboard controller (io ports 0x60 and 0x64 all together).

It also patches the UART initialization proceedure and uses the Reset Control Register (in addition to the keyboard controller) to reboot the system.

>How-To-Repeat:
Find a headless amd64 system with an ICH9 chipset (other ICHes will probably also work) and _no SuperIO_ chip, keyboard controller, or USB keyboard (i.e. serial port console).  (I'm using a Radisys COMExpress module).

Try to boot memtest86+ from the loader.   At best it will ignore serial port input.
>Fix:
The attached patch serves to:

    Initialize the UART correctly.
    Dont query the non-existant keyboard controller.
    Use something other than the keyboard controller to reboot.



Patch attached with submission follows:

diff -Nru /usr/ports/sysutils/memtest86+/Makefile memtest86+/Makefile
--- /usr/ports/sysutils/memtest86+/Makefile	2009-03-31 16:23:18.000000000 -0600
+++ memtest86+/Makefile	2009-09-17 18:00:23.000000000 -0600
@@ -24,7 +24,13 @@
 BOOT_DIR?=	/boot/opt
 
 OPTIONS=	ISO	"Build bootable ISO image"			off \
-		BOOT	"Build ELF image loadable by boot2 and loader"	on
+		BOOT	"Build ELF image loadable by boot2 and loader"	on \
+		SERIAL	"Default to serial console"	off \
+		NOKBD	"Missing keyboard controler"	off
+
+# Default serial port (0=sio0, 1=sio1)
+SERIAL_TTY?=	0
+SERIAL_BAUD_RATE?= 9600
 
 .include <bsd.port.pre.mk>
 
@@ -42,6 +48,10 @@
 ALL_TARGET+=	iso
 .endif
 
+.if defined(WITH_NOKBD)
+EXTRA_PATCHES+=	${FILESDIR}/extrapatch-config.h
+.endif
+
 pre-fetch:
 .if !defined(PACKAGE_BUILDING)
 	@${ECHO} "If you only need bootable ISO image of memtest86+, you can"
@@ -49,6 +59,14 @@
 	@${ECHO} "port if you need ELF image of memtest86+ that can be loaded"
 	@${ECHO} "by boot2 or loader(8), or if you want to use this port to"
 	@${ECHO} "build ISO image with custom tweaks in memtest86+ code."
+
+do-configure:
+.if defined(WITH_SERIAL)
+	${REINPLACE_CMD} -e \
+		's|#define SERIAL_TTY .*|#define SERIAL_TTY ${SERIAL_TTY}|; \
+		 s|#define SERIAL_BAUD_RATE .*|#define SERIAL_BAUD_RATE ${SERIAL_BAUD_RATE}|; \
+		 s|#define SERIAL_CONSOLE_DEFAULT .*|#define SERIAL_CONSOLE_DEFAULT 1|; \
+	' ${WRKSRC}/config.h
 .endif
 
 PLIST=		${WRKDIR}/pkg-plist
diff -Nru /usr/ports/sysutils/memtest86+/files/extrapatch-config.h memtest86+/files/extrapatch-config.h
--- /usr/ports/sysutils/memtest86+/files/extrapatch-config.h	1969-12-31 17:00:00.000000000 -0700
+++ memtest86+/files/extrapatch-config.h	2009-09-17 17:22:52.000000000 -0600
@@ -0,0 +1,7 @@
+--- config.h.orig	2008-11-15 17:18:14.000000000 -0700
++++ config.h	2009-09-17 17:22:30.000000000 -0600
+@@ -40,3 +40,4 @@
+ /*	Normally enabled */
+ #define USB_WAR
+ 
++#define	NO_KEYBOARD_CONTROLER
diff -Nru /usr/ports/sysutils/memtest86+/files/patch-lib.c memtest86+/files/patch-lib.c
--- /usr/ports/sysutils/memtest86+/files/patch-lib.c	1969-12-31 17:00:00.000000000 -0700
+++ memtest86+/files/patch-lib.c	2009-09-17 16:37:44.000000000 -0600
@@ -0,0 +1,79 @@
+--- lib.c.orig	2008-11-15 17:18:14.000000000 -0700
++++ lib.c	2009-09-17 15:45:53.000000000 -0600
+@@ -538,8 +538,10 @@
+ int get_key() {
+ 	int c;
+ 
++#ifndef NO_KEYBOARD_CONTROLER
+ 	c = inb(0x64);
+ 	if ((c & 1) == 0) {
++#endif /* !NO_KEYBOARD_CONTROLER */
+ 		if (serial_cons) {
+ 			int comstat;
+ 			comstat = serial_echo_inb(UART_LSR);
+@@ -553,9 +555,11 @@
+ 			}
+ 		}
+ 		return(0);
++#ifndef NO_KEYBOARD_CONTROLER
+ 	}
+ 	c = inb(0x60);
+ 	return((c));
++#endif /* !NO_KEYBOARD_CONTROLER */
+ }
+ 
+ void check_input(void)
+@@ -570,7 +574,13 @@
+ 
+ 			/* tell the BIOS to do a warm start */
+ 			*((unsigned short *)0x472) = 0x1234;
++#ifndef NO_KEYBOARD_CONTROLER
++			/* Try Keyboard Controler */
+ 			outb(0xfe,0x64);
++#endif
++			/* Try Reset Control Register */
++			outb(0x02, 0xcf9);
++			outb(0x06, 0xcf9);
+ 			break;
+ 		case 46:
+ 			/* c - Configure */
+@@ -762,12 +772,33 @@
+ 	serial_echo_outb((serial_div >> 8) & 0xff, UART_DLM);
+ 	serial_echo_outb(lcr, UART_LCR); /* Done with divisor */
+ 
+-
+-	/* Prior to disabling interrupts, read the LSR and RBR
+-	 * registers */
+-	comstat = serial_echo_inb(UART_LSR); /* COM? LSR */
+-	comstat = serial_echo_inb(UART_RX);	/* COM? RBR */
+-	serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */
++	/* Disable interrupts */
++	comstat = serial_echo_inb(UART_IER);
++	comstat &= 0xf0;
++	serial_echo_outb(comstat, UART_IER);
++
++	/* disable fifo */
++	serial_echo_outb(0, UART_FCR);
++
++	/* Clear pending interrupts */
++	while (((comstat = serial_echo_inb(UART_IIR)) & UART_IIR_NO_INT) == 0) {
++		comstat &= 0x0f;
++		switch (comstat) {
++		case UART_IIR_RLSI:
++			lsr = serial_echo_inb(UART_LSR);
++			if (lsr & (UART_LSR_BI|UART_LSR_FE|UART_LSR_PE))
++				(void)serial_echo_inb(UART_RX);
++			break;
++		case UART_IIR_RDI:
++		case UART_IIR_RDI|0x8: /* fifo */
++			(void)serial_echo_inb(UART_RX);
++			break;
++		case UART_IIR_MSI:
++			(void)serial_echo_inb(UART_MSR);
++		default:
++			break;
++		}
++	}
+ 
+ 	clear_screen_buf();
+ 


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909180024.n8I0OMAO046002>