diff --git a/exosphere/uart.c b/exosphere/uart.c new file mode 100644 index 000000000..86b10d6e4 --- /dev/null +++ b/exosphere/uart.c @@ -0,0 +1,46 @@ +#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; +} + +void uart_transmit_str(const char *str) { + while (*str) { + uart_transmit_char(*str++); + } +} + +void uart_transmit_hex(uint32_t value) { + for (unsigned int i = 0; i < 8; i++) { + uint32_t nibble = (value >> (28 - i * 4)) & 0xF; + uart_transmit_char("0123456789ABCDEF"[nibble]); + } +} \ No newline at end of file diff --git a/exosphere/uart.h b/exosphere/uart.h new file mode 100644 index 000000000..3da1219bf --- /dev/null +++ b/exosphere/uart.h @@ -0,0 +1,22 @@ +#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); +void uart_transmit_str(const char *str); +void uart_transmit_hex(uint32_t value); + +#endif \ No newline at end of file