diff options
author | Wesley W. Terpstra <wesley@sifive.com> | 2017-03-27 12:13:53 -0700 |
---|---|---|
committer | Wesley W. Terpstra <wesley@sifive.com> | 2017-03-27 15:50:22 -0700 |
commit | 9fa7b30887301f149f2497469a442d0887b21149 (patch) | |
tree | 33b67126a0fb86de8603aa8cae2496f2342f45d0 /machine/uart.c | |
parent | 3473915b3a3fd925a68fc3260c64824cab2846d2 (diff) | |
download | riscv-pk-9fa7b30887301f149f2497469a442d0887b21149.zip riscv-pk-9fa7b30887301f149f2497469a442d0887b21149.tar.gz riscv-pk-9fa7b30887301f149f2497469a442d0887b21149.tar.bz2 |
uart: add physical device driver
Diffstat (limited to 'machine/uart.c')
-rw-r--r-- | machine/uart.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/machine/uart.c b/machine/uart.c new file mode 100644 index 0000000..28cc21c --- /dev/null +++ b/machine/uart.c @@ -0,0 +1,38 @@ +#include "uart.h" +#include "fdt.h" + +volatile uint32_t* uart; + +void uart_putchar(uint8_t ch) +{ +#ifdef __riscv_atomic + int32_t r; + do { + __asm__ __volatile__ ( + "amoor.w %0, %2, %1\n" + : "=r" (r), "+A" (uart[UART_REG_TXFIFO]) + : "r" (ch)); + } while (r < 0); +#else + volatile uint32_t *tx = uart + UART_REG_TXFIFO; + while ((int32_t)(*tx) < 0); + *tx = ch; +#endif +} + +int uart_getchar() +{ + int32_t ch = uart[UART_REG_RXFIFO]; + if (ch < 0) return -1; + return ch; +} + +void query_uart(uintptr_t dtb) +{ + uart = 0; // (void*)fdt_get_reg(dtb, "sifive,uart0"); + if (!uart) return; + + // Enable Rx/Tx channels + uart[UART_REG_TXCTRL] = UART_TXEN; + uart[UART_REG_RXCTRL] = UART_RXEN; +} |