forked from cores/microwatt
				
			Breakout the console code so it can be reused.
No functional change. Signed-off-by: Michael Neuling <mikey@neuling.org>jtag-port
							parent
							
								
									8bee4ae3cc
								
							
						
					
					
						commit
						96fbd61de8
					
				@ -0,0 +1,132 @@
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Core UART functions to implement for a port
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static uint64_t potato_uart_base;
 | 
			
		||||
 | 
			
		||||
#define PROC_FREQ 50000000
 | 
			
		||||
#define UART_FREQ 115200
 | 
			
		||||
#define UART_BASE 0xc0002000
 | 
			
		||||
 | 
			
		||||
#define POTATO_CONSOLE_TX		0x00
 | 
			
		||||
#define POTATO_CONSOLE_RX		0x08
 | 
			
		||||
#define POTATO_CONSOLE_STATUS		0x10
 | 
			
		||||
#define   POTATO_CONSOLE_STATUS_RX_EMPTY		0x01
 | 
			
		||||
#define   POTATO_CONSOLE_STATUS_TX_EMPTY		0x02
 | 
			
		||||
#define   POTATO_CONSOLE_STATUS_RX_FULL			0x04
 | 
			
		||||
#define   POTATO_CONSOLE_STATUS_TX_FULL			0x08
 | 
			
		||||
#define POTATO_CONSOLE_CLOCK_DIV	0x18
 | 
			
		||||
#define POTATO_CONSOLE_IRQ_EN		0x20
 | 
			
		||||
 | 
			
		||||
static uint64_t potato_uart_reg_read(int offset)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t addr;
 | 
			
		||||
	uint64_t val;
 | 
			
		||||
 | 
			
		||||
	addr = potato_uart_base + offset;
 | 
			
		||||
 | 
			
		||||
	val = *(volatile uint64_t *)addr;
 | 
			
		||||
 | 
			
		||||
	return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void potato_uart_reg_write(int offset, uint64_t val)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t addr;
 | 
			
		||||
 | 
			
		||||
	addr = potato_uart_base + offset;
 | 
			
		||||
 | 
			
		||||
	*(volatile uint64_t *)addr = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int potato_uart_rx_empty(void)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t val;
 | 
			
		||||
 | 
			
		||||
	val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
 | 
			
		||||
 | 
			
		||||
	if (val & POTATO_CONSOLE_STATUS_RX_EMPTY)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int potato_uart_tx_full(void)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t val;
 | 
			
		||||
 | 
			
		||||
	val = potato_uart_reg_read(POTATO_CONSOLE_STATUS);
 | 
			
		||||
 | 
			
		||||
	if (val & POTATO_CONSOLE_STATUS_TX_FULL)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char potato_uart_read(void)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t val;
 | 
			
		||||
 | 
			
		||||
	val = potato_uart_reg_read(POTATO_CONSOLE_RX);
 | 
			
		||||
 | 
			
		||||
	return (char)(val & 0x000000ff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void potato_uart_write(char c)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t val;
 | 
			
		||||
 | 
			
		||||
	val = c;
 | 
			
		||||
 | 
			
		||||
	potato_uart_reg_write(POTATO_CONSOLE_TX, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long potato_uart_divisor(unsigned long proc_freq, unsigned long uart_freq)
 | 
			
		||||
{
 | 
			
		||||
	return proc_freq / (uart_freq * 16) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void potato_uart_init(void)
 | 
			
		||||
{
 | 
			
		||||
	potato_uart_base = UART_BASE;
 | 
			
		||||
 | 
			
		||||
	potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(PROC_FREQ, UART_FREQ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int getchar(void)
 | 
			
		||||
{
 | 
			
		||||
	while (potato_uart_rx_empty())
 | 
			
		||||
		/* Do nothing */ ;
 | 
			
		||||
 | 
			
		||||
	return potato_uart_read();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void putchar(unsigned char c)
 | 
			
		||||
{
 | 
			
		||||
	while (potato_uart_tx_full())
 | 
			
		||||
		/* Do Nothing */;
 | 
			
		||||
 | 
			
		||||
	potato_uart_write(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void putstr(const char *str, unsigned long len)
 | 
			
		||||
{
 | 
			
		||||
	for (unsigned long i = 0; i < len; i++) {
 | 
			
		||||
		putchar(str[i]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t strlen(const char *s)
 | 
			
		||||
{
 | 
			
		||||
	size_t len = 0;
 | 
			
		||||
 | 
			
		||||
	while (*s++)
 | 
			
		||||
		len++;
 | 
			
		||||
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,5 @@
 | 
			
		||||
void potato_uart_init(void);
 | 
			
		||||
int getchar(void);
 | 
			
		||||
void putchar(unsigned char c);
 | 
			
		||||
void putstr(const char *str, unsigned long len);
 | 
			
		||||
size_t strlen(const char *s);
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue