1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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();
}
|