From 890134dc8238cdd92507e831eed2418f7e720293 Mon Sep 17 00:00:00 2001
From: Stefan Lankes <slankes@eonerc.rwth-aachen.de>
Date: Sun, 5 Mar 2017 18:48:51 +0100
Subject: [PATCH] simplify uart device

- HermitCore uses on uart to send log messages to qemu
- unidirectional communication => remove interrupt handler
- remove mmio support for uart
---
 arch/x86/include/asm/uart.h |   6 --
 arch/x86/kernel/uart.c      | 150 ++----------------------------------
 kernel/main.c               |   1 -
 libkern/stdio.c             |   2 +-
 4 files changed, 8 insertions(+), 151 deletions(-)

diff --git a/arch/x86/include/asm/uart.h b/arch/x86/include/asm/uart.h
index 3514c30a2..f849fabeb 100644
--- a/arch/x86/include/asm/uart.h
+++ b/arch/x86/include/asm/uart.h
@@ -40,12 +40,6 @@ extern "C" {
  */
 int uart_init(void);
 
-/** @brief Initialize UART output without a device check
- *
- * @return Returns 0 on success
- */
-int uart_early_init(char*);
-
 /** @brief Simple string output on a serial device.
  *
  * If you want a new line you will have to "\\n".
diff --git a/arch/x86/kernel/uart.c b/arch/x86/kernel/uart.c
index 9dc9c1698..7a8a94044 100644
--- a/arch/x86/kernel/uart.c
+++ b/arch/x86/kernel/uart.c
@@ -97,40 +97,28 @@
 #define UART_MCR_RTS		0x02 /* RTS complement */
 #define UART_MCR_DTR		0x01 /* DTR complement */
 
-static uint8_t	mmio = 0;
 static size_t	iobase = 0;
 
 static inline unsigned char read_from_uart(uint32_t off)
 {
 	uint8_t c = 0;
 
-	if (mmio)
-		c = *((const volatile unsigned char*) (iobase + off));
-	else if (iobase)
+	if (iobase)
 		c = inportb(iobase + off);
 
 	return c;
 }
 
-static void write_to_uart(uint32_t off, unsigned char c)
+static inline void write_to_uart(uint32_t off, unsigned char c)
 {
-	if (mmio)
-		*((volatile unsigned char*) (iobase + off)) = c;
-	else if (iobase)
+	if (iobase)
 		outportb(iobase + off, c);
 }
 
-
-/* Get a single character on a serial device */
-static unsigned char uart_getchar(void)
-{
-	return read_from_uart(UART_RX);
-}
-
 /* Puts a single character on a serial device */
 int uart_putchar(unsigned char c)
 {
-	if (!iobase && !mmio)
+	if (!iobase)
 		return 0;
 
 	write_to_uart(UART_TX, c);
@@ -143,7 +131,7 @@ int uart_puts(const char *text)
 {
 	size_t i, len = strlen(text);
 
-	if (!iobase && !mmio)
+	if (!iobase)
 		return 0;
 
 	for (i = 0; i < len; i++)
@@ -152,39 +140,6 @@ int uart_puts(const char *text)
 	return len;
 }
 
-/* Handles all UART's interrupt */
-static void uart_handler(struct state *s)
-{
-	unsigned char c = read_from_uart(UART_IIR);
-
-	while (!(c & UART_IIR_NO_INT)) {
-		if (c & UART_IIR_RDI) {
-			c = uart_getchar();
-
-			//TODO: handle input messages
-
-			goto out;
-		}
-
-		if(c & UART_IIR_THRI) {
-			// acknowledge interrupt
-			c = read_from_uart(UART_IIR);
-
-			goto out;
-		}
-
-		if(c & UART_IIR_RLSI) {
-			// acknowledge interrupt
-			c = read_from_uart(UART_LSR);
-
-			goto out;
-		}
-
-out:
-		c = read_from_uart(UART_IIR);
-	}
-}
-
 static int uart_config(void)
 {
 	/*
@@ -226,105 +181,14 @@ static int uart_config(void)
 
 extern const void kernel_start;
 
-int uart_early_init(char* cmdline)
-{
-	if (is_uhyve())
-		return 0;
-#if 1
-	// default value of our QEMU configuration
-	iobase = 0xc110;
-#else
-	if (BUILTIN_EXPECT(!cmdline, 0))
-		return -EINVAL;
-
-	char* str = strstr(cmdline, "uart=");
-	if (!str)
-		return -EINVAL;
-
-	if (strncmp(str, "uart=io:", 8) == 0) {
-		iobase = strtol(str+8, (char **)NULL, 16);
-		if (!iobase)
-			return -EINVAL;
-		mmio = 0;
-	} else if (strncmp(str, "uart=mmio:", 10) == 0) {
-		iobase = strtol(str+10, (char **)NULL, 16);
-		if (!iobase)
-			return -EINVAL;
-		if (iobase >= PAGE_MAP_ENTRIES*PAGE_SIZE) {
-			/* at this point we use the boot page table
-			 * => IO address is not mapped
-			 * => dirty hack, map device before the kernel
-			 */
-			int err;
-			size_t newaddr = ((size_t) &kernel_start - PAGE_SIZE);
-
-			err = page_map_bootmap(newaddr & PAGE_MASK, iobase & PAGE_MASK, PG_GLOBAL | PG_ACCESSED | PG_DIRTY | PG_RW | PG_PCD);
-			if (BUILTIN_EXPECT(err, 0)) {
-				iobase = 0;
-				return err;
-			}
-			iobase = newaddr;
-		}
-		mmio = 1;
-	}
-#endif
-
-	// configure uart
-	return uart_config();
-}
-
 int uart_init(void)
 {
 	if (is_uhyve())
 		return 0;
 
-#ifdef CONFIG_PCI
-	pci_info_t pci_info;
-	uint32_t bar = 0;
-
-	// Searching for Intel's UART device
-	if (pci_get_device_info(0x8086, 0x0936, iobase, &pci_info) == 0)
-		goto Lsuccess;
- 	// Searching for Qemu's UART device
-	if (pci_get_device_info(0x1b36, 0x0002, iobase, &pci_info) == 0)
-		goto Lsuccess;
-	// Searching for Qemu's 2x UART device (pci-serial-2x)
-	if (pci_get_device_info(0x1b36, 0x0003, iobase, &pci_info) == 0)
-		goto Lsuccess;
-	// Searching for Qemu's 4x UART device (pci-serial-4x)
-	if (pci_get_device_info(0x1b36, 0x0004, iobase, &pci_info) == 0)
-		goto Lsuccess;
-
-	return -1;
-
-Lsuccess:
-	iobase = pci_info.base[bar];
-	irq_install_handler(32+pci_info.irq, uart_handler);
-	if (pci_info.type[0]) {
-		mmio = 0;
-		LOG_INFO("UART uses io address 0x%x\n", iobase);
-	} else {
-		mmio = 1;
-		page_map(iobase & PAGE_MASK, iobase & PAGE_MASK, 1, PG_GLOBAL | PG_ACCESSED | PG_DIRTY | PG_RW | PG_PCD);
-		LOG_INFO("UART uses mmio address 0x%x\n", iobase);
-		vma_add(iobase, iobase + PAGE_SIZE, VMA_READ|VMA_WRITE);
-	}
+	// default value of our QEMU configuration
+	iobase = 0xc110;
 
 	// configure uart
 	return uart_config();
-#else
-	// per default we use COM1...
-	if (!iobase)
-		iobase = 0x3F8;
-	mmio = 0;
-	if ((iobase == 0x3F8) || (iobase == 0x3E8))
-		irq_install_handler(32+4, uart_handler);
-	else if ((iobase == 0x2F8) || (iobase == 0x2E8))
-		irq_install_handler(32+3, uart_handler);
-	else
-		return -EINVAL;
-
-	// configure uart
-	return uart_config();
-#endif
 }
diff --git a/kernel/main.c b/kernel/main.c
index 2eda4d3a8..bbd6d00d9 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -132,7 +132,6 @@ static int hermit_init(void)
 	multitasking_init();
 	memory_init();
 	signal_init();
-	uart_init();
 
 	return 0;
 }
diff --git a/libkern/stdio.c b/libkern/stdio.c
index ed53c1885..0b1976589 100644
--- a/libkern/stdio.c
+++ b/libkern/stdio.c
@@ -45,7 +45,7 @@ spinlock_irqsave_t stdio_lock = SPINLOCK_IRQSAVE_INIT;
 int koutput_init(void)
 {
 	if (is_single_kernel())
-		uart_early_init(NULL);
+		uart_init();
 
 	return 0;
 }