summaryrefslogtreecommitdiff
path: root/tb/avalon.impl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'tb/avalon.impl.hpp')
-rw-r--r--tb/avalon.impl.hpp183
1 files changed, 0 insertions, 183 deletions
diff --git a/tb/avalon.impl.hpp b/tb/avalon.impl.hpp
deleted file mode 100644
index 12483f9..0000000
--- a/tb/avalon.impl.hpp
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef TALLER_AVALON_IMPL_HPP
-#define TALLER_AVALON_IMPL_HPP
-
-#include <cassert>
-#include <cstdio>
-
-namespace taller::avalon
-{
- template<class Platform>
- inline interconnect<Platform>::interconnect(Platform &plat) noexcept
- : plat(plat)
- {}
-
- template<class Platform>
- void interconnect<Platform>::attach(slave &dev)
- {
- auto base = dev.base_address();
- auto mask = dev.address_mask();
- assert((base & mask) == base);
-
- devices.push_back(binding { base, mask, dev });
- }
-
- template<class Platform>
- void interconnect<Platform>::attach_intc(interrupt_controller &intc)
- {
- assert(root_intc == nullptr);
-
- attach(intc.as_slave());
- root_intc = &intc;
- }
-
- template<class Platform>
- bool interconnect<Platform>::tick(bool clk) noexcept
- {
- if (!plat.reset_reset_n) {
- active = nullptr;
- plat.avl_irq = 0;
-
- avl_read = false;
- avl_write = false;
- avl_address = 0;
- avl_byteenable = 0;
-
- return true;
- }
-
- if (active) {
- assert(avl_address == plat.avl_address);
- assert(avl_read == plat.avl_read);
- assert(avl_write == plat.avl_write);
- assert(avl_writedata == plat.avl_writedata);
- assert(avl_byteenable == plat.avl_byteenable);
- }
-
- if (!clk) {
- tick_falling();
- return true;
- } else if (!active)
- assert(!avl_read || !avl_write);
-
- try {
- tick_rising();
- return true;
- } catch (const avl_bus_error&) {
- return false;
- }
- }
-
- template<class Platform>
- void interconnect<Platform>::tick_rising()
- {
- for (auto &binding : devices)
- binding.dev.tick();
-
- if (root_intc)
- plat.avl_irq = root_intc->irq();
-
- if (!active) {
- avl_address = plat.avl_address;
- avl_read = plat.avl_read;
- avl_write = plat.avl_write;
- avl_writedata = plat.avl_writedata;
- avl_byteenable = plat.avl_byteenable;
-
- if (!avl_read && !avl_write)
- return;
-
- for (auto &binding : devices)
- if ((avl_address & binding.mask) == binding.base) {
- active = &binding.dev;
- break;
- }
-
- if (!active) [[unlikely]] {
- bail();
-
- const char *op = avl_read ? "read" : "write";
- fprintf(stderr, "[avl] attempt to %s memory hole at 0x%08x\n", op, avl_address);
-
- throw avl_bus_error{"memory hole addressed"};
- } else if(avl_address & 0b1111) [[unlikely]] {
- bail();
- fprintf(stderr, "[avl] unaligned address: 0x%08x\n", avl_address);
-
- throw avl_bus_error{"unaligned address"};
- }
- }
-
- auto pos = (avl_address & ~active->address_mask()) >> 4;
-
- if (avl_read) {
- line readdata;
- plat.avl_waitrequest = !active->read_line(pos, readdata, avl_byteenable);
- plat.avl_readdata = readdata;
- } else if (avl_write)
- plat.avl_waitrequest = !active->write_line(pos, avl_writedata, avl_byteenable);
- }
-
- template<class Platform>
- void interconnect<Platform>::tick_falling() noexcept
- {
- for (auto &binding : devices)
- binding.dev.tick_falling();
-
- if (!plat.avl_waitrequest)
- active = nullptr;
- }
-
- template<class Platform>
- void interconnect<Platform>::bail() noexcept
- {
- for (auto &binding : devices)
- binding.dev.bail();
- }
-
- template<class Platform>
- bool interconnect<Platform>::dump(std::uint32_t addr, std::uint32_t &word)
- {
- std::uint32_t avl_address = addr << 2;
-
- auto *dev = resolve_external(avl_address);
- if (!dev)
- return false;
-
- auto pos = (avl_address & ~dev->address_mask()) >> dev->word_bits();
-
- while (!dev->read(pos, word))
- continue;
-
- return true;
- }
-
- template<class Platform>
- bool interconnect<Platform>::patch(std::uint32_t addr, std::uint32_t writedata)
- {
- std::uint32_t avl_address = addr << 2;
-
- auto *dev = resolve_external(avl_address);
- if (!dev)
- return false;
-
- auto pos = (avl_address & ~dev->address_mask()) >> dev->word_bits();
-
- while (!dev->write(pos, writedata, 0b1111))
- continue;
-
- return true;
- }
-
- template<class Platform>
- slave* interconnect<Platform>::resolve_external(std::uint32_t avl_address)
- {
- for (auto &binding : devices)
- if ((avl_address & binding.mask) == binding.base)
- return &binding.dev;
-
- fprintf(stderr, "[avl] attempt to access hole at 0x%08x\n", avl_address);
- return nullptr;
- }
-}
-
-#endif