7 * Core UART functions to implement for a port
10 static uint64_t potato_uart_base
;
12 #define PROC_FREQ 50000000
13 #define UART_FREQ 115200
14 #define UART_BASE 0xc0002000
16 #define POTATO_CONSOLE_TX 0x00
17 #define POTATO_CONSOLE_RX 0x08
18 #define POTATO_CONSOLE_STATUS 0x10
19 #define POTATO_CONSOLE_STATUS_RX_EMPTY 0x01
20 #define POTATO_CONSOLE_STATUS_TX_EMPTY 0x02
21 #define POTATO_CONSOLE_STATUS_RX_FULL 0x04
22 #define POTATO_CONSOLE_STATUS_TX_FULL 0x08
23 #define POTATO_CONSOLE_CLOCK_DIV 0x18
24 #define POTATO_CONSOLE_IRQ_EN 0x20
26 static uint64_t potato_uart_reg_read(int offset
)
30 __asm__
volatile("ldcix %0,%1,%2" : "=r" (val
) : "b" (potato_uart_base
), "r" (offset
));
35 static void potato_uart_reg_write(int offset
, uint64_t val
)
37 __asm__
volatile("stdcix %0,%1,%2" : : "r" (val
), "b" (potato_uart_base
), "r" (offset
));
40 static int potato_uart_rx_empty(void)
44 val
= potato_uart_reg_read(POTATO_CONSOLE_STATUS
);
46 if (val
& POTATO_CONSOLE_STATUS_RX_EMPTY
)
52 static int potato_uart_tx_full(void)
56 val
= potato_uart_reg_read(POTATO_CONSOLE_STATUS
);
58 if (val
& POTATO_CONSOLE_STATUS_TX_FULL
)
64 static char potato_uart_read(void)
68 val
= potato_uart_reg_read(POTATO_CONSOLE_RX
);
70 return (char)(val
& 0x000000ff);
73 static void potato_uart_write(char c
)
79 potato_uart_reg_write(POTATO_CONSOLE_TX
, val
);
82 static unsigned long potato_uart_divisor(unsigned long proc_freq
, unsigned long uart_freq
)
84 return proc_freq
/ (uart_freq
* 16) - 1;
87 void potato_uart_init(void)
89 potato_uart_base
= UART_BASE
;
91 potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV
, potato_uart_divisor(PROC_FREQ
, UART_FREQ
));
96 while (potato_uart_rx_empty())
99 return potato_uart_read();
102 void putchar(unsigned char c
)
104 while (potato_uart_tx_full())
107 potato_uart_write(c
);
110 void putstr(const char *str
, unsigned long len
)
112 for (unsigned long i
= 0; i
< len
; i
++) {
117 size_t strlen(const char *s
)