diff --git a/configs/astral-cluster.sh b/configs/astral-cluster.sh index fda44fd..fc79117 100644 --- a/configs/astral-cluster.sh +++ b/configs/astral-cluster.sh @@ -4,6 +4,7 @@ export PULPRT_TARGET=astral-cluster export PULPRUN_TARGET=astral-cluster export CONFIG_NO_FC=1 export ARCHI_HMR=1 +export ARCHI_HOST_UART=1 if [ -n "${ZSH_VERSION:-}" ]; then DIR="$(readlink -f -- "${(%):-%x}")" diff --git a/drivers/host_uart.c b/drivers/host_uart.c new file mode 100644 index 0000000..eaace7d --- /dev/null +++ b/drivers/host_uart.c @@ -0,0 +1,47 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Nils Wistoff +// Paul Scheffler + +#include "host_uart.h" + +static inline volatile uint8_t *reg8(void *base, int offs) { + return (volatile uint8_t *)(base + offs); +} + +static inline void fence() { + asm volatile("fence" ::: "memory"); +} + +int uart_read_ready(void *uart_base) { + return *reg8(uart_base, UART_LINE_STATUS_REG_OFFSET) & (1 << UART_LINE_STATUS_DATA_READY_BIT); +} + +static inline int __uart_write_ready(void *uart_base) { + return *reg8(uart_base, UART_LINE_STATUS_REG_OFFSET) & (1 << UART_LINE_STATUS_THR_EMPTY_BIT); +} + +static inline int __uart_write_idle(void *uart_base) { + return __uart_write_ready(uart_base) && + *reg8(uart_base, UART_LINE_STATUS_REG_OFFSET) & (1 << UART_LINE_STATUS_TMIT_EMPTY_BIT); +} + +void uart_write(void *uart_base, uint8_t byte) { + while (!__uart_write_ready(uart_base)) + ; + *reg8(uart_base, UART_THR_REG_OFFSET) = byte; +} + +void uart_write_flush(void *uart_base) { + fence(); + while (!__uart_write_idle(uart_base)) + ; +} + +uint8_t uart_read(void *uart_base) { + while (!uart_read_ready(uart_base)) + ; + return *reg8(uart_base, UART_RBR_REG_OFFSET); +} diff --git a/drivers/include/host_uart.h b/drivers/include/host_uart.h new file mode 100644 index 0000000..915fc2c --- /dev/null +++ b/drivers/include/host_uart.h @@ -0,0 +1,40 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Nils Wistoff +// Paul Scheffler + +#pragma once + +#include + +// Register offsets +#define UART_RBR_REG_OFFSET 0 +#define UART_THR_REG_OFFSET 0 +#define UART_INTR_ENABLE_REG_OFFSET 4 +#define UART_INTR_IDENT_REG_OFFSET 8 +#define UART_FIFO_CONTROL_REG_OFFSET 8 +#define UART_LINE_CONTROL_REG_OFFSET 12 +#define UART_MODEM_CONTROL_REG_OFFSET 16 +#define UART_LINE_STATUS_REG_OFFSET 20 +#define UART_MODEM_STATUS_REG_OFFSET 24 +#define UART_DLAB_LSB_REG_OFFSET 0 +#define UART_DLAB_MSB_REG_OFFSET 4 + +// Register fields +#define UART_LINE_STATUS_DATA_READY_BIT 0 +#define UART_LINE_STATUS_THR_EMPTY_BIT 5 +#define UART_LINE_STATUS_TMIT_EMPTY_BIT 6 + +int uart_read_ready(void *uart_base); + +void uart_write(void *uart_base, uint8_t byte); + +void uart_write_str(void *uart_base, void *src, uint64_t len); + +void uart_write_flush(void *uart_base); + +uint8_t uart_read(void *uart_base); + +void uart_read_str(void *uart_base, void *dst, uint64_t len); diff --git a/drivers/uart.c b/drivers/udma_uart.c similarity index 100% rename from drivers/uart.c rename to drivers/udma_uart.c diff --git a/include/archi/chips/astral-cluster/memory_map.h b/include/archi/chips/astral-cluster/memory_map.h index 10db2bb..d4d1bd0 100644 --- a/include/archi/chips/astral-cluster/memory_map.h +++ b/include/archi/chips/astral-cluster/memory_map.h @@ -60,6 +60,7 @@ #define ARCHI_FC_ITC_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_FC_ITC_OFFSET ) #define ARCHI_FC_TIMER_ADDR ( ARCHI_SOC_PERIPHERALS_ADDR + ARCHI_FC_TIMER_OFFSET ) #define ARCHI_STDOUT_ADDR 0x03002000 +#define ARCHI_HOST_UART_ADDR 0x03002000 #define ARCHI_FLL_AREA_SIZE 0x00000010 diff --git a/include/pulp.h b/include/pulp.h index f7870e0..635f412 100755 --- a/include/pulp.h +++ b/include/pulp.h @@ -93,12 +93,12 @@ void _start(); #ifdef ARCHI_CLUSTER_NB_PE static inline int get_core_num() { return ARCHI_CLUSTER_NB_PE; } #endif - - +#if defined(CONFIG_IO_UART) && CONFIG_IO_UART == 1 int uart_open(int uart_id, int baudrate); void uart_close(int uart_id); int uart_write(int uart_id, void *buffer, uint32_t size); int uart_read(int uart_id, void *buffer, uint32_t size); +#endif void synch_barrier(); diff --git a/lib/libc/minimal/io.c b/lib/libc/minimal/io.c index 3a0857a..3510ec4 100644 --- a/lib/libc/minimal/io.c +++ b/lib/libc/minimal/io.c @@ -239,12 +239,21 @@ static void pos_libc_putc_uart(char c) } #endif +#if defined(CONFIG_IO_UART) && CONFIG_IO_UART == 2 +static void pos_libc_putc_host_uart(char c) +{ + uart_write(ARCHI_HOST_UART_ADDR, c); + uart_write_flush(ARCHI_HOST_UART_ADDR); +} +#endif static void pos_putc(char c) { #if defined(CONFIG_IO_UART) && CONFIG_IO_UART == 1 pos_libc_putc_uart(c); +#elif defined(CONFIG_IO_UART) && CONFIG_IO_UART == 2 + pos_libc_putc_host_uart(c); #else pos_libc_putc_stdout(c); #endif diff --git a/rules/pulpos/default_rules.mk b/rules/pulpos/default_rules.mk index 9ea3c2b..0621820 100644 --- a/rules/pulpos/default_rules.mk +++ b/rules/pulpos/default_rules.mk @@ -36,6 +36,10 @@ ifdef io ifeq '$(io)' 'uart' CONFIG_IO_UART=1 endif +ifeq '$(io)' 'host_uart' +CONFIG_IO_UART=2 +PULP_APP_CFLAGS += -I$(PULPRT_HOME)/drivers/include +endif endif VPATH = $(PULPRT_HOME) diff --git a/rules/pulpos/src.mk b/rules/pulpos/src.mk index 22152d0..50ae84c 100644 --- a/rules/pulpos/src.mk +++ b/rules/pulpos/src.mk @@ -6,7 +6,15 @@ ifeq '$(CONFIG_LIBC_MINIMAL)' '1' PULP_SRCS += lib/libc/minimal/io.c lib/libc/minimal/fprintf.c lib/libc/minimal/prf.c lib/libc/minimal/sprintf.c endif -PULP_SRCS += kernel/init.c kernel/kernel.c kernel/alloc.c kernel/alloc_pool.c kernel/irq.c kernel/soc_event.c kernel/bench.c drivers/uart.c +ifeq '$(CONFIG_IO_UART)' '1' +PULP_SRCS += drivers/udma_uart.c +endif + +ifeq '$(CONFIG_IO_UART)' '2' +PULP_SRCS += drivers/host_uart.c +endif + +PULP_SRCS += kernel/init.c kernel/kernel.c kernel/alloc.c kernel/alloc_pool.c kernel/irq.c kernel/soc_event.c kernel/bench.c PULP_ASM_SRCS += kernel/irq_asm.S