From d0f7bd44867fb47aa35e4df1695d8789586517fb Mon Sep 17 00:00:00 2001 From: Mattia Sinigaglia Date: Sat, 5 Aug 2023 14:31:57 +0200 Subject: [PATCH] treewide: Add carfield-related modifications --- hw/system/spatz_cluster/Makefile | 23 +++++++--- hw/system/spatz_cluster/cfg/carfield.hjson | 9 ++-- .../spatz_cluster_peripheral_reg.hjson | 12 ++++++ .../spatz_cluster_peripheral_reg_pkg.sv | 32 ++++++++------ .../spatz_cluster_peripheral_reg_top.sv | 43 ++++++++++++++++++- hw/system/spatz_cluster/tb/testbench.sv.tpl | 4 +- hw/system/spatz_cluster/test/bootrom.S | 17 +++++--- sw/snRuntime/CMakeLists.txt | 39 +++++++++++++++-- .../include/spatz_cluster_peripheral.h | 9 ++++ sw/snRuntime/src/interrupt.c | 1 + sw/snRuntime/src/platforms/rtl/putchar.c.in | 39 +++++++++++++++++ .../src/platforms/standalone/putchar.c | 26 +++++------ .../src/platforms/standalone/start_snitch.S | 19 ++++++++ 13 files changed, 227 insertions(+), 46 deletions(-) create mode 100644 sw/snRuntime/src/platforms/rtl/putchar.c.in diff --git a/hw/system/spatz_cluster/Makefile b/hw/system/spatz_cluster/Makefile index 9977422c..04e165b4 100644 --- a/hw/system/spatz_cluster/Makefile +++ b/hw/system/spatz_cluster/Makefile @@ -3,6 +3,7 @@ # SPDX-License-Identifier: SHL-0.51 # Author: Matheus Cavalcante, ETH Zurich +# Author: Mattia Sinigaglia, University of Bologna SPATZ_DIR := $(shell git rev-parse --show-toplevel 2>/dev/null || echo $$SPATZ_DIR) ROOT := ${SPATZ_DIR} @@ -12,6 +13,15 @@ MKFILE_DIR := $(dir $(MKFILE_PATH)) # Configuration file SPATZ_CLUSTER_CFG ?= $(SPATZ_CLUSTER_DIR)/cfg/spatz_cluster.default.hjson +SPATZ_CFG_NAME_SPLIT := $(subst /, ,$(SPATZ_CLUSTER_CFG)) +SPATZ_CFG_FILENAME:= $(word $(words $(SPATZ_CFG_NAME_SPLIT)), $(SPATZ_CFG_NAME_SPLIT)) + +# Putchar utilization +# The Standalone cluster uses the Host-Target Interface HTIF for printing messages +# When the spatz cluster is integrated within an SoC, the HTIF could not be available and the regression test get stuck on the putchar function because of the missing comunication between the clients +# When the HTIF is not available, set the following param to "NO" + +HTIF_SERVER ?= YES # Include Makefrag include $(ROOT)/util/Makefrag @@ -129,7 +139,7 @@ bin/spatz_cluster.vsim: ${VSIM_BUILDDIR}/compile.vsim.tcl work/lib/libfesvr_vsim $(call QUESTASIM,tb_bin) clean.vsim: - rm -rf bin/spatz_cluster.vsim bin/spatz_cluster.vsim.gui work-vsim work vsim.wlf vish_stacktrace.vstf transcript + rm -rf bin/spatz_cluster.vsim bin/spatz_cluster.vsim.gui work-vsim work vsim.wlf vish_stacktrace.vstf transcript src/generated/ ####### # VCS # @@ -167,13 +177,14 @@ lint/tmp/files: ${BENDER} ## Build SW into sw/build with the LLVM toolchain sw: clean.sw mkdir -p sw/build - cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DPYTHON=${PYTHON} .. && make + cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DHTIF_SERVER=${HTIF_SERVER}-DSPATZ_CFG_FILENAME=${SPATZ_CFG_FILENAME} -DPYTHON=${PYTHON} .. && make # VSIM ## Build SW into sw/build with the LLVM toolchain (including tests) for Questasim simulator sw.vsim: clean.sw bin/spatz_cluster.vsim mkdir -p sw/build - cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vsim -DBUILD_TESTS=ON .. && make -j8 + cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DHTIF_SERVER=${HTIF_SERVER} -DSPATZ_CFG_FILENAME=${SPATZ_CFG_FILENAME} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vsim -DBUILD_TESTS=ON .. && make -j8 + echo -e "\033[31m ***IMPORTANT*** SW compilation has done for the following config file: "$(SPATZ_CFG_FILENAME) ## Build SW and run all tests with Questasim simulator sw.test.vsim: sw.vsim @@ -183,7 +194,8 @@ sw.test.vsim: sw.vsim ## Build SW into sw/build with the LLVM toolchain (including tests) for VCS simulator sw.vcs: clean.sw bin/spatz_cluster.vcs mkdir -p sw/build - cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vcs -DBUILD_TESTS=ON .. && make -j8 + cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DHTIF_SERVER=${HTIF_SERVER} -DSPATZ_CFG_FILENAME=${SPATZ_CFG_FILENAME} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vcs -DBUILD_TESTS=ON .. && make -j8 + echo -e "\033[31m ***IMPORTANT*** SW compilation has done for the following config file: "$(SPATZ_CFG_FILENAME) ## Build SW and run all tests with VCS simulator sw.test.vcs: sw.vcs @@ -193,7 +205,8 @@ sw.test.vcs: sw.vcs ## Build SW into sw/build with the LLVM toolchain (including tests) for Verilator simulator sw.vlt: clean.sw bin/spatz_cluster.vlt mkdir -p sw/build - cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vlt -DBUILD_TESTS=ON .. && make -j8 + cd sw/build && ${CMAKE} -DLLVM_PATH=${LLVM_INSTALL_DIR} -DGCC_PATH=${GCC_INSTALL_DIR} -DHTIF_SERVER=${HTIF_SERVER} -DSPATZ_CFG_FILENAME=${SPATZ_CFG_FILENAME} -DPYTHON=${PYTHON} -DSNITCH_SIMULATOR=../../../../../hw/system/spatz_cluster/bin/spatz_cluster.vlt -DBUILD_TESTS=ON .. && make -j8 + echo -e "\033[31m ***IMPORTANT*** SW compilation has done for the following config file: "$(SPATZ_CFG_FILENAME) ## Build SW and run all tests with Verilator simulator sw.test.vlt: sw.vlt diff --git a/hw/system/spatz_cluster/cfg/carfield.hjson b/hw/system/spatz_cluster/cfg/carfield.hjson index 8faca6dc..9d830377 100644 --- a/hw/system/spatz_cluster/cfg/carfield.hjson +++ b/hw/system/spatz_cluster/cfg/carfield.hjson @@ -61,11 +61,12 @@ } } + //L2 Carfield dram: { - // 0x8000_0000 - address: 2147483648, - // 0x8000_0000 - length: 2147483648 + // 0x78000000 + address: 2013265920, + // 0x400000 + length: 4194304 }, peripherals: { }, diff --git a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg.hjson b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg.hjson index c96f5ed8..a722ddeb 100644 --- a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg.hjson +++ b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg.hjson @@ -426,6 +426,18 @@ name: "ENTRY_POINT", desc: "Post-bootstrapping entry point." }] + }, + { + name: "CLUSTER_EOC_EXIT", + desc: '''End of computation and exit status register''' + swaccess: "rw", + hwaccess: "hro", + resval: "0", + fields: [{ + bits: "31:0", + name: "EOC_EXIT", + desc: "Indicates the end of computation and exit status." + }] } ] } diff --git a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_pkg.sv b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_pkg.sv index 1ae776d5..0272383c 100644 --- a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_pkg.sv +++ b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_pkg.sv @@ -147,6 +147,10 @@ package spatz_cluster_peripheral_reg_pkg; logic [31:0] q; } spatz_cluster_peripheral_reg2hw_cluster_boot_control_reg_t; + typedef struct packed { + logic [31:0] q; + } spatz_cluster_peripheral_reg2hw_cluster_eoc_exit_reg_t; + typedef struct packed { logic [47:0] d; } spatz_cluster_peripheral_hw2reg_perf_counter_mreg_t; @@ -157,15 +161,16 @@ package spatz_cluster_peripheral_reg_pkg; // Register -> HW type typedef struct packed { - spatz_cluster_peripheral_reg2hw_perf_counter_enable_mreg_t [1:0] perf_counter_enable; // [311:250] - spatz_cluster_peripheral_reg2hw_hart_select_mreg_t [1:0] hart_select; // [249:230] - spatz_cluster_peripheral_reg2hw_perf_counter_mreg_t [1:0] perf_counter; // [229:132] - spatz_cluster_peripheral_reg2hw_cl_clint_set_reg_t cl_clint_set; // [131:99] - spatz_cluster_peripheral_reg2hw_cl_clint_clear_reg_t cl_clint_clear; // [98:66] - spatz_cluster_peripheral_reg2hw_hw_barrier_reg_t hw_barrier; // [65:34] - spatz_cluster_peripheral_reg2hw_icache_prefetch_enable_reg_t icache_prefetch_enable; // [33:33] - spatz_cluster_peripheral_reg2hw_spatz_status_reg_t spatz_status; // [32:32] - spatz_cluster_peripheral_reg2hw_cluster_boot_control_reg_t cluster_boot_control; // [31:0] + spatz_cluster_peripheral_reg2hw_perf_counter_enable_mreg_t [1:0] perf_counter_enable; // [343:282] + spatz_cluster_peripheral_reg2hw_hart_select_mreg_t [1:0] hart_select; // [281:262] + spatz_cluster_peripheral_reg2hw_perf_counter_mreg_t [1:0] perf_counter; // [261:164] + spatz_cluster_peripheral_reg2hw_cl_clint_set_reg_t cl_clint_set; // [163:131] + spatz_cluster_peripheral_reg2hw_cl_clint_clear_reg_t cl_clint_clear; // [130:98] + spatz_cluster_peripheral_reg2hw_hw_barrier_reg_t hw_barrier; // [97:66] + spatz_cluster_peripheral_reg2hw_icache_prefetch_enable_reg_t icache_prefetch_enable; // [65:65] + spatz_cluster_peripheral_reg2hw_spatz_status_reg_t spatz_status; // [64:64] + spatz_cluster_peripheral_reg2hw_cluster_boot_control_reg_t cluster_boot_control; // [63:32] + spatz_cluster_peripheral_reg2hw_cluster_eoc_exit_reg_t cluster_eoc_exit; // [31:0] } spatz_cluster_peripheral_reg2hw_t; // HW -> register type @@ -187,6 +192,7 @@ package spatz_cluster_peripheral_reg_pkg; parameter logic [BlockAw-1:0] SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET = 7'h 48; parameter logic [BlockAw-1:0] SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS_OFFSET = 7'h 50; parameter logic [BlockAw-1:0] SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_OFFSET = 7'h 58; + parameter logic [BlockAw-1:0] SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_OFFSET = 7'h 60; // Reset values for hwext registers and their fields parameter logic [47:0] SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_0_RESVAL = 48'h 0; @@ -208,11 +214,12 @@ package spatz_cluster_peripheral_reg_pkg; SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER, SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE, SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS, - SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL, + SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT } spatz_cluster_peripheral_id_e; // Register width information to check illegal writes - parameter logic [3:0] SPATZ_CLUSTER_PERIPHERAL_PERMIT [12] = '{ + parameter logic [3:0] SPATZ_CLUSTER_PERIPHERAL_PERMIT [13] = '{ 4'b 1111, // index[ 0] SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0 4'b 1111, // index[ 1] SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_1 4'b 0011, // index[ 2] SPATZ_CLUSTER_PERIPHERAL_HART_SELECT_0 @@ -224,7 +231,8 @@ package spatz_cluster_peripheral_reg_pkg; 4'b 1111, // index[ 8] SPATZ_CLUSTER_PERIPHERAL_HW_BARRIER 4'b 0001, // index[ 9] SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE 4'b 0001, // index[10] SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS - 4'b 1111 // index[11] SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL + 4'b 1111, // index[11] SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL + 4'b 1111 // index[12] SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT }; endpackage diff --git a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_top.sv b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_top.sv index b5cf96a4..72d31f69 100644 --- a/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_top.sv +++ b/hw/system/spatz_cluster/src/spatz_cluster_peripheral/spatz_cluster_peripheral_reg_top.sv @@ -281,6 +281,9 @@ module spatz_cluster_peripheral_reg_top #( logic [31:0] cluster_boot_control_qs; logic [31:0] cluster_boot_control_wd; logic cluster_boot_control_we; + logic [31:0] cluster_eoc_exit_qs; + logic [31:0] cluster_eoc_exit_wd; + logic cluster_eoc_exit_we; // Register instances @@ -2120,9 +2123,36 @@ module spatz_cluster_peripheral_reg_top #( ); + // R[cluster_eoc_exit]: V(False) + prim_subreg #( + .DW (32), + .SWACCESS("RW"), + .RESVAL (32'h0) + ) u_cluster_eoc_exit ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (cluster_eoc_exit_we), + .wd (cluster_eoc_exit_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), - logic [11:0] addr_hit; + // to internal hardware + .qe (), + .q (reg2hw.cluster_eoc_exit.q ), + + // to register interface (read) + .qs (cluster_eoc_exit_qs) + ); + + + + + logic [12:0] addr_hit; always_comb begin addr_hit = '0; addr_hit[ 0] = (reg_addr == SPATZ_CLUSTER_PERIPHERAL_PERF_COUNTER_ENABLE_0_OFFSET); @@ -2137,6 +2167,7 @@ module spatz_cluster_peripheral_reg_top #( addr_hit[ 9] = (reg_addr == SPATZ_CLUSTER_PERIPHERAL_ICACHE_PREFETCH_ENABLE_OFFSET); addr_hit[10] = (reg_addr == SPATZ_CLUSTER_PERIPHERAL_SPATZ_STATUS_OFFSET); addr_hit[11] = (reg_addr == SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_OFFSET); + addr_hit[12] = (reg_addr == SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_OFFSET); end assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; @@ -2155,7 +2186,8 @@ module spatz_cluster_peripheral_reg_top #( (addr_hit[ 8] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[ 8] & ~reg_be))) | (addr_hit[ 9] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[ 9] & ~reg_be))) | (addr_hit[10] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[11] & ~reg_be))))); + (addr_hit[11] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(SPATZ_CLUSTER_PERIPHERAL_PERMIT[12] & ~reg_be))))); end assign perf_counter_enable_0_cycle_0_we = addr_hit[0] & reg_we & !reg_error; @@ -2375,6 +2407,9 @@ module spatz_cluster_peripheral_reg_top #( assign cluster_boot_control_we = addr_hit[11] & reg_we & !reg_error; assign cluster_boot_control_wd = reg_wdata[31:0]; + assign cluster_eoc_exit_we = addr_hit[12] & reg_we & !reg_error; + assign cluster_eoc_exit_wd = reg_wdata[31:0]; + // Read data return always_comb begin reg_rdata_next = '0; @@ -2487,6 +2522,10 @@ module spatz_cluster_peripheral_reg_top #( reg_rdata_next[31:0] = cluster_boot_control_qs; end + addr_hit[12]: begin + reg_rdata_next[31:0] = cluster_eoc_exit_qs; + end + default: begin reg_rdata_next = '1; end diff --git a/hw/system/spatz_cluster/tb/testbench.sv.tpl b/hw/system/spatz_cluster/tb/testbench.sv.tpl index 550e698e..a0802cce 100644 --- a/hw/system/spatz_cluster/tb/testbench.sv.tpl +++ b/hw/system/spatz_cluster/tb/testbench.sv.tpl @@ -162,10 +162,10 @@ module testharness ( .clk_i (clk_i ), .rst_ni (rst_ni ), .meip_i ('0 ), - .msip_i ('0 ), + .msip_i ( debug_req ), .mtip_i ('0 ), % if cfg['enable_debug']: - .debug_req_i ( debug_req ), + .debug_req_i ( '0 ), % endif % if cfg['axi_cdc_enable']: % if cfg['sw_rst_enable']: diff --git a/hw/system/spatz_cluster/test/bootrom.S b/hw/system/spatz_cluster/test/bootrom.S index 726ea13a..e7297ece 100644 --- a/hw/system/spatz_cluster/test/bootrom.S +++ b/hw/system/spatz_cluster/test/bootrom.S @@ -8,10 +8,14 @@ .global BOOTDATA _start: - la t1, exception + la t1, __snrt_isr csrw mtvec, t1 csrr a0, mhartid la a1, BOOTDATA + // Enable MSIP interrupt + csrr a2, mie + ori a2, a2, 0x8 + csrw mie, a2 // Wait for the wakeup interrupt wfi @@ -32,10 +36,13 @@ _start: // Jump to the entry point jr t2 -exception: - wfi - j exception +#exception: +# wfi +# j exception + +__snrt_isr: + j __snrt_isr .pushsection .boot_section,"aw",@progbits; entry_addr: - .word exception + .word __snrt_isr diff --git a/sw/snRuntime/CMakeLists.txt b/sw/snRuntime/CMakeLists.txt index 1603f5f5..7382708c 100644 --- a/sw/snRuntime/CMakeLists.txt +++ b/sw/snRuntime/CMakeLists.txt @@ -26,15 +26,46 @@ add_compile_options(-O3 -g -ffunction-sections) # Default memory regions if(SNITCH_RUNTIME STREQUAL "snRuntime-cluster") - set(MEM_DRAM_ORIGIN "0x80000000" CACHE STRING "Base address of external memory") - set(MEM_DRAM_SIZE "0x80000000" CACHE STRING "Size of external memory") + if(${SPATZ_CFG_FILENAME} STREQUAL spatz_cluster.default.hjson) + set(MEM_DRAM_ORIGIN "0x80000000" CACHE STRING "Base address of external memory") + set(MEM_DRAM_SIZE "0x80000000" CACHE STRING "Size of external memory") + + set(MEM_TCDM_ORIGIN "0x100000" CACHE STRING "Base address of TCDM memory") + set(MEM_TCDM_SIZE "0x20000" CACHE STRING "Size of TCDM memory") + + else(${SPATZ_CFG_FILENAME} STREQUAL carfield.hjson) + set(MEM_DRAM_ORIGIN "0x78000000" CACHE STRING "Base address of external memory") + set(MEM_DRAM_SIZE "0x400000" CACHE STRING "Size of external memory") + + set(MEM_TCDM_ORIGIN "0x51000000" CACHE STRING "Base address of TCDM memory") + set(MEM_TCDM_SIZE "0x20000" CACHE STRING "Size of TCDM memory") + endif() else() - set(MEM_DRAM_ORIGIN "0x80000000" CACHE STRING "Base address of external memory") - set(MEM_DRAM_SIZE "256M" CACHE STRING "Size of external memory") + if(${SPATZ_CFG_FILENAME} STREQUAL spatz_cluster.default.hjson) + set(MEM_DRAM_ORIGIN "0x80000000" CACHE STRING "Base address of external memory") + set(MEM_DRAM_SIZE "256M" CACHE STRING "Size of external memory") + else(${SPATZ_CFG_FILENAME} STREQUAL carfield.hjson) + set(MEM_DRAM_ORIGIN "0x78000000" CACHE STRING "Base address of external memory") + set(MEM_DRAM_SIZE "128M" CACHE STRING "Size of external memory") + endif() + endif() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/link/common.ld.in common.ld @ONLY) set(LINKER_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/common.ld CACHE PATH "") +# Start Snitch +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/rtl/start_snitch.S.in ${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/rtl/start_snitch.S @ONLY) +set(START_SNITCH ${CMAKE_CURRENT_BINARY_DIR}/src/platforms/rtl/start_snitch.S CACHE PATH "") + +# Patch putchar +if(${HTIF_SERVER} STREQUAL "YES") + set(HTIF_SERVER "1") +else() + set(HTIF_SERVER "0") +endif() +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/rtl/putchar.c.in ${CMAKE_CURRENT_SOURCE_DIR}/src/platforms/rtl/putchar.c @ONLY) + # provide linker script # set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/link/common.ld" CACHE PATH "") message(STATUS "Using common linker script: ${LINKER_SCRIPT}") diff --git a/sw/snRuntime/include/spatz_cluster_peripheral.h b/sw/snRuntime/include/spatz_cluster_peripheral.h index aef4ceaf..981d24c7 100644 --- a/sw/snRuntime/include/spatz_cluster_peripheral.h +++ b/sw/snRuntime/include/spatz_cluster_peripheral.h @@ -192,6 +192,15 @@ extern "C" { .index = \ SPATZ_CLUSTER_PERIPHERAL_CLUSTER_BOOT_CONTROL_ENTRY_POINT_OFFSET}) +// End of computation and exit status register +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_REG_OFFSET 0x60 +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_EOC_EXIT_MASK 0xffffffff +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_EOC_EXIT_OFFSET 0 +#define SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_EOC_EXIT_FIELD \ + ((bitfield_field32_t){ \ + .mask = SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_EOC_EXIT_MASK, \ + .index = SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_EOC_EXIT_OFFSET}) + #ifdef __cplusplus } // extern "C" #endif diff --git a/sw/snRuntime/src/interrupt.c b/sw/snRuntime/src/interrupt.c index 3c2f04e2..34a494d8 100644 --- a/sw/snRuntime/src/interrupt.c +++ b/sw/snRuntime/src/interrupt.c @@ -66,6 +66,7 @@ void __snrt_isr(void) { irq_m_cluster(core_idx); break; } + // enable interrupts } else { // exceptions not handled, halt while (1) diff --git a/sw/snRuntime/src/platforms/rtl/putchar.c.in b/sw/snRuntime/src/platforms/rtl/putchar.c.in new file mode 100644 index 00000000..d71b658e --- /dev/null +++ b/sw/snRuntime/src/platforms/rtl/putchar.c.in @@ -0,0 +1,39 @@ +// Copyright 2020 ETH Zurich and University of Bologna. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +#include "snrt.h" + +extern uintptr_t volatile tohost, fromhost; + +// Rudimentary string buffer for putc calls. +extern uint32_t _edram; +#define PUTC_BUFFER_LEN (1024 - sizeof(size_t)) +struct putc_buffer_header { + size_t size; + uint64_t syscall_mem[8]; +}; +static volatile struct putc_buffer { + struct putc_buffer_header hdr; + char data[PUTC_BUFFER_LEN]; +} *const putc_buffer = (void *)&_edram; + +// Provide an implementation for putchar. +void snrt_putchar(char character) { + if (@HTIF_SERVER@ == 1){ + volatile struct putc_buffer *buf = &putc_buffer[snrt_hartid()]; + buf->data[buf->hdr.size++] = character; + if (buf->hdr.size == PUTC_BUFFER_LEN || character == '\n') { + buf->hdr.syscall_mem[0] = 64; // sys_write + buf->hdr.syscall_mem[1] = 1; // file descriptor (1 = stdout) + buf->hdr.syscall_mem[2] = (uintptr_t)&buf->data; // buffer + buf->hdr.syscall_mem[3] = buf->hdr.size; // length + + tohost = (uintptr_t)buf->hdr.syscall_mem; + while (fromhost == 0) + ; + fromhost = 0; + + buf->hdr.size = 0; + } + } +} \ No newline at end of file diff --git a/sw/snRuntime/src/platforms/standalone/putchar.c b/sw/snRuntime/src/platforms/standalone/putchar.c index be8db6f4..eff127f4 100644 --- a/sw/snRuntime/src/platforms/standalone/putchar.c +++ b/sw/snRuntime/src/platforms/standalone/putchar.c @@ -19,19 +19,21 @@ static volatile struct putc_buffer { // Provide an implementation for putchar. void snrt_putchar(char character) { - volatile struct putc_buffer *buf = &putc_buffer[snrt_hartid()]; - buf->data[buf->hdr.size++] = character; - if (buf->hdr.size == PUTC_BUFFER_LEN || character == '\n') { - buf->hdr.syscall_mem[0] = 64; // sys_write - buf->hdr.syscall_mem[1] = 1; // file descriptor (1 = stdout) - buf->hdr.syscall_mem[2] = (uintptr_t)&buf->data; // buffer - buf->hdr.syscall_mem[3] = buf->hdr.size; // length + if (@HTIF_SERVER@ == 1){ + volatile struct putc_buffer *buf = &putc_buffer[snrt_hartid()]; + buf->data[buf->hdr.size++] = character; + if (buf->hdr.size == PUTC_BUFFER_LEN || character == '\n') { + buf->hdr.syscall_mem[0] = 64; // sys_write + buf->hdr.syscall_mem[1] = 1; // file descriptor (1 = stdout) + buf->hdr.syscall_mem[2] = (uintptr_t)&buf->data; // buffer + buf->hdr.syscall_mem[3] = buf->hdr.size; // length - tohost = (uintptr_t)buf->hdr.syscall_mem; - while (fromhost == 0) - ; - fromhost = 0; + tohost = (uintptr_t)buf->hdr.syscall_mem; + while (fromhost == 0) + ; + fromhost = 0; - buf->hdr.size = 0; + buf->hdr.size = 0; + } } } diff --git a/sw/snRuntime/src/platforms/standalone/start_snitch.S b/sw/snRuntime/src/platforms/standalone/start_snitch.S index 47be6baf..e40332a1 100644 --- a/sw/snRuntime/src/platforms/standalone/start_snitch.S +++ b/sw/snRuntime/src/platforms/standalone/start_snitch.S @@ -4,6 +4,10 @@ #include "../shared/start_snitch.S" +#include + +//.global BOOTDATA + # Function to terminate execution. # # Expecting: @@ -27,6 +31,21 @@ _snrt_exit: bnez a0, 1f slli t0, t0, 1 ori t0, t0, 1 + + # Load the start address and size of the TCDM + li t1, @MEM_TCDM_ORIGIN@ + li t2, @MEM_TCDM_SIZE@ + + # Final address of the TCDM + add t1, t1, t2 + + # Address of the EOC register + addi t1, t1, SPATZ_CLUSTER_PERIPHERAL_CLUSTER_EOC_EXIT_REG_OFFSET + + # Return to EOC register + sw t0, 0(t1) + + # Return to HTIF la t1, tohost sw t0, 0(t1) 1: ret