aboutsummaryrefslogtreecommitdiff
path: root/riscv/devices.h
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/devices.h
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/devices.h')
-rw-r--r--riscv/devices.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/riscv/devices.h b/riscv/devices.h
index c9e4f66..df7b289 100644
--- a/riscv/devices.h
+++ b/riscv/devices.h
@@ -7,6 +7,7 @@
#include "abstract_interrupt_controller.h"
#include "platform.h"
#include <map>
+#include <queue>
#include <vector>
#include <utility>
@@ -117,6 +118,36 @@ class plic_t : public abstract_device_t, public abstract_interrupt_controller_t
reg_t offset, uint32_t val);
};
+class ns16550_t : public abstract_device_t {
+ public:
+ ns16550_t(class bus_t *bus, abstract_interrupt_controller_t *intctrl,
+ uint32_t interrupt_id, uint32_t reg_shift, uint32_t reg_io_width);
+ bool load(reg_t addr, size_t len, uint8_t* bytes);
+ bool store(reg_t addr, size_t len, const uint8_t* bytes);
+ void tick(void);
+ size_t size() { return NS16550_SIZE; }
+ private:
+ class bus_t *bus;
+ abstract_interrupt_controller_t *intctrl;
+ uint32_t interrupt_id;
+ uint32_t reg_shift;
+ uint32_t reg_io_width;
+ std::queue<uint8_t> rx_queue;
+ uint8_t dll;
+ uint8_t dlm;
+ uint8_t iir;
+ uint8_t ier;
+ uint8_t fcr;
+ uint8_t lcr;
+ uint8_t mcr;
+ uint8_t lsr;
+ uint8_t msr;
+ uint8_t scr;
+ void update_interrupt(void);
+ uint8_t rx_byte(void);
+ void tx_byte(uint8_t val);
+};
+
class mmio_plugin_device_t : public abstract_device_t {
public:
mmio_plugin_device_t(const std::string& name, const std::string& args);