diff --git a/ports/powerpc/Makefile b/ports/powerpc/Makefile index 5f17a93557..1f5ec80d43 100644 --- a/ports/powerpc/Makefile +++ b/ports/powerpc/Makefile @@ -6,6 +6,9 @@ QSTR_DEFS = qstrdefsport.h # include py core make definitions include $(TOP)/py/py.mk +# potato or lpc_serial +UART ?= potato + ARCH = $(shell uname -m) ifneq ("$(ARCH)", "ppc64") ifneq ("$(ARCH)", "ppc64le") @@ -30,9 +33,7 @@ LIBS = SRC_C = \ main.c \ - uart_core.c \ - uart_potato.c \ - uart_lpc_serial.c \ + uart_$(UART).c \ lib/utils/printf.c \ lib/utils/stdout_helpers.c \ lib/utils/pyexec.c \ diff --git a/ports/powerpc/README.md b/ports/powerpc/README.md index 862bfcd3c5..631924c7c0 100644 --- a/ports/powerpc/README.md +++ b/ports/powerpc/README.md @@ -6,10 +6,14 @@ potato UART. ## Building -By default the port will be built for the host machine: +By default the port will be built with the potato uart for microwatt: $ make +To instead build for a machine with LPC serial, such as QEMU powernv: + + $ make UART=lpc_serial + ## Cross compilation for POWERPC If you need to cross compilers you'll want to grab a powerpc64le diff --git a/ports/powerpc/main.c b/ports/powerpc/main.c index 421f9be714..fdeec13abe 100644 --- a/ports/powerpc/main.c +++ b/ports/powerpc/main.c @@ -65,7 +65,6 @@ int main(int argc, char **argv) { int stack_dummy; stack_top = (char *)&stack_dummy; - // microwatt has argc/r3 = 0 whereas QEMU has r3 set in head.S uart_init_ppc(argc); #if MICROPY_ENABLE_PYSTACK diff --git a/ports/powerpc/uart_core.c b/ports/powerpc/uart_core.c deleted file mode 100644 index b0dcd031a5..0000000000 --- a/ports/powerpc/uart_core.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019, Michael Neuling, IBM Corporation. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "py/mpconfig.h" -#include "uart_potato.h" -#include "uart_lpc_serial.h" - -static int lpc_console; -static int potato_console; - -void uart_init_ppc(int lpc) { - lpc_console = lpc; - - if (!lpc_console) { - potato_console = 1; - - potato_uart_init(); - } else { - lpc_uart_init(); - } -} - -// Receive single character -int mp_hal_stdin_rx_chr(void) { - unsigned char c = 0; - if (lpc_console) { - c = lpc_uart_read(); - } else if (potato_console) { - c = potato_uart_read(); - } - return c; -} - -// Send string of given length -void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { - if (lpc_console) { - int i; - for (i = 0; i < len; i++) { - lpc_uart_write(str[i]); - } - } else if (potato_console) { - int i; - for (i = 0; i < len; i++) { - potato_uart_write(str[i]); - } - } -} diff --git a/ports/powerpc/uart_lpc_serial.c b/ports/powerpc/uart_lpc_serial.c index c15fc049b9..760615041c 100644 --- a/ports/powerpc/uart_lpc_serial.c +++ b/ports/powerpc/uart_lpc_serial.c @@ -96,20 +96,24 @@ static int lpc_uart_rx_empty(void) { return !(lpc_uart_reg_read(REG_LSR) & LSR_DR); } -void lpc_uart_init(void) { +void uart_init_ppc(void) { lpc_uart_base = LPC_UART_BASE; } -char lpc_uart_read(void) { +int mp_hal_stdin_rx_chr(void) { while (lpc_uart_rx_empty()) { ; } return lpc_uart_reg_read(REG_THR); } -void lpc_uart_write(char c) { - while (lpc_uart_tx_full()) { - ; + +void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { + int i; + for (i = 0; i < len; i++) { + while (lpc_uart_tx_full()) { + ; + } + lpc_uart_reg_write(REG_RBR, str[i]); } - lpc_uart_reg_write(REG_RBR, c); } diff --git a/ports/powerpc/uart_potato.c b/ports/powerpc/uart_potato.c index 4a487f3032..29f21934dd 100644 --- a/ports/powerpc/uart_potato.c +++ b/ports/powerpc/uart_potato.c @@ -34,10 +34,12 @@ #include #include "py/mpconfig.h" -#define PROC_FREQ 50000000 +#define SYSCON_BASE 0xc0000000 /* System control regs */ +#define SYS_REG_CLKINFO 0x20 + #define UART_FREQ 115200 #define POTATO_UART_BASE 0xc0002000 -uint64_t potato_uart_base; +static uint64_t potato_uart_base; #define POTATO_CONSOLE_TX 0x00 #define POTATO_CONSOLE_RX 0x08 @@ -60,7 +62,7 @@ static uint64_t potato_uart_reg_read(int offset) { return val; } -void potato_uart_reg_write(int offset, uint64_t val) { +static void potato_uart_reg_write(int offset, uint64_t val) { uint64_t addr; addr = potato_uart_base + offset; @@ -96,13 +98,16 @@ static unsigned long potato_uart_divisor(unsigned long proc_freq, unsigned long return proc_freq / (uart_freq * 16) - 1; } -void potato_uart_init(void) { +void uart_init_ppc(void) { + uint64_t proc_freq; + potato_uart_base = POTATO_UART_BASE; - potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(PROC_FREQ, UART_FREQ)); + proc_freq = *(volatile uint64_t *)(SYSCON_BASE + SYS_REG_CLKINFO); + potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV, potato_uart_divisor(proc_freq, UART_FREQ)); } -char potato_uart_read(void) { +int mp_hal_stdin_rx_chr(void) { uint64_t val; while (potato_uart_rx_empty()) { @@ -113,13 +118,15 @@ char potato_uart_read(void) { return (char)(val & 0x000000ff); } -void potato_uart_write(char c) { - uint64_t val; +void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { + int i; - val = c; + for (i = 0; i < len; i++) { + uint64_t val = str[i]; - while (potato_uart_tx_full()) { - ; + while (potato_uart_tx_full()) { + ; + } + potato_uart_reg_write(POTATO_CONSOLE_TX, val); } - potato_uart_reg_write(POTATO_CONSOLE_TX, val); }