Memtest86+: Support for configuring console from LB_SERIAL entry

I don't like how payload consoles are configured via Kconfig. This
leads to Kconfig needing to know things that would otherwise be the
responsibility of the code. We've had LB_SERIAL available for a very
long time, which does exactly this, but without Kconfig.

I complained to Martin, and he challenged me to fix this for Memtest86
Challenge accepted!

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Change-Id: Ifa920b8297c7edca53372482107a071b28296340
Reviewed-on: https://review.coreboot.org/c/memtest86plus/+/37056
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/coreboot.c b/coreboot.c
index bcc51f8..3c2883f 100644
--- a/coreboot.c
+++ b/coreboot.c
@@ -132,6 +132,7 @@
 
 int query_coreboot(void)
 {
+	const struct lb_serial *serial = 0;
 	struct lb_header *head;
 	struct lb_record *rec;
 	struct lb_memory *mem;
@@ -153,11 +154,21 @@
 
 	mem = 0;
 	for_each_lbrec(head, rec) {
-		if (rec->tag == LB_TAG_MEMORY) {
+		switch (rec->tag) {
+		case LB_TAG_MEMORY:
 			mem = (struct lb_memory *)rec;
 			break;
+		case LB_TAG_SERIAL:
+			serial = (const void *)rec;
+			break;
+		default:
+			break;
 		}
 	}
+
+	if (serial)
+		serial_console_setup_from_lb_serial(serial);
+
 	if (!mem) {
 		return 1;
 	}
diff --git a/coreboot_tables.h b/coreboot_tables.h
index f847d9b..4345947 100644
--- a/coreboot_tables.h
+++ b/coreboot_tables.h
@@ -56,6 +56,7 @@
 #define LB_TAG_UNUSED	0x0000
 
 #define LB_TAG_MEMORY	0x0001
+#define LB_TAG_SERIAL	0x000f
 #define LB_TAG_FORWARD	0x0011
 
 struct lb_memory_range {
@@ -77,6 +78,20 @@
 	struct lb_memory_range map[0];
 };
 
+#define LB_SERIAL_TYPE_IO_MAPPED     1
+#define LB_SERIAL_TYPE_MEMORY_MAPPED 2
+
+struct lb_serial {
+	uint32_t tag;
+	uint32_t size;
+	uint32_t type;
+	uint32_t baseaddr;
+	uint32_t baud;
+	uint32_t regwidth;
+	uint32_t input_hertz;
+	uint32_t uart_pci_addr;
+};
+
 struct lb_forward {
 	uint32_t tag;
 	uint32_t size;
diff --git a/lib.c b/lib.c
index c36e124..ecba1c2 100644
--- a/lib.c
+++ b/lib.c
@@ -11,6 +11,7 @@
 #include "stdint.h"
 #include "cpuid.h"
 #include "smp.h"
+#include "coreboot_tables.h"
 
 
 int slock = 0, lsr = 0;
@@ -1062,6 +1063,31 @@
 	}
 }
 
+void serial_console_setup_from_lb_serial(const struct lb_serial *serial)
+{
+	if (serial->type != LB_SERIAL_TYPE_IO_MAPPED)
+		return;
+
+	if (serial->regwidth != 1)
+		return;
+
+	switch (serial->baseaddr) {
+		case 0x3f8:
+			serial_tty = 0;
+			break;
+		case 0x2f8:
+			serial_tty = 1;
+			break;
+		default:
+			return;
+	}
+
+	serial_baud_rate = serial->baud;
+	serial_bits = 8;
+	serial_parity = 0;
+	serial_cons = 1;
+}
+
 /*
  * Handles "console=<param>" command line option
  *
diff --git a/test.h b/test.h
index f7b9ec0..e53ad08 100644
--- a/test.h
+++ b/test.h
@@ -104,6 +104,8 @@
 #define SZ_MODE_BIOS		1
 #define SZ_MODE_PROBE		2
 
+struct lb_serial;
+
 #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
 
 int memcmp(const void *s1, const void *s2, ulong count);
@@ -120,6 +122,7 @@
 void itoa(char s[], int n);
 void reverse(char *p);
 void serial_console_setup(char *param);
+void serial_console_setup_from_lb_serial(const struct lb_serial *serial);
 void serial_echo_init(void);
 void serial_echo_print(const char *s);
 void ttyprint(int y, int x, const char *s);