#include #include #include #include #include #include #include #include "microwatt_soc.h" #include "io.h" #include "sdram.h" /* * Core UART functions to implement for a port */ static uint64_t potato_uart_base; #define PROC_FREQ 100000000 #define UART_FREQ 115200 static uint8_t potato_uart_reg_read(int offset) { return readb(potato_uart_base + offset); } static void potato_uart_reg_write(int offset, uint8_t val) { writeb(val, potato_uart_base + offset); } static bool potato_uart_rx_empty(void) { uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS); return (val & POTATO_CONSOLE_STATUS_RX_EMPTY) != 0; } static int potato_uart_tx_full(void) { uint8_t val = potato_uart_reg_read(POTATO_CONSOLE_STATUS); return (val & POTATO_CONSOLE_STATUS_TX_FULL) != 0; } static char potato_uart_read(void) { return potato_uart_reg_read(POTATO_CONSOLE_RX); } static void potato_uart_write(char c) { potato_uart_reg_write(POTATO_CONSOLE_TX, c); } 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(); } int putchar(int c) { while (potato_uart_tx_full()) /* Do Nothing */; potato_uart_write(c); return c; } void putstr(const char *str, unsigned long len) { for (unsigned long i = 0; i < len; i++) { if (str[i] == '\n') putchar('\r'); putchar(str[i]); } } int _printf(const char *fmt, ...) { int count; char buffer[320]; va_list ap; va_start(ap, fmt); count = vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); putstr(buffer, count); return count; } void flush_cpu_dcache(void) { } void flush_cpu_icache(void) { } void flush_l2_cache(void) { } void main(void) { unsigned long long ftr, val; int i; /* * Let things settle ... not sure why but the UART is * not happy otherwise. The PLL might need to settle ? */ potato_uart_init(); for (i = 0; i < 100000; i++) potato_uart_reg_read(POTATO_CONSOLE_STATUS); printf("\n\nWelcome to Microwatt !\n\n"); /* TODO: Add core version information somewhere in syscon, possibly * extracted from git */ printf(" Soc signature: %016llx\n", (unsigned long long)readq(SYSCON_BASE + SYS_REG_SIGNATURE)); printf(" Soc features: "); ftr = readq(SYSCON_BASE + SYS_REG_INFO); if (ftr & SYS_REG_INFO_HAS_UART) printf("UART "); if (ftr & SYS_REG_INFO_HAS_DRAM) printf("DRAM "); printf("\n"); val = readq(SYSCON_BASE + SYS_REG_BRAMINFO); printf(" BRAM: %lld KB\n", val / 1024); if (ftr & SYS_REG_INFO_HAS_DRAM) { val = readq(SYSCON_BASE + SYS_REG_DRAMINFO); printf(" DRAM: %lld MB\n", val / (1024 * 1024)); } val = readq(SYSCON_BASE + SYS_REG_CLKINFO); printf(" CLK: %lld MHz\n", val / 1000000); printf("\n"); if (ftr & SYS_REG_INFO_HAS_DRAM) { printf("LiteDRAM built from Migen %s and LiteX %s\n", MIGEN_GIT_SHA1, LITEX_GIT_SHA1); sdrinit(); } printf("Booting from BRAM...\n"); }