diff --git a/.gitignore b/.gitignore index 4c8e9b871..88f0b384a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,13 @@ target/xilinx/build target/xilinx/out target/xilinx/scripts/add_sources.* vivado* + +# Bender lock +Bender.lock + +# Emacs undo-tree files +*undo-tree* + +# Temp files +*~ +*# \ No newline at end of file diff --git a/cheshire.mk b/cheshire.mk index d0b25a0bd..82b42cada 100644 --- a/cheshire.mk +++ b/cheshire.mk @@ -160,6 +160,13 @@ $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.sv: $(CHS_ROOT)/hw/bootrom/cheshire_boot CHS_BOOTROM_ALL += $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.sv $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.dump +.PHONY: chs_bootrom_clean + +chs_bootrom_clean: + rm -f $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.sv + rm -f $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.elf + rm -f $(CHS_ROOT)/hw/bootrom/cheshire_bootrom.bin + ############## # Simulation # ############## @@ -216,7 +223,7 @@ CHS_ALL += $(CHS_SW_ALL) $(CHS_HW_ALL) $(CHS_SIM_ALL) chs-all: $(CHS_ALL) chs-sw-all: $(CHS_SW_ALL) chs-hw-all: $(CHS_HW_ALL) -chs-bootrom-all: $(CHS_BOOTROM_ALL) +chs-bootrom-all: chs_bootrom_clean $(CHS_BOOTROM_ALL) chs-sim-all: $(CHS_SIM_ALL) chs-dramsys-all: $(CHS_DRAMSYS_ALL) chs-xilinx-all: $(CHS_XILINX_ALL) diff --git a/hw/bootrom/cheshire_bootrom.S b/hw/bootrom/cheshire_bootrom.S index 676041d6b..0589ae121 100644 --- a/hw/bootrom/cheshire_bootrom.S +++ b/hw/bootrom/cheshire_bootrom.S @@ -113,17 +113,23 @@ boot_next_stage: // Non-SMP hart: Write boot address into global scratch registers la t0, __regs_base_addr__ sw a0, 16(t0) // regs.SCRATCH[4] +#if XLEN==64 srli a0, a0, 32 sw a0, 20(t0) // regs.SCRATCH[5] +#endif fence // Resume SMP harts smp_resume(t0, t1, t2) // Load boot address from global scratch registers la t0, __regs_base_addr__ +#if XLEN==64 lwu t1, 20(t0) // regs.SCRATCH[5] slli t1, t1, 32 +#endif lwu t0, 16(t0) // regs.SCRATCH[4] +#if XLEN==64 or t0, t0, t1 +#endif // Store hartid to a0 csrr a0, mhartid // Jump to boot address diff --git a/hw/bootrom/cheshire_bootrom.ld b/hw/bootrom/cheshire_bootrom.ld index c422c3c1e..fcdd3d9da 100644 --- a/hw/bootrom/cheshire_bootrom.ld +++ b/hw/bootrom/cheshire_bootrom.ld @@ -9,7 +9,7 @@ INCLUDE common.ldh SECTIONS { - __stack_pointer$ = ORIGIN(spm) + LENGTH(spm) - 8; + __stack_pointer$ = __stack_start - 8; .text : { *(.text._start) diff --git a/hw/cheshire_addrmap_pkg.sv b/hw/cheshire_addrmap_pkg.sv index 41eb7cfb2..a3e60bee4 100644 --- a/hw/cheshire_addrmap_pkg.sv +++ b/hw/cheshire_addrmap_pkg.sv @@ -160,4 +160,4 @@ typedef enum logic [1:0] { I2C_24XX1025 = 2'd3 } BootMode_e; -endpackage; +endpackage diff --git a/hw/cheshire_idma_wrap.sv b/hw/cheshire_idma_wrap.sv index c101874f1..8ef581ae3 100644 --- a/hw/cheshire_idma_wrap.sv +++ b/hw/cheshire_idma_wrap.sv @@ -9,20 +9,26 @@ /// DMA core wrapper for the integration into Cheshire. module cheshire_idma_wrap #( - parameter int unsigned AxiAddrWidth = 0, - parameter int unsigned AxiDataWidth = 0, - parameter int unsigned AxiIdWidth = 0, - parameter int unsigned AxiUserWidth = 0, - parameter int unsigned AxiSlvIdWidth = 0, - parameter int unsigned NumAxInFlight = 0, - parameter int unsigned MemSysDepth = 0, - parameter int unsigned JobFifoDepth = 0, - parameter bit RAWCouplingAvail = 0, - parameter bit IsTwoD = 0, - parameter type axi_mst_req_t = logic, - parameter type axi_mst_rsp_t = logic, - parameter type axi_slv_req_t = logic, - parameter type axi_slv_rsp_t = logic + parameter int unsigned AxiAddrWidth = 0, + parameter int unsigned AxiDataWidth = 0, + parameter int unsigned AxiIdWidth = 0, + parameter int unsigned AxiUserWidth = 0, + parameter int unsigned AxiSlvIdWidth = 0, + parameter int unsigned NumAxInFlight = 0, + parameter int unsigned MemSysDepth = 0, + parameter int unsigned JobFifoDepth = 0, + parameter bit EnableAxiCut = 1'b1, + parameter bit RAWCouplingAvail = 0, + parameter bit IsTwoD = 0, + parameter type axi_mst_aw_chan_t = logic, + parameter type axi_mst_ar_chan_t = logic, + parameter type axi_mst_w_chan_t = logic, + parameter type axi_mst_r_chan_t = logic, + parameter type axi_mst_b_chan_t = logic, + parameter type axi_mst_req_t = logic, + parameter type axi_mst_rsp_t = logic, + parameter type axi_slv_req_t = logic, + parameter type axi_slv_rsp_t = logic ) ( input logic clk_i, input logic rst_ni, @@ -119,8 +125,8 @@ module cheshire_idma_wrap #( logic me_busy; // Internal AXI channels - axi_mst_req_t axi_read_req, axi_write_req; - axi_mst_rsp_t axi_read_rsp, axi_write_rsp; + axi_mst_req_t axi_read_req, axi_write_req, axi_cut_req; + axi_mst_rsp_t axi_read_rsp, axi_write_rsp, axi_cut_rsp; axi_to_reg_v2 #( .AxiAddrWidth ( AxiAddrWidth ), @@ -337,8 +343,26 @@ module cheshire_idma_wrap #( .slv_read_resp_o ( axi_read_rsp ), .slv_write_req_i ( axi_write_req ), .slv_write_resp_o ( axi_write_rsp ), - .mst_req_o ( axi_mst_req_o ), - .mst_resp_i ( axi_mst_rsp_i ) + .mst_req_o ( axi_cut_req ), + .mst_resp_i ( axi_cut_rsp ) + ); + + axi_cut #( + .Bypass ( ~EnableAxiCut ), + .aw_chan_t ( axi_mst_aw_chan_t ), + .w_chan_t ( axi_mst_w_chan_t ), + .b_chan_t ( axi_mst_b_chan_t ), + .ar_chan_t ( axi_mst_ar_chan_t ), + .r_chan_t ( axi_mst_r_chan_t ), + .axi_req_t ( axi_mst_req_t ), + .axi_resp_t ( axi_mst_rsp_t ) + ) i_axi_cut ( + .clk_i, + .rst_ni, + .slv_req_i ( axi_cut_req ), + .slv_resp_o ( axi_cut_rsp ), + .mst_req_o ( axi_mst_req_o ), + .mst_resp_i ( axi_mst_rsp_i ) ); endmodule diff --git a/hw/cheshire_pkg.sv b/hw/cheshire_pkg.sv index c595c5b8e..2e7c70a1e 100644 --- a/hw/cheshire_pkg.sv +++ b/hw/cheshire_pkg.sv @@ -95,6 +95,8 @@ package cheshire_pkg; dw_bt AxiDataWidth; dw_bt AxiUserWidth; aw_bt AxiMstIdWidth; + aw_bt TFLenWidth; + aw_bt AxiSlvIdWidth; dw_bt AxiMaxMstTrans; dw_bt AxiMaxSlvTrans; // User signals identify atomics masters. @@ -117,6 +119,9 @@ package cheshire_pkg; byte_bt [2**MaxExtAxiSlvWidth-1:0] AxiExtRegionIdx; doub_bt [2**MaxExtAxiSlvWidth-1:0] AxiExtRegionStart; doub_bt [2**MaxExtAxiSlvWidth-1:0] AxiExtRegionEnd; + // External Wide AXI ports (limited number of ports and rules) + bit [MaxExtAxiMstWidth-1:0] AxiExtNumWideMst; + bit [MaxExtAxiSlvWidth-1:0] AxiExtNumWideSlv; // External reg slaves (limited number of ports and rules) bit [MaxExtRegSlvWidth-1:0] RegExtNumSlv; bit [MaxExtRegSlvWidth-1:0] RegExtNumRules; @@ -438,7 +443,7 @@ package cheshire_pkg; // Set APB mask for all reg-bus ports whose IP uses an APB4-flat interface ret.apb_mask = '0; ret.apb_mask[ret.regs] = 1'b1; - ret.apb_mask[ret.slink] = 1'b1; + if (cfg.SerialLink) begin ret.apb_mask[ret.slink] = 1'b1; end return ret; endfunction @@ -557,6 +562,8 @@ package cheshire_pkg; AxiDataWidth : 64, AxiUserWidth : 2, // AMO(2) AxiMstIdWidth : 2, + TFLenWidth : 32, + AxiSlvIdWidth : 3, AxiMaxMstTrans : 24, AxiMaxSlvTrans : 24, AxiUserAmoMsb : 1, // Convention: lower AMO bits for cores, MSB for serial link diff --git a/hw/cheshire_soc.sv b/hw/cheshire_soc.sv index 526c7bd4b..bb9747709 100644 --- a/hw/cheshire_soc.sv +++ b/hw/cheshire_soc.sv @@ -118,6 +118,9 @@ module cheshire_soc import cheshire_pkg::*; #( import cheshire_addrmap_pkg::*; + localparam int unsigned RiscvWordWidth = riscv::XLEN; + + ////////////////// // Interrupts // ////////////////// @@ -338,7 +341,7 @@ module cheshire_soc import cheshire_pkg::*; #( .AxiUserAsId ( 1 ), .AxiUserIdMsb ( Cfg.AxiUserAmoMsb ), .AxiUserIdLsb ( Cfg.AxiUserAmoLsb ), - .RiscvWordWidth ( 64 ), + .RiscvWordWidth ( RiscvWordWidth ), .NAxiCuts ( Cfg.RegAmoNumCuts ), .axi_req_t ( axi_slv_req_t ), .axi_rsp_t ( axi_slv_rsp_t ) @@ -487,7 +490,7 @@ module cheshire_soc import cheshire_pkg::*; #( .AxiUserAsId ( 1 ), .AxiUserIdMsb ( Cfg.AxiUserAmoMsb ), .AxiUserIdLsb ( Cfg.AxiUserAmoLsb ), - .RiscvWordWidth ( 64 ), + .RiscvWordWidth ( RiscvWordWidth ), .NAxiCuts ( Cfg.LlcAmoNumCuts ), .axi_req_t ( axi_slv_req_t ), .axi_rsp_t ( axi_slv_rsp_t ) @@ -641,8 +644,8 @@ module cheshire_soc import cheshire_pkg::*; #( ) i_core_cva6 ( .clk_i, .rst_ni, - .boot_addr_i ( BootAddr ), - .hart_id_i ( 64'(i) ), + .boot_addr_i ( BootAddr[riscv::XLEN-1:0] ), + .hart_id_i ( riscv::XLEN'(i) ), .irq_i ( xeip[i] ), .ipi_i ( msip[i] ), .time_irq_i ( mtip[i] ), @@ -862,7 +865,7 @@ module cheshire_soc import cheshire_pkg::*; #( .AxiUserAsId ( 1 ), .AxiUserIdMsb ( Cfg.AxiUserAmoMsb ), .AxiUserIdLsb ( Cfg.AxiUserAmoLsb ), - .RiscvWordWidth ( 64 ), + .RiscvWordWidth ( RiscvWordWidth ), .NAxiCuts ( Cfg.DbgAmoNumCuts ), .axi_req_t ( axi_slv_req_t ), .axi_rsp_t ( axi_slv_rsp_t ) @@ -1446,7 +1449,7 @@ module cheshire_soc import cheshire_pkg::*; #( .AxiUserAsId ( 1 ), .AxiUserIdMsb ( Cfg.AxiUserAmoMsb ), .AxiUserIdLsb ( Cfg.AxiUserAmoLsb ), - .RiscvWordWidth ( 64 ), + .RiscvWordWidth ( RiscvWordWidth ), .NAxiCuts ( Cfg.DmaConfAmoNumCuts ), .axi_req_t ( axi_slv_req_t ), .axi_rsp_t ( axi_slv_rsp_t ) @@ -1495,8 +1498,14 @@ module cheshire_soc import cheshire_pkg::*; #( .NumAxInFlight ( Cfg.DmaNumAxInFlight ), .MemSysDepth ( Cfg.DmaMemSysDepth ), .JobFifoDepth ( Cfg.DmaJobFifoDepth ), + .EnableAxiCut ( 1'b1 ), .RAWCouplingAvail ( Cfg.DmaRAWCouplingAvail ), .IsTwoD ( Cfg.DmaConfEnableTwoD ), + .axi_mst_aw_chan_t( axi_mst_aw_chan_t ), + .axi_mst_ar_chan_t( axi_mst_ar_chan_t ), + .axi_mst_r_chan_t ( axi_mst_r_chan_t ), + .axi_mst_w_chan_t ( axi_mst_w_chan_t ), + .axi_mst_b_chan_t ( axi_mst_b_chan_t ), .axi_mst_req_t ( axi_mst_req_t ), .axi_mst_rsp_t ( axi_mst_rsp_t ), .axi_slv_req_t ( axi_slv_req_t ), diff --git a/sw/include/dif/uart.h b/sw/include/dif/uart.h index 134ec8149..f45fbbfcf 100644 --- a/sw/include/dif/uart.h +++ b/sw/include/dif/uart.h @@ -27,19 +27,19 @@ #define UART_LINE_STATUS_THR_EMPTY_BIT 5 #define UART_LINE_STATUS_TMIT_EMPTY_BIT 6 -void uart_init(void *uart_base, uint64_t freq, uint64_t baud); +void uart_init(void *uart_base, uint32_t freq, uint32_t baud); 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_str(void *uart_base, void *src, uint32_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); +void uart_read_str(void *uart_base, void *dst, uint32_t len); // Default UART provides console void _putchar(char byte); diff --git a/sw/lib/32/crt0.S b/sw/lib/32/crt0.S new file mode 100644 index 000000000..243161afa --- /dev/null +++ b/sw/lib/32/crt0.S @@ -0,0 +1,179 @@ +// 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 +// +// Nicole Narr +// Christopher Reinwardt +// Paul Scheffler + +.section .text._start + +// Minimal CRT0 +.global _start +_start: + // Globally disable Machine and Supervisor interrupts + csrrc x0, mstatus, 10 + + // Park SMP harts + csrr t0, mhartid + beqz t0, 2f +1: + wfi + j 1b +2: + // Init stack and global pointer iff linked as nonzero + mv t1, sp + la t0, __stack_pointer$ + beqz t0, 1f + mv sp, t0 +1: .option push + .option norelax + la t0, __global_pointer$ + beqz t0, 1f + mv gp, t0 +1: .option pop + + // Store existing stack, global, return pointers on new stack + addi sp, sp, -12 + sw t1, 0(sp) + sw gp, 4(sp) + sw ra, 8(sp) + + // Set trap vector + la t0, _trap_handler_wrap + csrrw x0, mtvec, t0 + + // Zero the .bss section + la t0, __bss_start // t0 = bss start address + la t1, __bss_end // t1 = bss end address + sub t2, t1, t0 // t2 = #bytes to zero + li a0, 0 + +_zero_bss_loop: + addi t4, t2, -16 + blez t2, _fp_init // t2 <= 0? => No bss to zero + blt t4, x0, _zero_bss_rem // t4 < 0? => Less than 4 words left + sw a0, 0(t0) + sw a0, 4(t0) + sw a0, 8(t0) + sw a0, 12(t0) + addi t2, t2, -16 + addi t0, t0, 16 + bgt t2, x0, _zero_bss_loop // Still more to go + j _fp_init + +_zero_bss_rem: + sb a0, 0(t0) + addi t2, t2, -1 + addi t0, t0, 1 + bgt t2, x0, _zero_bss_rem + +_fp_init: + // Set FS state to "Initial", enabling FP instructions + li t1, 1 + slli t1, t1, 13 + csrs mstatus, t1 + + // Clear all 32 double FP registers + fcvt.d.l f0, x0 + fmv.d f1, f0 + fmv.d f2, f0 + fmv.d f3, f0 + fmv.d f4, f0 + fmv.d f5, f0 + fmv.d f6, f0 + fmv.d f7, f0 + fmv.d f8, f0 + fmv.d f9, f0 + fmv.d f10, f0 + fmv.d f11, f0 + fmv.d f12, f0 + fmv.d f13, f0 + fmv.d f14, f0 + fmv.d f15, f0 + fmv.d f16, f0 + fmv.d f17, f0 + fmv.d f18, f0 + fmv.d f19, f0 + fmv.d f20, f0 + fmv.d f21, f0 + fmv.d f22, f0 + fmv.d f23, f0 + fmv.d f24, f0 + fmv.d f25, f0 + fmv.d f26, f0 + fmv.d f27, f0 + fmv.d f28, f0 + fmv.d f29, f0 + fmv.d f30, f0 + fmv.d f31, f0 + + // Set FS state to "Clean" + csrrc x0, mstatus, t1 + + // Full fence, then jump to main + fence + call main + +// If main returns, we end up here +.global _exit +_exit: + // Restore the original context registers (sp last) + lw ra, 8(sp) + lw gp, 4(sp) + lw sp, 0(sp) + // Save the return value to scratch register 2 and wait forever. + slli t0, a0, 1 + ori t0, t0, 1 + la t1, __regs_base_addr__ + sw t0, 8(t1) // regs.SCRATCH[2] + // Hand over to whatever called us, passing return + ret + +// This wraps the C trap handler to save the (integer-only) caller-save +// registers and perform a proper machine-mode exception return. +.align 4 +_trap_handler_wrap: + addi sp, sp, -64 + sw ra, 60(sp) + sw t0, 56(sp) + sw t1, 52(sp) + sw t2, 48(sp) + sw a0, 44(sp) + sw a1, 40(sp) + sw a2, 36(sp) + sw a3, 32(sp) + sw a4, 28(sp) + sw a5, 24(sp) + sw a6, 20(sp) + sw a7, 16(sp) + sw t3, 12(sp) + sw t4, 8(sp) + sw t5, 4(sp) + sw t6, 0(sp) + + jal trap_vector + + lw ra, 60(sp) + lw t0, 56(sp) + lw t1, 52(sp) + lw t2, 48(sp) + lw a0, 44(sp) + lw a1, 40(sp) + lw a2, 36(sp) + lw a3, 32(sp) + lw a4, 28(sp) + lw a5, 24(sp) + lw a6, 20(sp) + lw a7, 16(sp) + lw t3, 12(sp) + lw t4, 8(sp) + lw t5, 4(sp) + lw t6, 0(sp) + addi sp, sp, 128 + mret + +.global trap_vector +.weak trap_vector +trap_vector: + j trap_vector diff --git a/sw/lib/crt0.S b/sw/lib/64/crt0.S similarity index 100% rename from sw/lib/crt0.S rename to sw/lib/64/crt0.S diff --git a/sw/lib/dif/uart.c b/sw/lib/dif/uart.c index 7e49b8297..9f94495bb 100644 --- a/sw/lib/dif/uart.c +++ b/sw/lib/dif/uart.c @@ -9,8 +9,8 @@ #include "util.h" #include "params.h" -void uart_init(void *uart_base, uint64_t freq, uint64_t baud) { - uint64_t divisor = freq / (baud << 4); +void uart_init(void *uart_base, uint32_t freq, uint32_t baud) { + uint32_t divisor = freq / (baud << 4); uint8_t dlo = (uint8_t)(divisor); uint8_t dhi = (uint8_t)(divisor >> 8); *reg8(uart_base, UART_INTR_ENABLE_REG_OFFSET) = 0x00; // Disable all interrupts @@ -26,11 +26,11 @@ 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) { +static 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) { +static 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); } @@ -41,8 +41,8 @@ void uart_write(void *uart_base, uint8_t byte) { *reg8(uart_base, UART_THR_REG_OFFSET) = byte; } -void uart_write_str(void *uart_base, void *src, uint64_t len) { - for (uint64_t i = 0; i < len; ++i) uart_write(uart_base, ((uint8_t *)src)[i]); +void uart_write_str(void *uart_base, void *src, uint32_t len) { + for (uint32_t i = 0; i < len; ++i) uart_write(uart_base, ((uint8_t *)src)[i]); } void uart_write_flush(void *uart_base) { @@ -59,8 +59,8 @@ uint8_t uart_read(void *uart_base) { return *reg8(uart_base, UART_RBR_REG_OFFSET); } -void uart_read_str(void *uart_base, void *dst, uint64_t len) { - for (uint64_t i = 0; i < len; ++i) ((uint8_t *)dst)[i] = uart_read(uart_base); +void uart_read_str(void *uart_base, void *dst, uint32_t len) { + for (uint32_t i = 0; i < len; ++i) ((uint8_t *)dst)[i] = uart_read(uart_base); } // Default UART provides console diff --git a/sw/link/common.ldh b/sw/link/common.ldh index 7b248921b..da08b9105 100644 --- a/sw/link/common.ldh +++ b/sw/link/common.ldh @@ -24,4 +24,26 @@ SECTIONS { /* AXI-RT guard register (specific offset within AXI-RT region, not a named block) */ __axirtgrd_base_addr__ = 0x020C1ffc; + + /* Further addresses */ + __base_dma = 0x01000000; + __base_bootrom = 0x02000000; + __base_clint = 0x02040000; + __base_axirt = 0x020C0000; + __base_axirtgrd = 0x020C1ffc; + __base_regs = 0x03000000; + __base_llc = 0x03001000; + __base_uart = 0x03002000; + __base_i2c = 0x03003000; + __base_spih = 0x03004000; + __base_gpio = 0x03005000; + __base_slink = 0x03006000; + __base_vga = 0x03007000; + __base_usb = 0x03008000; + __base_bus_err = 0x03009000; + __base_plic = 0x04000000; + __base_clic = 0x08000000; + __base_spm = ORIGIN(spm); + __base_dram = ORIGIN(dram); + __stack_start = ORIGIN(spm) + LENGTH(spm); } diff --git a/sw/sw.mk b/sw/sw.mk index ffae2e744..7d6267f4f 100644 --- a/sw/sw.mk +++ b/sw/sw.mk @@ -7,23 +7,72 @@ # Paul Scheffler # Override this as needed -CHS_SW_GCC_BINROOT ?= $(dir $(shell which riscv64-unknown-elf-gcc)) -CHS_SW_DTC ?= dtc -CHS_SW_AR := $(CHS_SW_GCC_BINROOT)/riscv64-unknown-elf-ar -CHS_SW_CC := $(CHS_SW_GCC_BINROOT)/riscv64-unknown-elf-gcc -CHS_SW_OBJCOPY := $(CHS_SW_GCC_BINROOT)/riscv64-unknown-elf-objcopy -CHS_SW_OBJDUMP := $(CHS_SW_GCC_BINROOT)/riscv64-unknown-elf-objdump -CHS_SW_LTOPLUG := $(shell find $(shell dirname $(CHS_SW_GCC_BINROOT))/libexec/gcc/riscv64-unknown-elf/**/liblto_plugin.so) +CHS_XLEN ?= 64 + +ifeq (${CHS_XLEN}, 64) + +CHS_SW_64_GCC_BINROOT ?= $(dir $(shell which riscv64-unknown-elf-gcc)) +CHS_SW_64_DTC ?= dtc + +CHS_SW_64_AR := $(CHS_SW_64_GCC_BINROOT)/riscv64-unknown-elf-ar +CHS_SW_64_CC := $(CHS_SW_64_GCC_BINROOT)/riscv64-unknown-elf-gcc +CHS_SW_64_OBJCOPY := $(CHS_SW_64_GCC_BINROOT)/riscv64-unknown-elf-objcopy +CHS_SW_64_OBJDUMP := $(CHS_SW_64_GCC_BINROOT)/riscv64-unknown-elf-objdump +CHS_SW_64_LTOPLUG := $(shell find $(shell dirname $(CHS_SW_64_GCC_BINROOT))/libexec/gcc/riscv64-unknown-elf/**/liblto_plugin.so) + +CHS_SW_64_FLAGS ?= -DOT_PLATFORM_RV32 -march=rv64gc_zifencei -mabi=lp64d + +endif +ifeq (${CHS_XLEN}, 32) + +CHS_SW_32_GCC_BINROOT ?= $(dir $(shell which riscv32-unknown-elf-gcc)) +CHS_SW_32_DTC ?= dtc + +CHS_SW_32_AR := $(CHS_SW_32_GCC_BINROOT)/riscv32-unknown-elf-ar +CHS_SW_32_CC := $(CHS_SW_32_GCC_BINROOT)/riscv32-unknown-elf-gcc +CHS_SW_32_OBJCOPY := $(CHS_SW_32_GCC_BINROOT)/riscv32-unknown-elf-objcopy +CHS_SW_32_OBJDUMP := $(CHS_SW_32_GCC_BINROOT)/riscv32-unknown-elf-objdump +CHS_SW_32_LTOPLUG := $(shell find $(shell dirname $(CHS_SW_32_GCC_BINROOT))/libexec/gcc/riscv32-unknown-elf/**/liblto_plugin.so) + +CHS_SW_32_FLAGS ?= -DOT_PLATFORM_RV32 -march=rv32imc -mabi=ilp32 + +endif + +ifeq (${CHS_XLEN}, 64) + +CHS_SW_AR := ${CHS_SW_64_AR} +CHS_SW_CC := ${CHS_SW_64_CC} +CHS_SW_OBJCOPY := ${CHS_SW_64_OBJCOPY} +CHS_SW_OBJDUMP := ${CHS_SW_64_OBJDUMP} +CHS_SW_LTOPLUG := ${CHS_SW_64_LTOPLUG} + +CHS_SW_FLAGS := ${CHS_SW_64_FLAGS} + +endif + +ifeq (${CHS_XLEN}, 32) + +CHS_SW_AR := ${CHS_SW_32_AR} +CHS_SW_CC := ${CHS_SW_32_CC} +CHS_SW_OBJCOPY := ${CHS_SW_32_OBJCOPY} +CHS_SW_OBJDUMP := ${CHS_SW_32_OBJDUMP} +CHS_SW_LTOPLUG := ${CHS_SW_32_LTOPLUG} + +CHS_SW_FLAGS := ${CHS_SW_32_FLAGS} +endif CHS_SW_DIR ?= $(CHS_ROOT)/sw + CHS_SW_LD_DIR ?= $(CHS_SW_DIR)/link + CHS_SW_ZSL_TGUID := 0269B26A-FD95-4CE4-98CF-941401412C62 CHS_SW_DTB_TGUID := BA442F61-2AEF-42DE-9233-E4D75D3ACB9D CHS_SW_FW_TGUID := 99EC86DA-3F5B-4B0D-8F4B-C4BACFA5F859 CHS_SW_DISK_SIZE ?= 16M -CHS_SW_FLAGS ?= -DOT_PLATFORM_RV32 -march=rv64gc_zifencei -mabi=lp64d -mstrict-align -O2 -Wall -Wextra -static -ffunction-sections -fdata-sections -frandom-seed=cheshire -fuse-linker-plugin -flto -Wl,-flto +CHS_SW_FLAGS += -mstrict-align -O2 -Wall -Wextra -static -ffunction-sections -fdata-sections -frandom-seed=cheshire -fuse-linker-plugin -flto -Wl,-flto + CHS_SW_CCFLAGS ?= $(CHS_SW_FLAGS) -ggdb -mcmodel=medany -mexplicit-relocs -fno-builtin -fverbose-asm -pipe CHS_SW_LDFLAGS ?= $(CHS_SW_FLAGS) -nostartfiles -Wl,--gc-sections -Wl,-L$(CHS_SW_LD_DIR) CHS_SW_ARFLAGS ?= --plugin=$(CHS_SW_LTOPLUG) @@ -53,7 +102,15 @@ CHS_SW_DEPS_SRCS += $(wildcard $(OTPROOT)/sw/device/lib/dif/autogen/*.c) ############# CHS_SW_INCLUDES ?= -I$(CHS_SW_DIR)/include $(CHS_SW_DEPS_INCS) -CHS_SW_LIB_SRCS_S = $(wildcard $(CHS_SW_DIR)/lib/*.S $(CHS_SW_DIR)/lib/**/*.S) +CHS_SW_LIB_SRCS_S = $(wildcard $(CHS_SW_DIR)/lib/*.S) + +ifeq (${CHS_XLEN}, 64) +CHS_SW_LIB_SRCS_S += $(wildcard $(CHS_SW_DIR)/lib/64/*.S) +endif +ifeq (${CHS_XLEN}, 32) +CHS_SW_LIB_SRCS_S += $(wildcard $(CHS_SW_DIR)/lib/32/*.S) +endif + CHS_SW_LIB_SRCS_C = $(wildcard $(CHS_SW_DIR)/lib/*.c $(CHS_SW_DIR)/lib/**/*.c) CHS_SW_LIB_SRCS_O = $(CHS_SW_DEPS_SRCS:.c=.o) $(CHS_SW_LIB_SRCS_S:.S=.o) $(CHS_SW_LIB_SRCS_C:.c=.o) @@ -207,3 +264,13 @@ CHS_SW_TESTS += $(CHS_SW_TEST_ROM_DUMP:.rom.dump=.rom.memh) $(CHS_SW_TEST_ROM_DU # Add all dumps to test build CHS_SW_TESTS += $(CHS_SW_TEST_DUMP) + +######### +# Clean # +######### + +.PHONY: chs-clean-sw + +chs-clean-sw: + @find -name *.o | xargs -I ! rm ! + @find -name libcheshire.a | xargs -I ! rm ! diff --git a/sw/tests/helloworld.c b/sw/tests/helloworld.c index de60d72e6..bfdd47f2e 100644 --- a/sw/tests/helloworld.c +++ b/sw/tests/helloworld.c @@ -15,7 +15,7 @@ int main(void) { char str[] = "Hello World!\r\n"; uint32_t rtc_freq = CHS_REGS->rtc_freq.f.ref_freq; - uint64_t reset_freq = clint_get_core_freq(rtc_freq, 2500); + uint64_t reset_freq = clint_get_core_freq(rtc_freq, 2048); uart_init(&__uart_base_addr__, reset_freq, __BOOT_BAUDRATE); uart_write_str(&__uart_base_addr__, str, sizeof(str) - 1); uart_write_flush(&__uart_base_addr__); diff --git a/target/sim/src/tb_cheshire_pkg.sv b/target/sim/src/tb_cheshire_pkg.sv index c8d65696e..deeefc16a 100644 --- a/target/sim/src/tb_cheshire_pkg.sv +++ b/target/sim/src/tb_cheshire_pkg.sv @@ -9,6 +9,18 @@ package tb_cheshire_pkg; import cheshire_pkg::*; + // An embedded 32 bit config + function automatic cheshire_cfg_t gen_cheshire_emb_cfg(); + cheshire_cfg_t ret = DefaultCfg; + ret.Clic = 1; + ret.Vga = 0; + ret.SerialLink = 0; + ret.AxiDataWidth = 32; + ret.AddrWidth = 32; + ret.LlcOutRegionEnd = 'hFFFF_FFFF; + return ret; + endfunction : gen_cheshire_emb_cfg + // A dedicated RT config function automatic cheshire_cfg_t gen_cheshire_rt_cfg(); cheshire_cfg_t ret = DefaultCfg; @@ -39,6 +51,7 @@ package tb_cheshire_pkg; // Assemble a configuration array indexed by a numeric parameter localparam cheshire_cfg_t [NumCheshireConfigs-1:0] TbCheshireConfigs = { + gen_cheshire_emb_cfg(), // 4: Embedded configuration gen_cheshire_vclic_cfg(), // 3: vCLIC-enabled configuration gen_cheshire_clic_cfg(), // 2: CLIC-enabled configuration gen_cheshire_rt_cfg(), // 1: RT-enabled configuration diff --git a/target/sim/src/vip_cheshire_soc.sv b/target/sim/src/vip_cheshire_soc.sv index dce214a33..609f83701 100644 --- a/target/sim/src/vip_cheshire_soc.sv +++ b/target/sim/src/vip_cheshire_soc.sv @@ -213,7 +213,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #( //////////// localparam dm::sbcs_t JtagInitSbcs = dm::sbcs_t'{ - sbautoincrement: 1'b1, sbreadondata: 1'b1, sbaccess: 3, default: '0}; + sbautoincrement: 1'b1, sbreadondata: 1'b1, sbaccess: $clog2(riscv::XLEN / 8), default: '0}; // Generate clock clk_rst_gen #( @@ -345,7 +345,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #( // Write address as 64-bit double jtag_write(dm::SBAddress1, addr[63:32]); jtag_write(dm::SBAddress0, addr[31:0]); - for (longint i = 0; i <= len ; i += 8) begin + for (longint i = 0; i <= len ; i += riscv::XLEN / 8) begin bit checkpoint = (i != 0 && i % 512 == 0); if (checkpoint) $display("[JTAG] - %0d/%0d bytes (%0d%%)", i, len, i*100/(len>1 ? len-1 : 1)); @@ -404,7 +404,11 @@ module vip_cheshire_soc import cheshire_pkg::*; #( // Repoint execution jtag_write(dm::Data1, entry[63:32]); jtag_write(dm::Data0, entry[31:0]); - jtag_write(dm::Command, 32'h0033_07b1, 0, 1); + if (riscv::XLEN == 64) begin + jtag_write(dm::Command, 32'h0033_07b1, 0, 1); + end else begin + jtag_write(dm::Command, 32'h0023_07b1, 0, 1); + end // Resume hart 0 jtag_write(dm::DMControl, dm::dmcontrol_t'{resumereq: 1, dmactive: 1, default: '0}); $display("[JTAG] Resumed hart 0 from 0x%h", entry); @@ -539,6 +543,7 @@ module vip_cheshire_soc import cheshire_pkg::*; #( uart_boot_eoc = 1; end else begin uart_read_buf.push_back(bite); + $display("Read Byte: %s", bite); end end end