aboutsummaryrefslogtreecommitdiff
path: root/fesvr/tsi.cc
diff options
context:
space:
mode:
Diffstat (limited to 'fesvr/tsi.cc')
-rw-r--r--fesvr/tsi.cc115
1 files changed, 115 insertions, 0 deletions
diff --git a/fesvr/tsi.cc b/fesvr/tsi.cc
new file mode 100644
index 0000000..5ccafc4
--- /dev/null
+++ b/fesvr/tsi.cc
@@ -0,0 +1,115 @@
+#include "tsi.h"
+#include <cstdio>
+#include <cstdlib>
+
+#define NHARTS_MAX 16
+
+void tsi_t::host_thread(void *arg)
+{
+ tsi_t *tsi = static_cast<tsi_t*>(arg);
+ tsi->run();
+
+ while (true)
+ tsi->target->switch_to();
+}
+
+tsi_t::tsi_t(int argc, char** argv) : htif_t(argc, argv)
+{
+ target = context_t::current();
+ host.init(host_thread, this);
+}
+
+tsi_t::~tsi_t(void)
+{
+}
+
+#define MSIP_BASE 0x2000000
+
+// Interrupt core 0 to make it start executing the program in DRAM
+void tsi_t::reset()
+{
+ uint32_t one = 1;
+
+ write_chunk(MSIP_BASE, sizeof(uint32_t), &one);
+}
+
+void tsi_t::push_addr(addr_t addr)
+{
+ for (int i = 0; i < SAI_ADDR_CHUNKS; i++) {
+ in_data.push_back(addr & 0xffffffff);
+ addr = addr >> 32;
+ }
+}
+
+void tsi_t::push_len(addr_t len)
+{
+ for (int i = 0; i < SAI_LEN_CHUNKS; i++) {
+ in_data.push_back(len & 0xffffffff);
+ len = len >> 32;
+ }
+}
+
+void tsi_t::read_chunk(addr_t taddr, size_t nbytes, void* dst)
+{
+ uint32_t *result = static_cast<uint32_t*>(dst);
+ size_t len = nbytes / sizeof(uint32_t);
+
+ in_data.push_back(SAI_CMD_READ);
+ push_addr(taddr);
+ push_len(len - 1);
+
+ for (size_t i = 0; i < len; i++) {
+ while (out_data.empty())
+ switch_to_target();
+ result[i] = out_data.front();
+ out_data.pop_front();
+ }
+}
+
+void tsi_t::write_chunk(addr_t taddr, size_t nbytes, const void* src)
+{
+ const uint32_t *src_data = static_cast<const uint32_t*>(src);
+ size_t len = nbytes / sizeof(uint32_t);
+
+ in_data.push_back(SAI_CMD_WRITE);
+ push_addr(taddr);
+ push_len(len - 1);
+
+ in_data.insert(in_data.end(), src_data, src_data + len);
+}
+
+void tsi_t::send_word(uint32_t word)
+{
+ out_data.push_back(word);
+}
+
+uint32_t tsi_t::recv_word(void)
+{
+ uint32_t word = in_data.front();
+ in_data.pop_front();
+ return word;
+}
+
+bool tsi_t::data_available(void)
+{
+ return !in_data.empty();
+}
+
+void tsi_t::switch_to_host(void)
+{
+ host.switch_to();
+}
+
+void tsi_t::switch_to_target(void)
+{
+ target->switch_to();
+}
+
+void tsi_t::tick(bool out_valid, uint32_t out_bits, bool in_ready)
+{
+ if (out_valid && out_ready())
+ out_data.push_back(out_bits);
+
+ if (in_valid() && in_ready)
+ in_data.pop_front();
+}