diff --git a/iveia/Makefile b/iveia/Makefile index 58863d1..11e7cd5 100644 --- a/iveia/Makefile +++ b/iveia/Makefile @@ -3,11 +3,15 @@ BASE_DIR = $(abspath .) CFLAGS := -DALIGN_UART -DFPGA_GFE CC := $(ISP_PREFIX)/bin/clang + +ARCH ?= rv64 + ifneq ($(ARCH), rv64) RISCV_ARCH ?= rv32ima RISCV_ABI ?= ilp32 CFLAGS += --target=riscv32-unknown-elf CFLAGS += -DCPU_CLOCK_HZ=50000000 +CFLAGS += -DRV32 else RISCV_ARCH ?= rv64imafd RISCV_ABI ?= lp64d @@ -15,13 +19,15 @@ RISCV_ABI ?= lp64d CFLAGS += --target=riscv64-unknown-elf CFLAGS += -mcmodel=medany CFLAGS += -DCPU_CLOCK_HZ=50000000 +CFLAGS += -DRV64 endif CFLAGS += -O0 -g3 -Wall -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) LIB_TARGET = libiveia.a +LIB_UART = libuart-$(ARCH).a -CFLAGS += -I$(ISP_PREFIX)/include \ +CFLAGS += -I$(ISP_PREFIX)/include -I$(ISP_PREFIX)/iveia_bsp \ -I$(BASE_DIR) \ -I$(BASE_DIR)/wrap \ -I$(BASE_DIR)/xilinx/common \ @@ -32,13 +38,11 @@ CFLAGS += -I$(ISP_PREFIX)/include \ C_SRCS = init.c \ uart.c \ wrap/isatty.c \ - wrap/malloc.c \ wrap/printf.c \ wrap/puts.c \ wrap/read.c \ wrap/write.c \ - wrap/sbrk.c \ - xilinx/common/xbasic_types.c \ + xilinx/common/xbasic_types.c \ xilinx/common/xil_io.c \ xilinx/common/xil_assert.c \ xilinx/uartns550/xuartns550.c \ @@ -51,13 +55,18 @@ C_SRCS = init.c \ xilinx/uartns550/xuartns550_sinit.c \ xilinx/uartns550/xuartns550_stats.c +C_SRCS_SYS = wrap/malloc.c \ + wrap/sbrk.c + + ASM_SRCS = boot.S -OBJS = $(patsubst %.c,%.o,$(C_SRCS)) -OBJS += $(patsubst %.S,%.o,$(ASM_SRCS)) +OBJS = $(patsubst %.c,%.o,$(C_SRCS)) +ASM_OBJS = $(patsubst %.S,%.o,$(ASM_SRCS)) +SYS_OBJS = $(patsubst %.c,%.o,$(C_SRCS_SYS)) all: $(LIB_TARGET) -.PHONY: all clean +.PHONY: all clean $(LIB_UART) .PRECIOUS: $(BUILD_DIR)/ $(BUILD_DIR)%/ .SECONDEXPANSION: @@ -67,8 +76,11 @@ all: $(LIB_TARGET) %.o: %.S $(CC) $(CFLAGS) -c $< -o $@ -$(LIB_TARGET): $(OBJS) +$(LIB_TARGET): $(OBJS) $(ASM_OBJS) $(SYS_OBJS) + ar rcs $@ $(OBJS) $(ASM_OBJS) $(SYS_OBJS) + +$(LIB_UART): $(OBJS) ar rcs $@ $(OBJS) clean: - rm -rf $(OBJS) $(LIB_TARGET) + rm -rf $(OBJS) $(ASM_OBJS) $(SYS_OBJS) $(LIB_TARGET) diff --git a/iveia/Makefile.isp b/iveia/Makefile.isp new file mode 100644 index 0000000..fb062dd --- /dev/null +++ b/iveia/Makefile.isp @@ -0,0 +1,13 @@ +LIBS := libiveia.a +LIBS += libuart-rv32.a +LIBS += libuart-rv64.a + +.PHONY: all + +all: + make clean && make all + ARCH=rv32 make -B libuart-rv32.a + ARCH=rv64 make -B libuart-rv64.a + +clean: + make clean && /bin/rm -f $(LIBS) diff --git a/iveia/bsp.h b/iveia/bsp.h deleted file mode 100644 index 96b387a..0000000 --- a/iveia/bsp.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RISCV_P2_BSP_H -#define RISCV_P2_BSP_H - -#ifndef CPU_CLOCK_HZ -#define CPU_CLOCK_HZ 50000000 -#endif - -/** - * UART defines - */ -#define XPAR_XUARTNS550_NUM_INSTANCES 2 -#define XPAR_DEFAULT_BAUD_RATE 115200 - -#define BSP_USE_UART0 1 -#define XPAR_UARTNS550_0_DEVICE_ID 0 -#define XPAR_UARTNS550_0_BAUD_RATE XPAR_DEFAULT_BAUD_RATE -#define XPAR_UARTNS550_0_BASEADDR 0xA0000000ULL -#define XPAR_UARTNS550_0_CLOCK_HZ CPU_CLOCK_HZ - -// UART1 is in use by the PEX, so avoid re-initializing it on the AP -#define BSP_USE_UART1 0 -#define XPAR_UARTNS550_1_DEVICE_ID 1 -#define XPAR_UARTNS550_1_BAUD_RATE XPAR_DEFAULT_BAUD_RATE -#define XPAR_UARTNS550_1_BASEADDR (0xA0010000ULL) -#define XPAR_UARTNS550_1_CLOCK_HZ CPU_CLOCK_HZ - -#endif /* RISCV_P2_BSP_H */ diff --git a/iveia/init.c b/iveia/init.c index 48047d3..176d8d4 100644 --- a/iveia/init.c +++ b/iveia/init.c @@ -15,7 +15,7 @@ void bad_trap(){ asm volatile("csrr %0, mcause" : "=r"(mcause)); asm volatile("csrr %0, mtval" : "=r"(mtval)); asm volatile("csrr %0, mepc" : "=r"(mepc)); - printf("\n FAILURE: \n mcause=0x%lx\n, mepc=0x%lx \n, mtval=0x%lx \n", mcause, mepc, mtval); + printf("\n BAD TRAP: \n mcause=0x%lx\n, mepc=0x%lx \n, mtval=0x%lx \n", mcause, mepc, mtval); } void _init(void) diff --git a/iveia/uart.c b/iveia/uart.c index b91e565..b4edb6e 100644 --- a/iveia/uart.c +++ b/iveia/uart.c @@ -53,108 +53,48 @@ static XUartNs550 UartNs550_1; struct UartDriver Uart1; #endif +#if BSP_USE_UART2 +static XUartNs550 UartNs550_2; +struct UartDriver Uart2; +#endif + /*****************************************************************************/ /* Peripheral specific definitions */ #if BSP_USE_UART0 /** * Initialize UART 0 peripheral */ -void uart0_init(void) -{ - uart_init(&Uart0, XPAR_UARTNS550_0_DEVICE_ID, 0); -} - -/** - * Return 1 if UART0 has at leas 1 byte in the RX FIFO - */ -bool uart0_rxready(void) -{ - return uart_rxready(&Uart0); -} - -/** - * Receive a single byte. Polling mode, waits until finished - */ -char uart0_rxchar(void) -{ - return (char)uart_rxchar(&Uart0); -} - -/** - * Transmit a buffer. Waits indefinitely for a UART TX mutex, - * returns number of transferred bytes or -1 in case of an error. - * Synchronous API. - */ -int uart0_txbuffer(char *ptr, int len) -{ - return uart_txbuffer(&Uart0, (uint8_t *)ptr, len); -} - -/** - * Transmit a single byte. Polling mode, waits until finished - */ -char uart0_txchar(char c) -{ - return (char)uart_txchar(&Uart0, (uint8_t)c); -} +UART_INIT(0) +UART_RXREADY(0) +UART_RXCHAR(0) +UART_TXCHAR(0) +UART_TXBUFFER(0) +UART_RXBUFFER(0) -int uart0_rxbuffer(char *ptr, int len) -{ - return uart_rxbuffer(&Uart0, (uint8_t *)ptr, len); -} #endif /* BSP_USE_UART0 */ #if BSP_USE_UART1 -/** - * Initialize UART 1 peripheral - */ -void uart1_init(void) -{ - uart_init(&Uart1, XPAR_UARTNS550_1_DEVICE_ID, 0); -} -/** - * Return 1 if UART1 has at leas 1 byte in the RX FIFO - */ -bool uart1_rxready(void) -{ - return uart_rxready(&Uart1); -} +UART_INIT(1) +UART_RXREADY(1) +UART_RXCHAR(1) +UART_TXCHAR(1) +UART_TXBUFFER(1) +UART_RXBUFFER(1) -/** - * Receive a single byte. - */ -char uart1_rxchar(void) -{ - return (char)uart_rxchar(&Uart1); -} +#endif /* BSP_USE_UART1 */ -/** - * Transmit a buffer. Waits indefinitely for a UART TX mutex, - * returns number of transferred bytes or -1 in case of an error. - * Synchronous API. - */ -int uart1_txbuffer(char *ptr, int len) -{ - return uart_txbuffer(&Uart1, (uint8_t *)ptr, len); -} +#if BSP_USE_UART2 -/** - * Transmit a single byte. - */ -char uart1_txchar(char c) -{ - return (char)uart_txchar(&Uart1, (uint8_t)c); -} +UART_INIT(2) +UART_RXREADY(2) +UART_RXCHAR(2) +UART_TXCHAR(2) +UART_TXBUFFER(2) +UART_RXBUFFER(2) + +#endif /* BSP_USE_UART2 */ -/** - * Transmit buffer. - */ -int uart1_rxbuffer(char *ptr, int len) -{ - return uart_rxbuffer(&Uart1, (uint8_t *)ptr, len); -} -#endif /* BSP_USE_UART1 */ /*****************************************************************************/ /* Driver specific defintions */ @@ -180,6 +120,11 @@ static void uart_init(struct UartDriver *Uart, uint8_t device_id, uint8_t plic_s case 1: Uart->Device = UartNs550_1; break; +#endif +#if BSP_USE_UART2 + case 2: + Uart->Device = UartNs550_2; + break; #endif default: // Trigger a fault: unsupported device ID diff --git a/iveia/uart.h b/iveia/uart.h index b1521d8..2c1f395 100644 --- a/iveia/uart.h +++ b/iveia/uart.h @@ -4,22 +4,73 @@ #include "bsp.h" #include +/** + * Initialize UART peripheral + */ +#define UART_INIT(uart_number) \ + void uart##uart_number##_init(void) \ + { uart_init(&Uart ## uart_number, XPAR_UARTNS550_ ## uart_number ## _DEVICE_ID , 0); } + +/** + * Return 1 if UART has at leas 1 byte in the RX FIFO + */ +#define UART_RXREADY(uart_number) \ + bool uart##uart_number##_rxready(void) \ + {return uart_rxready(&Uart##uart_number);} + +/** + * Receive a single byte. Polling mode, waits until finished + */ +#define UART_RXCHAR(uart_number) \ + uint8_t uart ## uart_number ## _rxchar(void) \ + { return uart_rxchar(&Uart##uart_number);} + +/** + * Transmit a single byte. Polling mode, waits until finished + */ +#define UART_TXCHAR(uart_number) \ + uint8_t uart##uart_number##_txchar(uint8_t c) \ + { return uart_txchar(&Uart##uart_number, c); } +/** + * Transmit a buffer. Waits indefinitely for a UART TX mutex, + * returns number of transferred bytes or -1 in case of an error. + * Synchronous API. + */ +#define UART_TXBUFFER(uart_number) \ + int uart##uart_number##_txbuffer(uint8_t *ptr, int len) \ + { return uart_txbuffer(&Uart##uart_number, ptr, len); } + + +#define UART_RXBUFFER(uart_number) \ + int uart##uart_number##_rxbuffer(uint8_t *ptr, int len) \ + { return uart_rxbuffer(&Uart##uart_number, ptr, len);} + + #if BSP_USE_UART0 bool uart0_rxready(void); -char uart0_rxchar(void); -char uart0_txchar(char c); -int uart0_rxbuffer(char *ptr, int len); -int uart0_txbuffer(char *ptr, int len); +uint8_t uart0_rxchar(void); +uint8_t uart0_txchar(uint8_t c); +int uart0_rxbuffer(uint8_t *ptr, int len); +int uart0_txbuffer(uint8_t *ptr, int len); void uart0_init(void); #endif #if BSP_USE_UART1 bool uart1_rxready(void); -char uart1_rxchar(void); -char uart1_txchar(char c); -int uart1_rxbuffer(char *ptr, int len); -int uart1_txbuffer(char *ptr, int len); +uint8_t uart1_rxuint8_t(void); +uint8_t uart1_txuint8_t(uint8_t c); +int uart1_rxbuffer(uint8_t *ptr, int len); +int uart1_txbuffer(uint8_t *ptr, int len); void uart1_init(void); #endif +#if BSP_USE_UART2 +bool uart2_rxready(void); +uint8_t uart2_rxuint8_t(void); +uint8_t uart2_txuint8_t(uint8_t c); +int uart2_rxbuffer(uint8_t *ptr, int len); +int uart2_txbuffer(uint8_t *ptr, int len); +void uart2_init(void); +#endif + #endif diff --git a/iveia/xilinx/uartns550/xuartns550_g.c b/iveia/xilinx/uartns550/xuartns550_g.c index 83a5943..8d4a633 100644 --- a/iveia/xilinx/uartns550/xuartns550_g.c +++ b/iveia/xilinx/uartns550/xuartns550_g.c @@ -83,6 +83,12 @@ XUartNs550_Config XUartNs550_ConfigTable[] = XPAR_UARTNS550_1_BASEADDR, XPAR_UARTNS550_1_CLOCK_HZ, XPAR_UARTNS550_1_BAUD_RATE - } + }, + { + XPAR_UARTNS550_2_DEVICE_ID, + XPAR_UARTNS550_2_BASEADDR, + XPAR_UARTNS550_2_CLOCK_HZ, + XPAR_UARTNS550_2_BAUD_RATE + } }; /** @} */ diff --git a/vcu118/Makefile b/vcu118/Makefile index 3184cfa..8146003 100644 --- a/vcu118/Makefile +++ b/vcu118/Makefile @@ -8,6 +8,7 @@ RISCV_ARCH ?= rv32ima RISCV_ABI ?= ilp32 CFLAGS += --target=riscv32-unknown-elf CFLAGS += -DCPU_CLOCK_HZ=50000000 +CFLAGS += -DRV32 else RISCV_ARCH ?= rv64imafd RISCV_ABI ?= lp64d @@ -15,13 +16,14 @@ RISCV_ABI ?= lp64d CFLAGS += --target=riscv64-unknown-elf CFLAGS += -mcmodel=medany CFLAGS += -DCPU_CLOCK_HZ=100000000 +CFLAGS += -DRV64 endif CFLAGS += -O0 -g3 -Wall -march=$(RISCV_ARCH) -mabi=$(RISCV_ABI) LIB_TARGET = libvcu118.a -CFLAGS += -I$(ISP_PREFIX)/include \ +CFLAGS += -I$(ISP_PREFIX)/include -I$(ISP_PREFIX)/vcu118_bsp \ -I$(BASE_DIR) \ -I$(BASE_DIR)/wrap \ -I$(BASE_DIR)/xilinx/common \ diff --git a/vcu118/boot.S b/vcu118/boot.S index d8fe6d1..c6b69c0 100644 --- a/vcu118/boot.S +++ b/vcu118/boot.S @@ -73,7 +73,8 @@ /* Startup code */ .globl boot boot: - li t6, 0x1800 + // enable MSTATUS_PRV1 and MSTATUS_MIE + li t6, 0x1888 csrw mstatus, t6 j _mstart diff --git a/vcu118/bsp.h b/vcu118/bsp.h deleted file mode 100644 index b95f7a8..0000000 --- a/vcu118/bsp.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef RISCV_P1_BSP_H -#define RISCV_P1_BSP_H - -#ifndef CPU_CLOCK_HZ -#define CPU_CLOCK_HZ 100000000 -#endif - -/** - * UART defines - */ -#define XPAR_XUARTNS550_NUM_INSTANCES 2 -#define XPAR_DEFAULT_BAUD_RATE 115200 - -#define BSP_USE_UART0 1 -#define XPAR_UARTNS550_0_DEVICE_ID 0 -#define XPAR_UARTNS550_0_BAUD_RATE XPAR_DEFAULT_BAUD_RATE -#define XPAR_UARTNS550_0_BASEADDR 0x62300000ULL -#define XPAR_UARTNS550_0_CLOCK_HZ CPU_CLOCK_HZ - -// UART1 is in use by the PEX, so avoid re-initializing it on the AP -#define BSP_USE_UART1 0 -#define XPAR_UARTNS550_1_DEVICE_ID 1 -#define XPAR_UARTNS550_1_BAUD_RATE XPAR_DEFAULT_BAUD_RATE -#define XPAR_UARTNS550_1_BASEADDR (0x62340000ULL) -#define XPAR_UARTNS550_1_CLOCK_HZ CPU_CLOCK_HZ - -#endif /* RISCV_P1_BSP_H */ diff --git a/vcu118/init.c b/vcu118/init.c index a16f508..62b0402 100644 --- a/vcu118/init.c +++ b/vcu118/init.c @@ -3,12 +3,30 @@ extern int main(void); +#define write_csr(reg, val) \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)) + +#define read_csr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +void bad_trap(){ + unsigned long mepc, mtval, mcause; + asm volatile("csrr %0, mcause" : "=r"(mcause)); + asm volatile("csrr %0, mtval" : "=r"(mtval)); + asm volatile("csrr %0, mepc" : "=r"(mepc)); + printf("\n BAD TRAP: \n mcause=0x%lx\n, mepc=0x%lx \n, mtval=0x%lx \n", mcause, mepc, mtval); +} + void _init(void) { int result; uart0_init(); + // set up a bad trap handler + write_csr(mtvec, ((uintptr_t)&bad_trap)); + // set up floating point computation uintptr_t misa, mstatus; asm volatile("csrr %0, misa" : "=r"(misa));