Skip to content

Instantly share code, notes, and snippets.

@enjoy-digital
Created April 23, 2020 15:42
Show Gist options
  • Save enjoy-digital/641a52b6cbe5f29b989f587ec24e558e to your computer and use it in GitHub Desktop.
Save enjoy-digital/641a52b6cbe5f29b989f587ec24e558e to your computer and use it in GitHub Desktop.
SweRV initial support
rom e9163d85ba2b0a1be46e9cef9c71f4a72710dc13 Mon Sep 17 00:00:00 2001
From: Florent Kermarrec <florent@enjoy-digital.fr>
Date: Thu, 17 Oct 2019 10:08:54 +0200
Subject: [PATCH] add initial SwerRV support
---
.gitmodules | 3 +
litex/build/sim/core/Makefile | 3 +-
litex/soc/cores/cpu/__init__.py | 2 +
litex/soc/cores/cpu/swerv/__init__.py | 1 +
litex/soc/cores/cpu/swerv/core.py | 341 ++++++++++++++++++++
litex/soc/integration/soc_core.py | 3 +
litex/soc/interconnect/axi.py | 1 +
litex/soc/software/bios/boot-helper-swerv.S | 4 +
litex/soc/software/bios/isr.c | 4 +
litex/soc/software/bios/sdram.c | 2 +
litex/soc/software/include/base/irq.h | 10 +
litex/soc/software/libbase/crt0-swerv.S | 63 ++++
litex/soc/software/libbase/system.c | 6 +
13 files changed, 442 insertions(+), 1 deletion(-)
create mode 100644 litex/soc/cores/cpu/swerv/__init__.py
create mode 100644 litex/soc/cores/cpu/swerv/core.py
create mode 100644 litex/soc/software/bios/boot-helper-swerv.S
create mode 100644 litex/soc/software/libbase/crt0-swerv.S
diff --git a/.gitmodules b/.gitmodules
index 17eaf734..8c19280c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,6 @@
[submodule "litex/soc/cores/cpu/rocket/verilog"]
path = litex/soc/cores/cpu/rocket/verilog
url = https://github.com/enjoy-digital/rocket-litex-verilog
+[submodule "litex/soc/cores/cpu/swerv/verilog"]
+ path = litex/soc/cores/cpu/swerv/verilog
+ url = https://github.com/chipsalliance/Cores-SweRV
\ No newline at end of file
diff --git a/litex/build/sim/core/Makefile b/litex/build/sim/core/Makefile
index e34e456e..d280234c 100644
--- a/litex/build/sim/core/Makefile
+++ b/litex/build/sim/core/Makefile
@@ -26,10 +26,11 @@ $(OBJS_SIM): %.o: $(SRC_DIR)/%.c
.PHONY: sim
sim: mkdir $(OBJS_SIM)
- verilator -Wno-fatal -O3 $(CC_SRCS) --top-module dut --exe \
+ verilator '-UASSERT_ON' -Wno-fatal -O3 -CFLAGS "-std=c++11" $(CC_SRCS) --top-module dut --exe \
-DPRINTF_COND=0 \
$(SRCS_SIM_CPP) $(OBJS_SIM) \
--top-module dut \
+ --sv \
$(if $(THREADS), --threads $(THREADS),) \
-CFLAGS "$(CFLAGS) -I$(SRC_DIR)" \
-LDFLAGS "$(LDFLAGS)" \
diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py
index 6aeb6ba5..371ae472 100644
--- a/litex/soc/cores/cpu/__init__.py
+++ b/litex/soc/cores/cpu/__init__.py
@@ -32,6 +32,7 @@ from litex.soc.cores.cpu.picorv32 import PicoRV32
from litex.soc.cores.cpu.vexriscv import VexRiscv
from litex.soc.cores.cpu.minerva import Minerva
from litex.soc.cores.cpu.rocket import RocketRV64
+from litex.soc.cores.cpu.swerv import SweRV
CPUS = {
"lm32" : LM32,
@@ -40,6 +41,7 @@ CPUS = {
"vexriscv" : VexRiscv,
"minerva" : Minerva,
"rocket" : RocketRV64,
+ "swerv" : SweRV,
}
# CPU Variants/Extensions Definition ---------------------------------------------------------------
diff --git a/litex/soc/cores/cpu/swerv/__init__.py b/litex/soc/cores/cpu/swerv/__init__.py
new file mode 100644
index 00000000..8d6f2d72
--- /dev/null
+++ b/litex/soc/cores/cpu/swerv/__init__.py
@@ -0,0 +1 @@
+from litex.soc.cores.cpu.swerv.core import SweRV
diff --git a/litex/soc/cores/cpu/swerv/core.py b/litex/soc/cores/cpu/swerv/core.py
new file mode 100644
index 00000000..a791d2c1
--- /dev/null
+++ b/litex/soc/cores/cpu/swerv/core.py
@@ -0,0 +1,341 @@
+# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
+
+# License: BSD
+
+import os
+
+from migen import *
+
+from litex.soc.interconnect import axi
+from litex.soc.interconnect import wishbone
+from litex.soc.cores.cpu import CPU
+
+CPU_VARIANTS = ["standard"]
+
+
+class SweRV(CPU):
+ name = "swerv"
+ data_width = 32
+ endianness = "little"
+ gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed")
+ linker_output_format = "elf32-littleriscv"
+ io_regions = {0x80000000: 0x80000000} # origin, length
+
+ @property
+ def gcc_flags(self):
+ flags = "-march=rv32im "
+ flags += "-mabi=ilp32 "
+ flags += "-D__swerv__ "
+ return flags
+
+ def __init__(self, platform, variant="standard"):
+ assert variant is "standard", "Unsupported variant %s" % variant
+ self.platform = platform
+ self.variant = variant
+
+ self.reset = Signal()
+ self.ibus = wishbone.Interface()
+ self.dbus = wishbone.Interface()
+ self.buses = [self.ibus, self.dbus]
+
+ self.lsu_axi = lsu_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
+ self.ifu_axi = ifu_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
+ self.sb_axi = sb_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
+ self.dma_axi = dma_axi = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
+
+
+ # # #
+
+ self.cpu_params = dict(
+ # Clk / Rst ----------------------------------------------------------------------------
+ i_clk = ClockSignal("sys"),
+ i_rst_l = ~(ResetSignal("sys") | self.reset),
+
+ # NMI ----------------------------------------------------------------------------------
+ i_nmi_int = 0,
+ i_nmi_vec = 0x8880000,
+
+ # JTAG ---------------------------------------------------------------------------------
+ i_jtag_id = 0,
+ i_jtag_tck = 0,
+ i_jtag_tms = 0,
+ i_jtag_tdi = 0,
+ i_jtag_trst_n = 0,
+ #o_jtag_tdo = ,
+
+ # Clock Enable -------------------------------------------------------------------------
+ i_lsu_bus_clk_en = 1,
+ i_ifu_bus_clk_en = 1,
+ i_dbg_bus_clk_en = 1,
+ i_dma_bus_clk_en = 1,
+
+ # IRQ ----------------------------------------------------------------------------------
+ i_timer_int = 0,
+ i_extintsrc_req = 0,
+
+ # DEBUG --------------------------------------------------------------------------------
+ i_mpc_debug_halt_req = 0,
+ i_mpc_debug_run_req = 0,
+ i_mpc_reset_run_req = 1,
+ #o_mpc_debug_halt_ack = ,
+ #o_mpc_debug_run_ack = ,
+ #o_debug_brkpt_status = ,
+ #o_o_debug_mode_status = ,
+
+ i_i_cpu_halt_req = 0,
+ #o_o_cpu_halt_ack = ,
+ #o_o_cpu_halt_status = ,
+ i_i_cpu_run_req = 0,
+ #o_o_cpu_run_ack = ,
+
+ i_scan_mode = 0,
+ i_mbist_mode = 0,
+
+ # LSU AXI ------------------------------------------------------------------------------
+ o_lsu_axi_awvalid = lsu_axi.aw.valid,
+ i_lsu_axi_awready = lsu_axi.aw.ready,
+ o_lsu_axi_awid = lsu_axi.aw.id,
+ o_lsu_axi_awaddr = lsu_axi.aw.addr,
+ o_lsu_axi_awregion = lsu_axi.aw.region,
+ o_lsu_axi_awlen = lsu_axi.aw.len,
+ o_lsu_axi_awsize = lsu_axi.aw.size,
+ o_lsu_axi_awburst = lsu_axi.aw.burst,
+ o_lsu_axi_awlock = lsu_axi.aw.lock,
+ o_lsu_axi_awcache = lsu_axi.aw.cache,
+ o_lsu_axi_awprot = lsu_axi.aw.prot,
+ o_lsu_axi_awqos = lsu_axi.aw.qos,
+
+ o_lsu_axi_wvalid = lsu_axi.w.valid,
+ i_lsu_axi_wready = lsu_axi.w.ready,
+ o_lsu_axi_wdata = lsu_axi.w.data,
+ o_lsu_axi_wstrb = lsu_axi.w.strb,
+ o_lsu_axi_wlast = lsu_axi.w.last,
+
+ i_lsu_axi_bvalid = lsu_axi.b.valid,
+ o_lsu_axi_bready = lsu_axi.b.ready,
+ i_lsu_axi_bresp = lsu_axi.b.resp,
+ i_lsu_axi_bid = lsu_axi.b.id,
+
+ o_lsu_axi_arvalid = lsu_axi.ar.valid,
+ i_lsu_axi_arready = lsu_axi.ar.ready,
+ o_lsu_axi_arid = lsu_axi.ar.id,
+ o_lsu_axi_araddr = lsu_axi.ar.addr,
+ o_lsu_axi_arregion = lsu_axi.ar.region,
+ o_lsu_axi_arlen = lsu_axi.ar.len,
+ o_lsu_axi_arsize = lsu_axi.ar.size,
+ o_lsu_axi_arburst = lsu_axi.ar.burst,
+ o_lsu_axi_arlock = lsu_axi.ar.lock,
+ o_lsu_axi_arcache = lsu_axi.ar.cache,
+ o_lsu_axi_arprot = lsu_axi.ar.prot,
+ o_lsu_axi_arqos = lsu_axi.ar.qos,
+
+ i_lsu_axi_rvalid = lsu_axi.r.valid,
+ o_lsu_axi_rready = lsu_axi.r.ready,
+ i_lsu_axi_rid = lsu_axi.r.id,
+ i_lsu_axi_rdata = lsu_axi.r.data,
+ i_lsu_axi_rresp = lsu_axi.r.resp,
+ i_lsu_axi_rlast = lsu_axi.r.last,
+
+ # IFU AXI ------------------------------------------------------------------------------
+ o_ifu_axi_awvalid = ifu_axi.aw.valid,
+ i_ifu_axi_awready = ifu_axi.aw.ready,
+ o_ifu_axi_awid = ifu_axi.aw.id,
+ o_ifu_axi_awaddr = ifu_axi.aw.addr,
+ o_ifu_axi_awregion = ifu_axi.aw.region,
+ o_ifu_axi_awlen = ifu_axi.aw.len,
+ o_ifu_axi_awsize = ifu_axi.aw.size,
+ o_ifu_axi_awburst = ifu_axi.aw.burst,
+ o_ifu_axi_awlock = ifu_axi.aw.lock,
+ o_ifu_axi_awcache = ifu_axi.aw.cache,
+ o_ifu_axi_awprot = ifu_axi.aw.prot,
+ o_ifu_axi_awqos = ifu_axi.aw.qos,
+
+ o_ifu_axi_wvalid = ifu_axi.w.valid,
+ i_ifu_axi_wready = ifu_axi.w.ready,
+ o_ifu_axi_wdata = ifu_axi.w.data,
+ o_ifu_axi_wstrb = ifu_axi.w.strb,
+ o_ifu_axi_wlast = ifu_axi.w.last,
+
+ i_ifu_axi_bvalid = ifu_axi.b.valid,
+ o_ifu_axi_bready = ifu_axi.b.ready,
+ i_ifu_axi_bresp = ifu_axi.b.resp,
+ i_ifu_axi_bid = ifu_axi.b.id,
+
+ o_ifu_axi_arvalid = ifu_axi.ar.valid,
+ i_ifu_axi_arready = ifu_axi.ar.ready,
+ o_ifu_axi_arid = ifu_axi.ar.id,
+ o_ifu_axi_araddr = ifu_axi.ar.addr,
+ o_ifu_axi_arregion = ifu_axi.ar.region,
+ o_ifu_axi_arlen = ifu_axi.ar.len,
+ o_ifu_axi_arsize = ifu_axi.ar.size,
+ o_ifu_axi_arburst = ifu_axi.ar.burst,
+ o_ifu_axi_arlock = ifu_axi.ar.lock,
+ o_ifu_axi_arcache = ifu_axi.ar.cache,
+ o_ifu_axi_arprot = ifu_axi.ar.prot,
+ o_ifu_axi_arqos = ifu_axi.ar.qos,
+
+ i_ifu_axi_rvalid = ifu_axi.r.valid,
+ o_ifu_axi_rready = ifu_axi.r.ready,
+ i_ifu_axi_rid = ifu_axi.r.id,
+ i_ifu_axi_rdata = ifu_axi.r.data,
+ i_ifu_axi_rresp = ifu_axi.r.resp,
+ i_ifu_axi_rlast = ifu_axi.r.last,
+
+ # SB AXI -------------------------------------------------------------------------------
+ o_sb_axi_awvalid = sb_axi.aw.valid,
+ i_sb_axi_awready = sb_axi.aw.ready,
+ o_sb_axi_awid = sb_axi.aw.id,
+ o_sb_axi_awaddr = sb_axi.aw.addr,
+ o_sb_axi_awregion = sb_axi.aw.region,
+ o_sb_axi_awlen = sb_axi.aw.len,
+ o_sb_axi_awsize = sb_axi.aw.size,
+ o_sb_axi_awburst = sb_axi.aw.burst,
+ o_sb_axi_awlock = sb_axi.aw.lock,
+ o_sb_axi_awcache = sb_axi.aw.cache,
+ o_sb_axi_awprot = sb_axi.aw.prot,
+ o_sb_axi_awqos = sb_axi.aw.qos,
+
+ o_sb_axi_wvalid = sb_axi.w.valid,
+ i_sb_axi_wready = sb_axi.w.ready,
+ o_sb_axi_wdata = sb_axi.w.data,
+ o_sb_axi_wstrb = sb_axi.w.strb,
+ o_sb_axi_wlast = sb_axi.w.last,
+
+ i_sb_axi_bvalid = sb_axi.b.valid,
+ o_sb_axi_bready = sb_axi.b.ready,
+ i_sb_axi_bresp = sb_axi.b.resp,
+ i_sb_axi_bid = sb_axi.b.id,
+
+ o_sb_axi_arvalid = sb_axi.ar.valid,
+ i_sb_axi_arready = sb_axi.ar.ready,
+ o_sb_axi_arid = sb_axi.ar.id,
+ o_sb_axi_araddr = sb_axi.ar.addr,
+ o_sb_axi_arregion = sb_axi.ar.region,
+ o_sb_axi_arlen = sb_axi.ar.len,
+ o_sb_axi_arsize = sb_axi.ar.size,
+ o_sb_axi_arburst = sb_axi.ar.burst,
+ o_sb_axi_arlock = sb_axi.ar.lock,
+ o_sb_axi_arcache = sb_axi.ar.cache,
+ o_sb_axi_arprot = sb_axi.ar.prot,
+ o_sb_axi_arqos = sb_axi.ar.qos,
+
+ i_sb_axi_rvalid = sb_axi.r.valid,
+ o_sb_axi_rready = sb_axi.r.ready,
+ i_sb_axi_rid = sb_axi.r.id,
+ i_sb_axi_rdata = sb_axi.r.data,
+ i_sb_axi_rresp = sb_axi.r.resp,
+ i_sb_axi_rlast = sb_axi.r.last,
+
+ # DMA AXI ------------------------------------------------------------------------------
+ i_dma_axi_awvalid = dma_axi.aw.valid,
+ o_dma_axi_awready = dma_axi.aw.ready,
+ i_dma_axi_awid = dma_axi.aw.id,
+ i_dma_axi_awaddr = dma_axi.aw.addr,
+ i_dma_axi_awsize = dma_axi.aw.size,
+ i_dma_axi_awprot = dma_axi.aw.prot,
+ i_dma_axi_awlen = dma_axi.aw.len,
+ i_dma_axi_awburst = dma_axi.aw.burst,
+
+ i_dma_axi_wvalid = dma_axi.w.valid,
+ o_dma_axi_wready = dma_axi.w.ready,
+ i_dma_axi_wdata = dma_axi.w.data,
+ i_dma_axi_wstrb = dma_axi.w.strb,
+ i_dma_axi_wlast = dma_axi.w.last,
+
+ o_dma_axi_bvalid = dma_axi.b.valid,
+ i_dma_axi_bready = dma_axi.b.ready,
+ o_dma_axi_bresp = dma_axi.b.resp,
+ o_dma_axi_bid = dma_axi.b.id,
+
+ i_dma_axi_arvalid = dma_axi.ar.valid,
+ o_dma_axi_arready = dma_axi.ar.ready,
+ i_dma_axi_arid = dma_axi.ar.id,
+ i_dma_axi_araddr = dma_axi.ar.addr,
+ i_dma_axi_arsize = dma_axi.ar.size,
+ i_dma_axi_arprot = dma_axi.ar.prot,
+ i_dma_axi_arlen = dma_axi.ar.len,
+ i_dma_axi_arburst = dma_axi.ar.burst,
+
+ o_dma_axi_rvalid = dma_axi.r.valid,
+ i_dma_axi_rready = dma_axi.r.ready,
+ o_dma_axi_rid = dma_axi.r.id,
+ o_dma_axi_rdata = dma_axi.r.data,
+ o_dma_axi_rresp = dma_axi.r.resp,
+ o_dma_axi_rlast = dma_axi.r.last,
+ )
+
+ # adapt axi interfaces to wishbone
+ lsu_a2w = ResetInserter()(axi.AXI2Wishbone(lsu_axi, self.ibus, base_address=0))
+ ifu_a2w = ResetInserter()(axi.AXI2Wishbone(ifu_axi, self.dbus, base_address=0))
+ self.comb += [
+ lsu_a2w.reset.eq(ResetSignal() | self.reset),
+ ifu_a2w.reset.eq(ResetSignal() | self.reset),
+ ]
+ self.submodules += lsu_a2w, ifu_a2w
+
+ # add verilog sources
+ self.add_sources(platform)
+
+ def set_reset_address(self, reset_address):
+ assert not hasattr(self, "reset_address")
+ self.reset_address = reset_address
+ self.cpu_params.update(i_rst_vec=reset_address)
+
+ @staticmethod
+ def add_sources(platform):
+ vdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "verilog")
+ platform.add_source(os.path.join(vdir, "configs", "snapshots", "default", "common_defines.vh"))
+ platform.add_source(os.path.join(vdir, "design/include", "build.h"))
+ platform.add_source(os.path.join(vdir, "design/include", "global.h"))
+ platform.add_source(os.path.join(vdir, "design/include", "swerv_types.sv"))
+ platform.add_source(os.path.join(vdir, "design/swerv_wrapper.sv"))
+ platform.add_source(os.path.join(vdir, "design/mem.sv"))
+ platform.add_source(os.path.join(vdir, "design/pic_ctrl.sv"))
+ platform.add_source(os.path.join(vdir, "design/swerv.sv"))
+ platform.add_source(os.path.join(vdir, "design/dma_ctrl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_aln_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_compress_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_ifc_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_bp_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_ic_mem.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_mem_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu_iccm_mem.sv"))
+ platform.add_source(os.path.join(vdir, "design/ifu/ifu.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec_decode_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec_gpr_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec_ib_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec_tlu_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec_trigger.sv"))
+ platform.add_source(os.path.join(vdir, "design/dec/dec.sv"))
+ platform.add_source(os.path.join(vdir, "design/exu/exu_alu_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/exu/exu_mul_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/exu/exu_div_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/exu/exu.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_clkdomain.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_addrcheck.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_lsc_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_stbuf.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_bus_buffer.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_bus_intf.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_ecc.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_dccm_mem.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_dccm_ctl.sv"))
+ platform.add_source(os.path.join(vdir, "design/lsu/lsu_trigger.sv"))
+ platform.add_source(os.path.join(vdir, "design/dbg/dbg.sv"))
+ platform.add_source(os.path.join(vdir, "design/dmi/dmi_wrapper.v"))
+ platform.add_source(os.path.join(vdir, "design/dmi/dmi_jtag_to_core_sync.v"))
+ platform.add_source(os.path.join(vdir, "design/dmi/rvjtag_tap.sv"))
+ platform.add_source(os.path.join(vdir, "design/lib/beh_lib.sv"))
+ platform.add_source(os.path.join(vdir, "design/lib/mem_lib.sv"))
+ platform.add_source(os.path.join(vdir, "design/lib/ahb_to_axi4.sv"))
+ platform.add_source(os.path.join(vdir, "design/lib/axi4_to_ahb.sv"))
+ platform.add_verilog_include_path(os.path.join(vdir, "design/include"))
+ platform.add_verilog_include_path(os.path.join(vdir, "design/lib"))
+ platform.add_verilog_include_path(os.path.join(vdir, "design/dmi"))
+ platform.add_verilog_include_path(os.path.join(vdir, "configs", "snapshots", "default"))
+ #platform.add_verilog_include_path(vdir)
+
+ def do_finalize(self):
+ assert hasattr(self, "reset_address")
+ self.specials += Instance("swerv_wrapper", **self.cpu_params)
diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py
index 7c8abecf..a4385213 100644
--- a/litex/soc/integration/soc_core.py
+++ b/litex/soc/integration/soc_core.py
@@ -172,6 +172,9 @@ class SoCCore(Module):
# Add the CPU
self.add_cpu(cpu.CPUS[cpu_type](platform, self.cpu_variant))
+ if cpu_type == "swerv":
+ self.add_constant("UART_POLLING")
+
# Update Memory Map (if defined by CPU)
self.soc_mem_map.update(self.cpu.mem_map)
diff --git a/litex/soc/interconnect/axi.py b/litex/soc/interconnect/axi.py
index 5d362c7b..a45298f6 100644
--- a/litex/soc/interconnect/axi.py
+++ b/litex/soc/interconnect/axi.py
@@ -25,6 +25,7 @@ def ax_description(address_width, id_width):
("burst", 2), # Burst type
("len", 8), # Number of data (-1) transfers (up to 256)
("size", 4), # Number of bytes (-1) of each data transfer (up to 1024 bits)
+ ("region", 4), # *
("lock", 2), # *
("prot", 3), # *
("cache", 4), # *
diff --git a/litex/soc/software/bios/boot-helper-swerv.S b/litex/soc/software/bios/boot-helper-swerv.S
new file mode 100644
index 00000000..6dd74aae
--- /dev/null
+++ b/litex/soc/software/bios/boot-helper-swerv.S
@@ -0,0 +1,4 @@
+.section .text, "ax", @progbits
+.global boot_helper
+boot_helper:
+ jr x13
diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c
index aa47cacc..4e8b4189 100644
--- a/litex/soc/software/bios/isr.c
+++ b/litex/soc/software/bios/isr.c
@@ -30,9 +30,11 @@ void isr(void)
while ((claim = csr_readl(PLIC_CLAIM))) {
switch (claim - 1) {
+#ifndef UART_POLLING
case UART_INTERRUPT:
uart_isr();
break;
+#endif
default:
printf("## PLIC: Unhandled claim: %d\n", claim);
printf("# plic_enabled: %08x\n", irq_getmask());
@@ -56,7 +58,9 @@ void isr(void)
irqs = irq_pending() & irq_getmask();
+#ifndef UART_POLLING
if(irqs & (1 << UART_INTERRUPT))
uart_isr();
+#endif
}
#endif
diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c
index f0c12edf..774c11f5 100644
--- a/litex/soc/software/bios/sdram.c
+++ b/litex/soc/software/bios/sdram.c
@@ -44,6 +44,8 @@ __attribute__((unused)) static void cdelay(int i)
__asm__ volatile("nop");
#elif defined (__powerpc__)
__asm__ volatile("nop");
+#elif defined (__swerv__)
+ __asm__ volatile("nop");
#else
#error Unsupported architecture
#endif
diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h
index 4bf6786c..3ee20f33 100644
--- a/litex/soc/software/include/base/irq.h
+++ b/litex/soc/software/include/base/irq.h
@@ -56,6 +56,8 @@ static inline unsigned int irq_getie(void)
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
#elif defined (__rocket__)
return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;
+#elif defined (__swerv__)
+ return 0; /* FIXME */
#else
#error Unsupported architecture
#endif
@@ -81,6 +83,8 @@ static inline void irq_setie(unsigned int ie)
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
#elif defined (__rocket__)
if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);
+#elif defined (__swerv__)
+ /* FIXME */
#else
#error Unsupported architecture
#endif
@@ -108,6 +112,8 @@ static inline unsigned int irq_getmask(void)
return mask;
#elif defined (__rocket__)
return csr_readl(PLIC_ENABLED) >> 1;
+#elif defined (__swerv__)
+ return 0; /* FIXME */
#else
#error Unsupported architecture
#endif
@@ -129,6 +135,8 @@ static inline void irq_setmask(unsigned int mask)
asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask));
#elif defined (__rocket__)
csr_writel(mask << 1, PLIC_ENABLED);
+#elif defined (__swerv__)
+ /* FIXME */
#else
#error Unsupported architecture
#endif
@@ -154,6 +162,8 @@ static inline unsigned int irq_pending(void)
return pending;
#elif defined (__rocket__)
return csr_readl(PLIC_PENDING) >> 1;
+#elif defined (__swerv__)
+ return 0;/* FIXME */
#else
#error Unsupported architecture
#endif
diff --git a/litex/soc/software/libbase/crt0-swerv.S b/litex/soc/software/libbase/crt0-swerv.S
new file mode 100644
index 00000000..6f6e9e6c
--- /dev/null
+++ b/litex/soc/software/libbase/crt0-swerv.S
@@ -0,0 +1,63 @@
+#define MIE_MEIE 0x800
+
+ .global _start
+_start:
+ j reset_vector
+
+reset_vector:
+ la sp, _fstack
+ la t0, trap_vector
+ csrw mtvec, t0
+
+ // initialize .bss
+ la t0, _fbss
+ la t1, _ebss
+1: beq t0, t1, 2f
+ sw zero, 0(t0)
+ addi t0, t0, 4
+ j 1b
+2:
+ // enable external interrupts
+ li t0, MIE_MEIE
+ csrs mie, t0
+
+ call main
+1: j 1b
+
+trap_vector:
+ addi sp, sp, -16*4
+ sw ra, 0*4(sp)
+ sw t0, 1*4(sp)
+ sw t1, 2*4(sp)
+ sw t2, 3*4(sp)
+ sw a0, 4*4(sp)
+ sw a1, 5*4(sp)
+ sw a2, 6*4(sp)
+ sw a3, 7*4(sp)
+ sw a4, 8*4(sp)
+ sw a5, 9*4(sp)
+ sw a6, 10*4(sp)
+ sw a7, 11*4(sp)
+ sw t3, 12*4(sp)
+ sw t4, 13*4(sp)
+ sw t5, 14*4(sp)
+ sw t6, 15*4(sp)
+ call isr
+ lw ra, 0*4(sp)
+ lw t0, 1*4(sp)
+ lw t1, 2*4(sp)
+ lw t2, 3*4(sp)
+ lw a0, 4*4(sp)
+ lw a1, 5*4(sp)
+ lw a2, 6*4(sp)
+ lw a3, 7*4(sp)
+ lw a4, 8*4(sp)
+ lw a5, 9*4(sp)
+ lw a6, 10*4(sp)
+ lw a7, 11*4(sp)
+ lw t3, 12*4(sp)
+ lw t4, 13*4(sp)
+ lw t5, 14*4(sp)
+ lw t6, 15*4(sp)
+ addi sp, sp, 16*4
+ mret
diff --git a/litex/soc/software/libbase/system.c b/litex/soc/software/libbase/system.c
index bb15aad0..d57b6b15 100644
--- a/litex/soc/software/libbase/system.c
+++ b/litex/soc/software/libbase/system.c
@@ -56,6 +56,9 @@ void flush_cpu_icache(void)
#elif defined (__rocket__)
/* FIXME: do something useful here! */
asm volatile("nop");
+#elif defined (__swerv__)
+ /* FIXME: do something useful here! */
+ asm volatile("nop");
#else
#error Unsupported architecture
#endif
@@ -101,6 +104,9 @@ void flush_cpu_dcache(void)
#elif defined (__rocket__)
/* FIXME: do something useful here! */
asm volatile("nop");
+#elif defined (__swerv__)
+ /* no data cache */
+ asm volatile("nop");
#else
#error Unsupported architecture
#endif
--
2.17.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment