diff options
author | Anup Patel <anup@brainfault.org> | 2021-12-14 11:25:55 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-04-20 10:20:10 +0530 |
commit | 5a433081f4ce1a49ee83d1a81cf4922e7542a20c (patch) | |
tree | c99dfe8db908caf9319c905e5bba388b3206d43a /riscv/dts.cc | |
parent | d5b1a65c0e3a0b6b46eb66d5d0284bf3a6cc1e0c (diff) | |
download | spike-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.cc | 37 |
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; |