#include "tsi.h" #include #include #define NHARTS_MAX 16 void tsi_t::host_thread(void *arg) { tsi_t *tsi = static_cast(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(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(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(); }