diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-12-13 21:43:25 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-12-16 16:29:10 -0600 |
| commit | 0c63c46e31642d0102542a745af6b445a9d22b3b (patch) | |
| tree | 0e8b6db18829e4a3d6c894af206f2b5257815827 /tb/avalon.hpp | |
| parent | d564e3538a3654facc94bb4cd1ee021830dfcf52 (diff) | |
Implement interrupt controller
Diffstat (limited to 'tb/avalon.hpp')
| -rw-r--r-- | tb/avalon.hpp | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/tb/avalon.hpp b/tb/avalon.hpp index 347c8bd..95bbe78 100644 --- a/tb/avalon.hpp +++ b/tb/avalon.hpp @@ -11,7 +11,7 @@ namespace taller::avalon class slave { public: - inline slave(std::uint32_t base, std::uint32_t size, std::size_t word_size) + inline slave(std::uint32_t base, std::uint32_t size, std::size_t word_size) noexcept : base(base), mask(~(size - 1)), word(log2i(word_size)) @@ -59,6 +59,11 @@ namespace taller::avalon virtual bool read(std::uint32_t addr, std::uint32_t &data) = 0; virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) = 0; + inline virtual bool irq() noexcept + { + return false; + } + private: std::uint32_t base; std::uint32_t mask; @@ -70,6 +75,39 @@ namespace taller::avalon } }; + struct irq_lines + { + slave *timer = nullptr; + slave *jtaguart = nullptr; + }; + + class interrupt_controller : private slave + { + public: + interrupt_controller(std::uint32_t base) noexcept; + + virtual bool read(std::uint32_t addr, std::uint32_t &data) noexcept final override; + virtual bool write(std::uint32_t addr, std::uint32_t data, unsigned byte_enable) noexcept final override; + + virtual bool irq() noexcept; + + inline slave &as_slave() noexcept + { + return *this; + } + + inline irq_lines &lines() noexcept + { + return irqs; + } + + private: + irq_lines irqs; + std::uint32_t mask = 0; + + std::uint32_t status() noexcept; + }; + template<class Platform> class interconnect { @@ -78,6 +116,7 @@ namespace taller::avalon bool tick(bool clk); void attach(slave &dev); + void attach_intc(interrupt_controller &intc); void bail() noexcept; bool dump(std::uint32_t addr, std::uint32_t &word); @@ -91,14 +130,15 @@ namespace taller::avalon slave &dev; }; - Platform &plat; - slave* active = nullptr; - std::vector<binding> devices; - std::uint32_t avl_address = 0; - std::uint32_t avl_writedata = 0; - unsigned avl_byteenable = 0; - bool avl_read = false; - bool avl_write = false; + Platform &plat; + slave* active = nullptr; + std::vector<binding> devices; + interrupt_controller *root_intc = nullptr; + std::uint32_t avl_address = 0; + std::uint32_t avl_writedata = 0; + unsigned avl_byteenable = 0; + bool avl_read = false; + bool avl_write = false; slave *resolve_external(std::uint32_t avl_address); }; |
