1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-01-11 23:43:15 +00:00

console: Add support for the 16550 UART

And rebuild various binaries

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Benjamin Herrenschmidt 2020-06-18 17:14:41 +10:00
parent cc10f6b289
commit d654667304
15 changed files with 1565 additions and 1347 deletions

Binary file not shown.

Binary file not shown.

View File

@ -515,79 +515,117 @@ e8010010ebc1fff0
3c4000014e800020 3c4000014e800020
7c0802a63842a000 7c0802a63842a000
f821ffe1f8010010 f821ffe1f8010010
6000000048000229 60000000480001dd
386372783c62ffff 386373a83c62ffff
600000004800018d 6000000048000141
60000000480000f9 600000004800002d
480001355463063e 480000a95463063e
4bffffec60000000 4bffffec60000000
0100000000000000 0100000000000000
3c40000100000080 3c40000100000080
3d20c0003842a000 600000003842a000
6129200060000000 6000000039228000
f922800079290020 8929000039428008
612900203d20c000 419e00302f890000
7c0004ac79290020 39290014e92a0000
3d40001c7d204eea 7d204eaa7c0004ac
614a200079290600 4182ffec71290001
e94280007d295392 7c0004ace86a0000
3929ffff394a0018 5463063e7c601eaa
e92a00004e800020
7c0004ac39290010
712900017d204eea
e86a00004082ffec
7c0004ac38630008
4bffffd07c601eea
0000000000000000
3c40000100000000
600000003842a000
6000000039228000
8929000039428008
419e002c2f890000
39290014e92a0000
7d204eaa7c0004ac
4182ffec71290020
7c0004ace92a0000
4e8000207c604faa
39290010e92a0000
7d204eea7c0004ac
4082ffec71290008
e94a00005469063e
7d2057ea7c0004ac 7d2057ea7c0004ac
000000004e800020 000000004e800020
0000000000000000 0000000000000000
3842a0003c400001 3842a0003c400001
419e00082fa40000 fbc1fff07c0802a6
6000000060630002 3bc3fffffbe1fff8
39290020e9228000 f821ffd1f8010010
7c604fea7c0004ac 2fbf00008ffe0001
000000004e800020 38210030409e0010
4bfffe5c38600000
409e000c2b9f000a
4bffff413860000d
4bffff397fe3fb78
000000004bffffd0
0000028001000000
7d4348ae39200000
409e000c2f8a0000
4e8000207d234b78
4bffffe839290001
0000000000000000 0000000000000000
3842a0003c400001 3c40000100000000
e922800060000000 3d20c0003842a000
3929002039400000 7929002061290020
7d404fea7c0004ac 7d204eea7c0004ac
000000004e800020 792906003d00c000
0000000000000000 7908002061080008
3842a0003c400001 7d0046ea7c0004ac
e922800060000000 3940000071080020
7c0004ac39290010 3d40c00041820018
712900017d204eea 794a0020614a0040
e86280004082ffe8 7d4056ea7c0004ac
7c0004ac38630008 600000003d00c000
5463063e7c601eea 38e2800060000000
000000004e800020 7908002061082000
0000000000000000 3d00001cf9028008
3842a0003c400001 7d29439261082000
e922800060000000 79080fc37948f804
7c0004ac39290010 3940000141820080
712900087d204eea 6108200c3d00c000
5469063e4082ffe8 7908002099470000
7c0004ace9428000 7c0004ac3940ff80
e94280087d4047aa
7d2057aa7c0004ac
7929c202e9428008
7c0004ac394a0004
e92280087d2057aa
3929000c39400003
7d404faa7c0004ac
39290010e9228008
7d404faa7c0004ac
39400007e9228008
7c0004ac39290008
4e8000207d404faa
990700003d40c000
614a20183929ffff
7c0004ac794a0020
4e8000207d2057ea 4e8000207d2057ea
0000000000000000 0000000000000000
3c40000100000000 3c40000100000000
7c0802a63842a000 600000003842a000
fbe1fff8fbc1fff0 2ea4000039228000
f80100103bc3ffff 2f89000089290000
8ffe0001f821ffd1 e922800860000000
409e00102fbf0000 41960024419e0030
3860000038210030 2fa3000039400002
2b9f000a4bfffe10 614a0001419e0008
3860000d409e000c 7c0004ac39290004
7fe3fb784bffff81 4e8000207d404faa
4bffffd04bffff79 4bffffe039400000
0100000000000000 6063000241960008
3920000000000280 7c0004ac39290020
2f8a00007d4348ae 4e8000207c604fea
7d234b78409e000c
392900014e800020
000000004bffffe8
0000000000000000 0000000000000000
3842a0003c400001
000000004bfffe1c
0000000000000000
3842a0003c400001
000000004bfffe68
0000000000000000 0000000000000000
6f57206f6c6c6548 6f57206f6c6c6548
000000000a646c72 000000000a646c72

View File

@ -79,6 +79,10 @@
#define UART_REG_TX 0x00 #define UART_REG_TX 0x00
#define UART_REG_DLL 0x00 #define UART_REG_DLL 0x00
#define UART_REG_IER 0x04 #define UART_REG_IER 0x04
#define UART_REG_IER_RDI 0x01
#define UART_REG_IER_THRI 0x02
#define UART_REG_IER_RLSI 0x04
#define UART_REG_IER_MSI 0x08
#define UART_REG_DLM 0x04 #define UART_REG_DLM 0x04
#define UART_REG_IIR 0x08 #define UART_REG_IIR 0x08
#define UART_REG_FCR 0x08 #define UART_REG_FCR 0x08

View File

@ -5,22 +5,29 @@
#include "microwatt_soc.h" #include "microwatt_soc.h"
#include "io.h" #include "io.h"
#define UART_FREQ 115200 #define UART_BAUDS 115200
/* /*
* Core UART functions to implement for a port * Core UART functions to implement for a port
*/ */
static uint64_t potato_uart_base; bool uart_is_std;
static uint64_t uart_base;
static unsigned long uart_divisor(unsigned long uart_freq, unsigned long bauds)
{
return uart_freq / (bauds * 16);
}
static uint64_t potato_uart_reg_read(int offset) static uint64_t potato_uart_reg_read(int offset)
{ {
return readq(potato_uart_base + offset); return readq(uart_base + offset);
} }
static void potato_uart_reg_write(int offset, uint64_t val) static void potato_uart_reg_write(int offset, uint64_t val)
{ {
writeq(val, potato_uart_base + offset); writeq(val, uart_base + offset);
} }
static int potato_uart_rx_empty(void) static int potato_uart_rx_empty(void)
@ -65,22 +72,13 @@ static void potato_uart_write(char c)
potato_uart_reg_write(POTATO_CONSOLE_TX, val); potato_uart_reg_write(POTATO_CONSOLE_TX, val);
} }
static unsigned long potato_uart_divisor(unsigned long proc_freq, unsigned long uart_freq) static void potato_uart_init(uint64_t uart_freq)
{ {
return proc_freq / (uart_freq * 16) - 1; unsigned long div = uart_divisor(uart_freq, UART_BAUDS) - 1;
potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, div);
} }
void potato_uart_init(void) static void potato_uart_set_irq_en(bool rx_irq, bool tx_irq)
{
uint64_t proc_freq;
potato_uart_base = UART_BASE;
proc_freq = readq(SYSCON_BASE + SYS_REG_CLKINFO) & SYS_REG_CLKINFO_FREQ_MASK;
potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(proc_freq, UART_FREQ));
}
void potato_uart_set_irq_en(bool rx_irq, bool tx_irq)
{ {
uint64_t en = 0; uint64_t en = 0;
@ -91,25 +89,76 @@ void potato_uart_set_irq_en(bool rx_irq, bool tx_irq)
potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN, en); potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN, en);
} }
void potato_uart_irq_dis(void) static bool std_uart_rx_empty(void)
{ {
potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN, 0x00); return !(readb(uart_base + UART_REG_LSR) & UART_REG_LSR_DR);
}
static uint8_t std_uart_read(void)
{
return readb(uart_base + UART_REG_RX);
}
static bool std_uart_tx_full(void)
{
return !(readb(uart_base + UART_REG_LSR) & UART_REG_LSR_THRE);
}
static void std_uart_write(uint8_t c)
{
writeb(c, uart_base + UART_REG_TX);
}
static void std_uart_set_irq_en(bool rx_irq, bool tx_irq)
{
uint8_t ier = 0;
if (tx_irq)
ier |= UART_REG_IER_THRI;
if (rx_irq)
ier |= UART_REG_IER_RDI;
writeb(ier, uart_base + UART_REG_IER);
}
static void std_uart_init(uint64_t uart_freq)
{
unsigned long div = uart_divisor(uart_freq, UART_BAUDS);
writeb(UART_REG_LCR_DLAB, uart_base + UART_REG_LCR);
writeb(div & 0xff, uart_base + UART_REG_DLL);
writeb(div >> 8, uart_base + UART_REG_DLM);
writeb(UART_REG_LCR_8BIT, uart_base + UART_REG_LCR);
writeb(UART_REG_MCR_DTR |
UART_REG_MCR_RTS, uart_base + UART_REG_MCR);
writeb(UART_REG_FCR_EN_FIFO |
UART_REG_FCR_CLR_RCVR |
UART_REG_FCR_CLR_XMIT, uart_base + UART_REG_FCR);
} }
int getchar(void) int getchar(void)
{ {
if (uart_is_std) {
while (std_uart_rx_empty())
/* Do nothing */ ;
return std_uart_read();
} else {
while (potato_uart_rx_empty()) while (potato_uart_rx_empty())
/* Do nothing */ ; /* Do nothing */ ;
return potato_uart_read(); return potato_uart_read();
} }
}
int putchar(int c) int putchar(int c)
{ {
if (uart_is_std) {
while(std_uart_tx_full())
/* Do Nothing */;
std_uart_write(c);
} else {
while (potato_uart_tx_full()) while (potato_uart_tx_full())
/* Do Nothing */; /* Do Nothing */;
potato_uart_write(c); potato_uart_write(c);
}
return c; return c;
} }
@ -140,10 +189,35 @@ size_t strlen(const char *s)
void console_init(void) void console_init(void)
{ {
potato_uart_init(); uint64_t sys_info;
uint64_t proc_freq;
uint64_t uart_info = 0;
uint64_t uart_freq = 0;
proc_freq = readq(SYSCON_BASE + SYS_REG_CLKINFO) & SYS_REG_CLKINFO_FREQ_MASK;
sys_info = readq(SYSCON_BASE + SYS_REG_INFO);
if (sys_info & SYS_REG_INFO_HAS_LARGE_SYSCON) {
uart_info = readq(SYSCON_BASE + SYS_REG_UART0_INFO);
uart_freq = uart_info & 0xffffffff;
}
if (uart_freq == 0)
uart_freq = proc_freq;
uart_base = UART_BASE;
if (uart_info & SYS_REG_UART_IS_16550) {
uart_is_std = true;
std_uart_init(proc_freq);
} else {
uart_is_std = false;
potato_uart_init(proc_freq);
}
} }
void console_set_irq_en(bool rx_irq, bool tx_irq) void console_set_irq_en(bool rx_irq, bool tx_irq)
{ {
if (uart_is_std)
std_uart_set_irq_en(rx_irq, tx_irq);
else
potato_uart_set_irq_en(rx_irq, tx_irq); potato_uart_set_irq_en(rx_irq, tx_irq);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.