diff --git a/exosphere/uart.c b/exosphere/uart.c new file mode 100644 index 000000000..265931789 --- /dev/null +++ b/exosphere/uart.c @@ -0,0 +1,33 @@ +#include "uart.h" + +volatile void *g_uart_registers = NULL; + +void set_uart_address(void *uart_base) { + g_uart_registers = uart_base; +} + +inline void *get_uart_address(void) { + return g_uart_registers; +} + +void uart_initialize(uint16_t divider) { + /* Setup UART in 16450 mode. We assume the relevant UART clock has been enabled. */ + + /* Disable FIFO */ + UART_IIR_FCR_0 = 0x00; + + /* Set DLAB */ + UART_LCR_0 = 0x80; + UART_THR_DLAB_0_0 = (uint8_t)divider; + UART_IER_DLAB_0_0 = (uint8_t)(divider >> 8); + + /* 8N1 mode */ + UART_LCR_0 = 0x03; +} + +void uart_transmit_char(char ch) { + /* Wait for THR to be empty */ + while (!(UART_LSR_0 & 0x20)) {} + + UART_THR_DLAB_0_0 = ch; +} \ No newline at end of file diff --git a/exosphere/uart.h b/exosphere/uart.h new file mode 100644 index 000000000..cb7010774 --- /dev/null +++ b/exosphere/uart.h @@ -0,0 +1,20 @@ +#ifndef EXOSPHERE_UART_H +#define EXOSPHERE_UART_H + +#include + +/* Exosphere driver for the Tegra X1 UARTs. */ + +void set_uart_address(void *uart_base); +void *get_uart_address(void); /* This is inlined in uart.c */ + +#define UART_THR_DLAB_0_0 (*((volatile uint32_t *)(get_uart_address() + 0x0))) +#define UART_IER_DLAB_0_0 (*((volatile uint32_t *)(get_uart_address() + 0x4))) +#define UART_IIR_FCR_0 (*((volatile uint32_t *)(get_uart_address() + 0x8))) +#define UART_LCR_0 (*((volatile uint32_t *)(get_uart_address() + 0xC))) +#define UART_LSR_0 (*((volatile uint32_t *)(get_uart_address() + 0x14))) + +void uart_initialize(uint16_t divider); +void uart_transmit_char(char ch); + +#endif \ No newline at end of file