aboutsummaryrefslogtreecommitdiff
path: root/riscv/sim.cc
diff options
context:
space:
mode:
authorAnup Patel <anup@brainfault.org>2021-12-14 19:18:32 +0530
committerAnup Patel <anup@brainfault.org>2022-04-20 11:24:35 +0530
commit191634d2854dfed448fc323195f9b65c305e2d77 (patch)
tree47193b8ed63049f264211a87e9402c82660c7f85 /riscv/sim.cc
parent5a433081f4ce1a49ee83d1a81cf4922e7542a20c (diff)
downloadspike-191634d2854dfed448fc323195f9b65c305e2d77.zip
spike-191634d2854dfed448fc323195f9b65c305e2d77.tar.gz
spike-191634d2854dfed448fc323195f9b65c305e2d77.tar.bz2
Add ns16550 serial device emulation
The ns16550 is a widely use serial device so we add a simplified ns16550 device emulation which is good enough for Linux, OpenSBI, and hypervisors to use as console. Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'riscv/sim.cc')
-rw-r--r--riscv/sim.cc16
1 files changed, 16 insertions, 0 deletions
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 81a0cbc..e909009 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -98,12 +98,27 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
bus.add_device(clint_base, clint.get());
}
+ // pointer to wired interrupt controller
+ abstract_interrupt_controller_t *intctrl = NULL;
+
// create plic
reg_t plic_base;
uint32_t plic_ndev;
if (fdt_parse_plic(fdt, &plic_base, &plic_ndev, "riscv,plic0") == 0) {
plic.reset(new plic_t(procs, true, plic_ndev));
bus.add_device(plic_base, plic.get());
+ intctrl = plic.get();
+ }
+
+ // create ns16550
+ reg_t ns16550_base;
+ uint32_t ns16550_shift, ns16550_io_width;
+ if (fdt_parse_ns16550(fdt, &ns16550_base,
+ &ns16550_shift, &ns16550_io_width, "ns16550a") == 0) {
+ assert(intctrl);
+ ns16550.reset(new ns16550_t(&bus, intctrl, NS16550_INTERRUPT_ID,
+ ns16550_shift, ns16550_io_width));
+ bus.add_device(ns16550_base, ns16550.get());
}
//per core attribute
@@ -228,6 +243,7 @@ void sim_t::step(size_t n)
if (++current_proc == procs.size()) {
current_proc = 0;
if (clint) clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK);
+ if (ns16550) ns16550->tick();
}
host->switch_to();