240 lines
6.2 KiB
Diff
240 lines
6.2 KiB
Diff
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);
|
|
|
|
--
|