memtest86plus/console-boot-parameter.diff

240 lines
6.2 KiB
Diff
Raw Normal View History

Make the serial console port and its baudrate configurable on the bootloader
(e.g GRUB) command line.
The parameter format is similar to Linux's. Examples:
console=ttyS0 # to enable serial console on the first serial port
console=ttyS1 # second serial port
console=ttyS0,38400 # with the given baudrate
Selectable parity, bits, flow control not implemented yet.
Index: memtest86+-1.70/config.h
===================================================================
--- memtest86+-1.70.orig/config.h
+++ memtest86+-1.70/config.h
@@ -15,6 +15,9 @@
/* to enable. */
#define SERIAL_CONSOLE_DEFAULT 0
+/* SERIAL_TTY - The default serial port to use. 0=ttyS0, 1=ttyS1 */
+#define SERIAL_TTY 0
+
/* SERIAL_BAUD_RATE - Baud rate for the serial console */
#define SERIAL_BAUD_RATE 9600
Index: memtest86+-1.70/lib.c
===================================================================
--- memtest86+-1.70.orig/lib.c
+++ memtest86+-1.70/lib.c
@@ -11,6 +11,18 @@
int slock = 0, lsr = 0;
short serial_cons = SERIAL_CONSOLE_DEFAULT;
+
+#if SERIAL_TTY != 0 && SERIAL_TTY != 1
+#error Bad SERIAL_TTY. Only ttyS0 and ttyS1 are supported.
+#endif
+short serial_tty = SERIAL_TTY;
+const short serial_base_ports[] = {0x3f8, 0x2f8};
+
+#if ((115200%SERIAL_BAUD_RATE) != 0)
+#error Bad default baud rate
+#endif
+int serial_baud_rate = SERIAL_BAUD_RATE;
+
char buf[18];
struct ascii_map_str {
@@ -721,19 +733,9 @@ void ttyprint(int y, int x, const char *
serial_echo_print(p);
}
-#if defined(SERIAL_BAUD_RATE)
-
-#if ((115200%SERIAL_BAUD_RATE) != 0)
-#error Bad ttys0 baud rate
-#endif
-
-#define SERIAL_DIV (115200/SERIAL_BAUD_RATE)
-
-#endif /* SERIAL_BAUD_RATE */
-
void serial_echo_init(void)
{
- int comstat, hi, lo;
+ int comstat, hi, lo, serial_div;
/* read the Divisor Latch */
comstat = serial_echo_inb(UART_LCR);
@@ -744,12 +746,11 @@ void serial_echo_init(void)
/* now do hardwired init */
serial_echo_outb(0x03, UART_LCR); /* No parity, 8 data bits, 1 stop */
-#if defined(SERIAL_BAUD_RATE)
+ serial_div = 115200 / serial_baud_rate;
serial_echo_outb(0x83, UART_LCR); /* Access divisor latch */
- serial_echo_outb(SERIAL_DIV & 0xff, UART_DLL); /* baud rate divisor */
- serial_echo_outb((SERIAL_DIV>> 8) & 0xff, UART_DLM);
+ serial_echo_outb(serial_div & 0xff, UART_DLL); /* baud rate divisor */
+ serial_echo_outb((serial_div >> 8) & 0xff, UART_DLM);
serial_echo_outb(0x03, UART_LCR); /* Done with divisor */
-#endif
/* Prior to disabling interrupts, read the LSR and RBR
* registers */
@@ -974,6 +975,59 @@ void wait_keyup( void ) {
}
}
}
+
+/*
+ * Handles "console=<param>" command line option
+ *
+ * Examples of accepted params:
+ * ttyS0
+ * ttyS1
+ * ttyS0,115200
+ */
+void serial_console_setup(char *param)
+{
+ char *option, *end;
+ unsigned long tty;
+ unsigned long baud_rate;
+
+ if (strncmp(param, "ttyS", 4))
+ return; /* not a serial port */
+
+ param += 4;
+
+ tty = simple_strtoul(param, &option, 10);
+
+ if (option == param)
+ return; /* there were no digits */
+
+ if (tty > 1)
+ return; /* only ttyS0 and ttyS1 supported */
+
+ if (*option == '\0')
+ goto save_tty; /* no options given, just ttyS? */
+
+ if (*option != ',')
+ return; /* missing the comma separator */
+
+ /* baud rate must follow */
+ option++;
+ baud_rate = simple_strtoul(option, &end, 10);
+
+ if (end == option)
+ return; /* no baudrate after comma */
+
+ if (baud_rate == 0 || (115200 % baud_rate) != 0)
+ return; /* wrong baud rate */
+
+ if (*end != '\0')
+ return; /* garbage at the end */
+
+ serial_baud_rate = (int) baud_rate;
+save_tty:
+ serial_tty = (short) tty;
+ serial_cons = 1;
+}
+
#ifdef LP
#define DATA 0x00
#define STATUS 0x01
Index: memtest86+-1.70/main.c
===================================================================
--- memtest86+-1.70.orig/main.c
+++ memtest86+-1.70/main.c
@@ -31,6 +31,7 @@ const struct tseq tseq[] = {
};
char firsttime = 0;
+char cmdline_parsed = 0;
struct vars variables = {};
struct vars * const v = &variables;
@@ -135,12 +136,53 @@ static void run_at(unsigned long addr)
__run_at(run_at_addr);
}
+/* command line passing using the 'old' boot protocol */
+#define MK_PTR(seg,off) ((void*)(((unsigned long)(seg) << 4) + (off)))
+#define OLD_CL_MAGIC_ADDR ((unsigned short*) MK_PTR(INITSEG,0x20))
+#define OLD_CL_MAGIC 0xA33F
+#define OLD_CL_OFFSET_ADDR ((unsigned short*) MK_PTR(INITSEG,0x22))
+
+static void parse_command_line(void)
+{
+ char *cmdline;
+
+ if (cmdline_parsed)
+ return;
+
+ if (*OLD_CL_MAGIC_ADDR != OLD_CL_MAGIC)
+ return;
+
+ unsigned short offset = *OLD_CL_OFFSET_ADDR;
+ cmdline = MK_PTR(INITSEG, offset);
+
+ /* skip leading spaces */
+ while (*cmdline == ' ')
+ cmdline++;
+
+ while (*cmdline) {
+ if (!strncmp(cmdline, "console=", 8)) {
+ cmdline += 8;
+ serial_console_setup(cmdline);
+ }
+
+ /* go to the next parameter */
+ while (*cmdline && *cmdline != ' ')
+ cmdline++;
+ while (*cmdline == ' ')
+ cmdline++;
+ }
+
+ cmdline_parsed = 1;
+}
+
void do_test(void)
{
int i = 0;
unsigned long chunks;
unsigned long lo, hi;
+ parse_command_line();
+
/* If we have a partial relocation finish it */
if (run_at_addr == (unsigned long)&_start) {
run_at_addr = 0xffffffff;
Index: memtest86+-1.70/serial.h
===================================================================
--- memtest86+-1.70.orig/serial.h
+++ memtest86+-1.70/serial.h
@@ -136,8 +136,8 @@
*/
#include "io.h"
-#define serial_echo_outb(v,a) outb((v),(a)+0x3f8)
-#define serial_echo_inb(a) inb((a)+0x3f8)
+#define serial_echo_outb(v,a) outb((v),(a)+serial_base_ports[serial_tty])
+#define serial_echo_inb(a) inb((a)+serial_base_ports[serial_tty])
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
/* Wait for transmitter & holding register to empty */
#define WAIT_FOR_XMITR \
Index: memtest86+-1.70/test.h
===================================================================
--- memtest86+-1.70.orig/test.h
+++ memtest86+-1.70/test.h
@@ -103,6 +103,7 @@ void printpatn(void);
void printpatn(void);
void itoa(char s[], int n);
void reverse(char *p);
+void serial_console_setup(char *param);
void serial_echo_init(void);
void serial_echo_print(const char *s);
void ttyprint(int y, int x, const char *s);
--