-
Notifications
You must be signed in to change notification settings - Fork 1
/
tinsel-interface.h
210 lines (162 loc) · 6.12 KB
/
tinsel-interface.h
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// SPDX-License-Identifier: BSD-2-Clause
#ifndef _TINSEL_INTERFACE_H_
#define _TINSEL_INTERFACE_H_
#include <stdint.h>
#include <config.h>
#include <io.h>
#define INLINE inline __attribute__((always_inline))
// Get globally unique thread id of caller
INLINE uint32_t tinselId();
// Read cycle counter
INLINE uint32_t tinselCycleCount();
// Cache flush
INLINE void tinselCacheFlush();
// Flush cache line
INLINE void tinselFlushLine(uint32_t lineNum, uint32_t way);
// Write a word to instruction memory
INLINE void tinselWriteInstr(uint32_t addr, uint32_t word);
// Emit word to console (simulation only)
INLINE void tinselEmit(uint32_t x);
// Send byte to host (over DebugLink UART)
// (Returns non-zero on success)
INLINE uint32_t tinselUartTryPut(uint8_t x);
// Receive byte from host (over DebugLink UART)
// (Byte present in bits [7:0]; bit 8 indicates validity)
INLINE uint32_t tinselUartTryGet();
// Insert new thread (with given id) into run queue
INLINE void tinselCreateThread(uint32_t id);
// Do not insert currently running thread back in to run queue
INLINE void tinselKillThread();
// Tell mailbox that given message slot is no longer needed
INLINE void tinselFree(volatile void* addr);
// Determine if calling thread can send a message
INLINE int tinselCanSend();
// Determine if calling thread can receive a message
INLINE int tinselCanRecv();
// Get pointer to thread's message slot reserved for sending
INLINE volatile void* tinselSendSlot();
// Set message length for send operation
// (A message of length N is comprised of N+1 flits)
INLINE void tinselSetLen(int n);
// Send message to multiple threads on the given mailbox
INLINE void tinselMulticast(
uint32_t mboxDest, // Destination mailbox
uint32_t destMaskHigh, // Destination bit mask (high bits)
uint32_t destMaskLow, // Destination bit mask (low bits)
volatile void* addr); // Message pointer
// Send message at addr to dest
INLINE void tinselSend(int dest, volatile void* addr);
// Receive message
INLINE volatile void* tinselRecv();
// Thread can be woken by a logical-OR of these events
typedef enum {TINSEL_CAN_SEND = 1, TINSEL_CAN_RECV = 2} TinselWakeupCond;
// Suspend thread until wakeup condition satisfied
INLINE void tinselWaitUntil(TinselWakeupCond cond);
// Suspend thread until message arrives or all threads globally are idle
INLINE int tinselIdle();
#ifdef __cplusplus
INLINE TinselWakeupCond operator|(TinselWakeupCond a, TinselWakeupCond b);
#endif
// Get address of master host
// (Master host is accessible via mesh origin)
INLINE uint32_t tinselHostId()
{
return 1 << (1 + TinselMeshYBits + TinselMeshXBits +
TinselLogCoresPerBoard + TinselLogThreadsPerCore);
}
// Given thread id, return base address of thread's partition in DRAM
INLINE uint32_t tinselHeapBaseGeneric(uint32_t id)
{
uint32_t partId = id & (TinselThreadsPerDRAM-1);
uint32_t addr = TinselBytesPerDRAM -
((partId+1) << TinselLogBytesPerDRAMPartition);
// Use the partition-interleaved translation
addr |= 0x80000000;
return addr;
}
// Given thread id, return base address of thread's partition in SRAM
INLINE uint32_t tinselHeapBaseSRAMGeneric(uint32_t id)
{
uint32_t partId = id & (TinselThreadsPerDRAM-1);
uint32_t addr = (1 << TinselLogBytesPerSRAM)
+ (partId << TinselLogBytesPerSRAMPartition);
return addr;
}
// Return pointer to base of calling thread's DRAM partition
INLINE void* tinselHeapBase();
// Return pointer to base of calling thread's SRAM partition
INLINE void* tinselHeapBaseSRAM();
// Reset performance counters
INLINE void tinselPerfCountReset();
// Start performance counters
INLINE void tinselPerfCountStart();
// Stop performance counters
INLINE void tinselPerfCountStop();
// Performance counter: get the cache miss count
INLINE uint32_t tinselMissCount();
// Performance counter: get the cache hit count
INLINE uint32_t tinselHitCount();
// Performance counter: get the cache writeback count
INLINE uint32_t tinselWritebackCount();
// Performance counter: get the CPU-idle count
INLINE uint32_t tinselCPUIdleCount();
// Performance counter: get the CPU-idle count (upper 8 bits)
INLINE uint32_t tinselCPUIdleCountU();
// Read cycle counter (upper 8 bits)
INLINE uint32_t tinselCycleCountU();
// Address construction
INLINE uint32_t tinselToAddr(
uint32_t boardX, uint32_t boardY,
uint32_t tileX, uint32_t tileY,
uint32_t coreId, uint32_t threadId)
{
uint32_t addr;
addr = boardY;
addr = (addr << TinselMeshXBits) | boardX;
addr = (addr << TinselMailboxMeshYBits) | tileY;
addr = (addr << TinselMailboxMeshXBits) | tileX;
addr = (addr << TinselLogCoresPerMailbox) | coreId;
addr = (addr << TinselLogThreadsPerCore) | threadId;
return addr;
}
// Address deconstruction
INLINE void tinselFromAddr(uint32_t addr,
uint32_t* boardX, uint32_t* boardY,
uint32_t* tileX, uint32_t* tileY,
uint32_t* coreId, uint32_t* threadId)
{
*threadId = addr & ((1 << TinselLogThreadsPerCore) - 1);
addr >>= TinselLogThreadsPerCore;
*coreId = addr & ((1 << TinselLogCoresPerMailbox) - 1);
addr >>= TinselLogCoresPerMailbox;
*tileX = addr & ((1 << TinselMailboxMeshXBits) - 1);
addr >>= TinselMailboxMeshXBits;
*tileY = addr & ((1 << TinselMailboxMeshYBits) - 1);
addr >>= TinselMailboxMeshYBits;
*boardX = addr & ((1 << TinselMeshXBits) - 1);
addr >>= TinselMeshXBits;
*boardY = addr & ((1 << TinselMeshYBits) - 1);
}
// Get address of specified custom accelerator
INLINE uint32_t tinselAccId(
uint32_t boardX, uint32_t boardY,
uint32_t tileX, uint32_t tileY)
{
uint32_t addr;
addr = 0x8;
addr = (addr << TinselMeshYBits) | boardY;
addr = (addr << TinselMeshXBits) | boardX;
addr = (addr << TinselMailboxMeshYBits) | tileY;
addr = (addr << TinselMailboxMeshXBits) | tileX;
addr = addr << (TinselLogCoresPerMailbox+TinselLogThreadsPerCore);
return addr;
}
// Special address to signify use of routing key
INLINE uint32_t tinselUseRoutingKey()
{
// Special address to signify use of routing key
return 1 <<
(TinselMailboxMeshYBits + TinselMailboxMeshXBits +
TinselMeshXBits + TinselMeshYBits + 2);
}
#endif