aboutsummaryrefslogtreecommitdiff
path: root/riscv/dts.cc
diff options
context:
space:
mode:
authorAnup Patel <anup@brainfault.org>2021-12-14 11:25:55 +0530
committerAnup Patel <anup@brainfault.org>2022-04-20 10:20:10 +0530
commit5a433081f4ce1a49ee83d1a81cf4922e7542a20c (patch)
treec99dfe8db908caf9319c905e5bba388b3206d43a /riscv/dts.cc
parentd5b1a65c0e3a0b6b46eb66d5d0284bf3a6cc1e0c (diff)
downloadspike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.zip
spike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.tar.gz
spike-5a433081f4ce1a49ee83d1a81cf4922e7542a20c.tar.bz2
Add PLIC emulation
We need an interrupt controller in Spike which will allow us to emulate more real-world devices such as UART, VirtIO net, VirtIO block, etc. The RISC-V PLIC (or SiFive PLIC) is the commonly used interrupt controller in existing RISC-V platforms so this patch adds PLIC emulation for Spike. Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'riscv/dts.cc')
-rw-r--r--riscv/dts.cc37
1 files changed, 37 insertions, 0 deletions
diff --git a/riscv/dts.cc b/riscv/dts.cc
index 6b47c76..970e0ef 100644
--- a/riscv/dts.cc
+++ b/riscv/dts.cc
@@ -93,6 +93,21 @@ std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz,
" reg = <0x" << (clintbs >> 32) << " 0x" << (clintbs & (uint32_t)-1) <<
" 0x" << (clintsz >> 32) << " 0x" << (clintsz & (uint32_t)-1) << ">;\n"
" };\n"
+ " plic@" << PLIC_BASE << " {\n"
+ " compatible = \"riscv,plic0\";\n"
+ " interrupts-extended = <" << std::dec;
+ for (size_t i = 0; i < procs.size(); i++)
+ s << "&CPU" << i << "_intc 11 &CPU" << i << "_intc 9 ";
+ reg_t plicbs = PLIC_BASE;
+ reg_t plicsz = PLIC_SIZE;
+ s << std::hex << ">;\n"
+ " reg = <0x" << (plicbs >> 32) << " 0x" << (plicbs & (uint32_t)-1) <<
+ " 0x" << (plicsz >> 32) << " 0x" << (plicsz & (uint32_t)-1) << ">;\n"
+ " riscv,ndev = <0x" << PLIC_NDEV << ">;\n"
+ " riscv,max-priority = <0x" << ((1U << PLIC_PRIO_BITS) - 1) << ">;\n"
+ " #interrupt-cells = <1>;\n"
+ " interrupt-controller;\n"
+ " };\n"
" };\n"
" htif {\n"
" compatible = \"ucb,htif0\";\n"
@@ -277,6 +292,28 @@ int fdt_parse_clint(void *fdt, reg_t *clint_addr,
return 0;
}
+int fdt_parse_plic(void *fdt, reg_t *plic_addr, uint32_t *ndev,
+ const char *compatible)
+{
+ int nodeoffset, len, rc;
+ const fdt32_t *ndev_p;
+
+ nodeoffset = fdt_node_offset_by_compatible(fdt, -1, compatible);
+ if (nodeoffset < 0)
+ return nodeoffset;
+
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, plic_addr, NULL, "reg");
+ if (rc < 0 || !plic_addr)
+ return -ENODEV;
+
+ ndev_p = (fdt32_t *)fdt_getprop(fdt, nodeoffset, "riscv,ndev", &len);
+ if (!ndev || !ndev_p)
+ return -ENODEV;
+ *ndev = fdt32_to_cpu(*ndev_p);
+
+ return 0;
+}
+
int fdt_parse_pmp_num(void *fdt, int cpu_offset, reg_t *pmp_num)
{
int rc;