diff options
author | Anup Patel <anup@brainfault.org> | 2021-12-14 19:18:32 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-04-20 11:24:35 +0530 |
commit | 191634d2854dfed448fc323195f9b65c305e2d77 (patch) | |
tree | 47193b8ed63049f264211a87e9402c82660c7f85 /riscv/devices.h | |
parent | 5a433081f4ce1a49ee83d1a81cf4922e7542a20c (diff) | |
download | spike-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.h | 31 |
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); |