| #ifndef LEARNING_BRAIN_RESEARCH_MPACT_SIM_CHERI_RISCV_SIMPLE_UART_H_ |
| #define LEARNING_BRAIN_RESEARCH_MPACT_SIM_CHERI_RISCV_SIMPLE_UART_H_ |
| |
| #include <cstdint> |
| #include <ostream> |
| |
| #include "mpact/sim/generic/arch_state.h" |
| #include "mpact/sim/generic/data_buffer.h" |
| #include "mpact/sim/generic/instruction.h" |
| #include "mpact/sim/generic/ref_count.h" |
| #include "mpact/sim/util/memory/memory_interface.h" |
| |
| // This file declares the class to implement a very trivial uart with only |
| // output capabilities for now. The following memory mapped registers are |
| // defined: |
| // |
| // Offset: Dlab: Semantics: |
| // 0x0000 1 Divisor latch low byte. |
| // 0x0000 0 TX(write)/RX(read) buffer. |
| // 0x0004 1 Divisor latch high byte. |
| // 0x0004 0 Interrupt enable register. |
| // 0x0008 x Interrupt identification register. |
| // 0x000c x Line control register. |
| // 0x0010 x Modem control register. |
| // 0x0014 x Line status register. |
| // 0x0018 x Modem status register. |
| // 0x001c x Scratch register. |
| |
| namespace mpact::sim::util { |
| |
| using ::mpact::sim::generic::ArchState; |
| using ::mpact::sim::generic::DataBuffer; |
| using ::mpact::sim::generic::Instruction; |
| using ::mpact::sim::generic::ReferenceCount; |
| using ::mpact::sim::util::MemoryInterface; |
| |
| class SimpleUart : public MemoryInterface { |
| public: |
| // Constructors. |
| // Instantiate the uart and set the output to std::cerr. |
| explicit SimpleUart(ArchState *state); |
| // Instantiate the uart and set the output to the given ostream. |
| SimpleUart(ArchState *state, std::ostream &output); |
| |
| // Memory interface methods used to write to the memory mapped registers. |
| void Load(uint64_t address, DataBuffer *db, Instruction *inst, |
| ReferenceCount *context) override; |
| void Load(DataBuffer *address_db, DataBuffer *mask_db, int el_size, |
| DataBuffer *db, Instruction *inst, |
| ReferenceCount *context) override; |
| void Store(uint64_t address, DataBuffer *db) override; |
| void Store(DataBuffer *address, DataBuffer *mask_db, int el_size, |
| DataBuffer *db) override; |
| |
| private: |
| // Helper methods. |
| uint32_t Read(uint32_t offset); |
| void Write(uint32_t offset, uint32_t value); |
| // The dlab_ bit of the line control register. The dlab bit changes the |
| // register map for offsets 0x0 and 0x4 when set. |
| bool dlab_ = false; |
| // Selected uart registers. |
| uint32_t line_control_reg_ = 0; |
| uint32_t divisor_high_byte_ = 0; |
| uint32_t divisor_low_byte_ = 0; |
| uint32_t interrupt_enable_ = 0; |
| uint32_t scratch_; |
| std::ostream *output_; |
| }; |
| |
| } // namespace mpact::sim::util |
| |
| #endif // LEARNING_BRAIN_RESEARCH_MPACT_SIM_CHERI_RISCV_SIMPLE_UART_H_ |