Index: kernel/genarch/src/drivers/amdm37x_uart/amdm37x_uart.c
===================================================================
--- kernel/genarch/src/drivers/amdm37x_uart/amdm37x_uart.c	(revision b0e58c7a89fef9fcc3325787870c9927f15524d9)
+++ kernel/genarch/src/drivers/amdm37x_uart/amdm37x_uart.c	(revision fcc622441d5706c3fcd58ee0e93a8291d7a9abd7)
@@ -35,13 +35,88 @@
 
 #include <genarch/drivers/amdm37x_uart/amdm37x_uart.h>
+#include <str.h>
+#include <mm/km.h>
 
-int amdm37x_uart_init(
+static void amdm37x_uart_txb(amdm37x_uart_t *uart, uint8_t b)
+{
+	/* Wait for buffer */
+	while (uart->regs->ssr & AMDM37x_UART_SSR_TX_FIFO_FULL_FLAG);
+	/* Write to the outgoing fifo */
+	uart->regs->thr = b;
+}
+
+static void amdm37x_uart_putchar(outdev_t *dev, wchar_t ch)
+{
+	amdm37x_uart_t *uart = dev->data;
+	if (!ascii_check(ch)) {
+		amdm37x_uart_txb(uart, U_SPECIAL);
+	} else {
+		if (ch == '\n')
+			amdm37x_uart_txb(uart, '\r');
+		amdm37x_uart_txb(uart, ch);
+	}
+}
+
+static outdev_operations_t amdm37x_uart_ops = {
+	.redraw = NULL,
+	.write = amdm37x_uart_putchar,
+};
+
+bool amdm37x_uart_init(
     amdm37x_uart_t *uart, inr_t interrupt, uintptr_t addr, size_t size)
 {
-	return 0;
+	ASSERT(uart);
+	uart->regs = (void *)km_map(addr, size, PAGE_NOT_CACHEABLE);
+
+	/* See TI OMAP35X TRM ch 17.5.1.1 p. 2732 for startup routine */
+
+	/* Soft reset the port */
+	uart->regs->sysc = AMDM37x_UART_SYSC_SOFTRESET_FLAG;
+	while (uart->regs->syss & AMDM37x_UART_SYSS_RESETDONE_FLAG) ;
+
+	/* Enable access to EFR register */
+	const uint8_t lcr = uart->regs->lcr; /* Save old value */
+	uart->regs->lcr = 0xbf;              /* Sets config mode B */
+
+	/* Enable access to TCL_TLR register */
+	const bool enhanced = uart->regs->efr & AMDM37x_UART_EFR_ENH_FLAG;
+	uart->regs->efr |= AMDM37x_UART_EFR_ENH_FLAG; /* Turn on enh. */
+	uart->regs->lcr = 0x80;              /* Config mode A */
+
+	/* Set default (val 0) triggers, disable DMA enable FIFOs */
+	const bool tcl_tlr = uart->regs->mcr & AMDM37x_UART_MCR_TCR_TLR_FLAG;
+	uart->regs->fcr = AMDM37x_UART_FCR_FIFO_EN_FLAG;
+
+	/* Enable fine granularity for rx trigger */
+	uart->regs->lcr = 0xbf;              /* Sets config mode B */
+	uart->regs->scr = AMDM37x_UART_SCR_RX_TRIG_GRANU1_FLAG;
+
+	/* Restore enhanced */
+	if (!enhanced)
+		uart->regs->efr &= ~AMDM37x_UART_EFR_ENH_FLAG;
+
+	uart->regs->lcr = 0x80;              /* Config mode A */
+	/* Restore tcl_lcr */
+	if (!tcl_tlr)
+		uart->regs->mcr &= ~AMDM37x_UART_MCR_TCR_TLR_FLAG;
+
+	/* Restore tcl_lcr */
+	uart->regs->lcr = lcr;
+
+	/* Disable interrupts */
+	uart->regs->ier = 0;
+
+	/* Setup outdev */
+	outdev_initialize("amdm37x_uart_dev", &uart->outdev, &amdm37x_uart_ops);
+	uart->outdev.data = uart;
+	return false;
 }
 
 void amdm37x_uart_input_wire(amdm37x_uart_t *uart, indev_t *indev)
 {
+	// TODO implement
+	// register interrupt
+	// set rx fifo
+	// set rx fifo threshold to 1
 }
 
