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#include "qemu/osdep.h"
28#include "libqtest.h"
29
30
31#define CAN0_BASE_ADDR 0xFF060000
32#define CAN1_BASE_ADDR 0xFF070000
33
34
35#define R_SRR_OFFSET 0x00
36#define R_MSR_OFFSET 0x04
37#define R_SR_OFFSET 0x18
38#define R_ISR_OFFSET 0x1C
39#define R_ICR_OFFSET 0x24
40#define R_TXID_OFFSET 0x30
41#define R_TXDLC_OFFSET 0x34
42#define R_TXDATA1_OFFSET 0x38
43#define R_TXDATA2_OFFSET 0x3C
44#define R_RXID_OFFSET 0x50
45#define R_RXDLC_OFFSET 0x54
46#define R_RXDATA1_OFFSET 0x58
47#define R_RXDATA2_OFFSET 0x5C
48#define R_AFR 0x60
49#define R_AFMR1 0x64
50#define R_AFIR1 0x68
51#define R_AFMR2 0x6C
52#define R_AFIR2 0x70
53#define R_AFMR3 0x74
54#define R_AFIR3 0x78
55#define R_AFMR4 0x7C
56#define R_AFIR4 0x80
57
58
59#define CONFIG_MODE 0x00
60#define NORMAL_MODE 0x00
61#define LOOPBACK_MODE 0x02
62#define SNOOP_MODE 0x04
63#define SLEEP_MODE 0x01
64#define ENABLE_CAN (1 << 1)
65#define STATUS_NORMAL_MODE (1 << 3)
66#define STATUS_LOOPBACK_MODE (1 << 1)
67#define STATUS_SNOOP_MODE (1 << 12)
68#define STATUS_SLEEP_MODE (1 << 2)
69#define ISR_TXOK (1 << 1)
70#define ISR_RXOK (1 << 4)
71
72static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
73 uint8_t can_timestamp)
74{
75 uint16_t size = 0;
76 uint8_t len = 4;
77
78 while (size < len) {
79 if (R_RXID_OFFSET + 4 * size == R_RXDLC_OFFSET) {
80 g_assert_cmpint(buf_rx[size], ==, buf_tx[size] + can_timestamp);
81 } else {
82 g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
83 }
84
85 size++;
86 }
87}
88
89static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
90{
91 uint32_t int_status;
92
93
94 int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
95
96 g_assert_cmpint(int_status, ==, ISR_RXOK);
97
98
99 buf_rx[0] = qtest_readl(qts, can_base_addr + R_RXID_OFFSET);
100 buf_rx[1] = qtest_readl(qts, can_base_addr + R_RXDLC_OFFSET);
101 buf_rx[2] = qtest_readl(qts, can_base_addr + R_RXDATA1_OFFSET);
102 buf_rx[3] = qtest_readl(qts, can_base_addr + R_RXDATA2_OFFSET);
103
104
105 qtest_writel(qts, CAN1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
106}
107
108static void send_data(QTestState *qts, uint64_t can_base_addr,
109 const uint32_t *buf_tx)
110{
111 uint32_t int_status;
112
113
114 qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
115 qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
116 qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]);
117 qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]);
118
119
120 int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK;
121
122 g_assert_cmpint(int_status, ==, ISR_TXOK);
123
124
125 qtest_writel(qts, CAN0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK);
126}
127
128
129
130
131
132
133static void test_can_bus(void)
134{
135 const uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
136 uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
137 uint32_t status = 0;
138 uint8_t can_timestamp = 1;
139
140 QTestState *qts = qtest_init("-machine xlnx-zcu102"
141 " -object can-bus,id=canbus"
142 " -machine canbus0=canbus"
143 " -machine canbus1=canbus"
144 );
145
146
147 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
148 qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
149 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
150 qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
151
152
153 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
154 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
155
156 status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
157 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
158
159 send_data(qts, CAN0_BASE_ADDR, buf_tx);
160
161 read_data(qts, CAN1_BASE_ADDR, buf_rx);
162 match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
163
164 qtest_quit(qts);
165}
166
167
168
169
170
171static void test_can_loopback(void)
172{
173 uint32_t buf_tx[4] = { 0xFF, 0x80000000, 0x12345678, 0x87654321 };
174 uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
175 uint32_t status = 0;
176
177 QTestState *qts = qtest_init("-machine xlnx-zcu102"
178 " -object can-bus,id=canbus"
179 " -machine canbus0=canbus"
180 " -machine canbus1=canbus"
181 );
182
183
184 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
185 qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
186 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
187
188
189 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
190
191 g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
192
193 send_data(qts, CAN0_BASE_ADDR, buf_tx);
194 read_data(qts, CAN0_BASE_ADDR, buf_rx);
195 match_rx_tx_data(buf_tx, buf_rx, 0);
196
197
198 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
199 qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, LOOPBACK_MODE);
200 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
201
202
203 status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
204
205 g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
206
207 send_data(qts, CAN1_BASE_ADDR, buf_tx);
208 read_data(qts, CAN1_BASE_ADDR, buf_rx);
209 match_rx_tx_data(buf_tx, buf_rx, 0);
210
211 qtest_quit(qts);
212}
213
214
215
216
217
218static void test_can_filter(void)
219{
220 uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
221 uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
222 uint32_t status = 0;
223 uint8_t can_timestamp = 1;
224
225 QTestState *qts = qtest_init("-machine xlnx-zcu102"
226 " -object can-bus,id=canbus"
227 " -machine canbus0=canbus"
228 " -machine canbus1=canbus"
229 );
230
231
232 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
233 qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
234 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
235 qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
236
237
238 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
239 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
240
241 status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
242 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
243
244
245 qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0x0);
246 qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR1, 0xF7);
247 qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR1, 0x121F);
248 qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR2, 0x5431);
249 qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR2, 0x14);
250 qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR3, 0x1234);
251 qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR3, 0x5431);
252 qtest_writel(qts, CAN1_BASE_ADDR + R_AFMR4, 0xFFF);
253 qtest_writel(qts, CAN1_BASE_ADDR + R_AFIR4, 0x1234);
254
255 qtest_writel(qts, CAN1_BASE_ADDR + R_AFR, 0xF);
256
257 send_data(qts, CAN0_BASE_ADDR, buf_tx);
258
259 read_data(qts, CAN1_BASE_ADDR, buf_rx);
260 match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
261
262 qtest_quit(qts);
263}
264
265
266static void test_can_sleepmode(void)
267{
268 uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
269 uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
270 uint32_t status = 0;
271 uint8_t can_timestamp = 1;
272
273 QTestState *qts = qtest_init("-machine xlnx-zcu102"
274 " -object can-bus,id=canbus"
275 " -machine canbus0=canbus"
276 " -machine canbus1=canbus"
277 );
278
279
280 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
281 qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SLEEP_MODE);
282 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
283
284 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
285 qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
286
287
288 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
289 g_assert_cmpint(status, ==, STATUS_SLEEP_MODE);
290
291 status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
292 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
293
294 send_data(qts, CAN1_BASE_ADDR, buf_tx);
295
296
297
298
299
300
301 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
302 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
303
304 read_data(qts, CAN0_BASE_ADDR, buf_rx);
305
306 match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
307
308 qtest_quit(qts);
309}
310
311
312static void test_can_snoopmode(void)
313{
314 uint32_t buf_tx[4] = { 0x14, 0x80000000, 0x12345678, 0x87654321 };
315 uint32_t buf_rx[4] = { 0x00, 0x00, 0x00, 0x00 };
316 uint32_t status = 0;
317 uint8_t can_timestamp = 1;
318
319 QTestState *qts = qtest_init("-machine xlnx-zcu102"
320 " -object can-bus,id=canbus"
321 " -machine canbus0=canbus"
322 " -machine canbus1=canbus"
323 );
324
325
326 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, CONFIG_MODE);
327 qtest_writel(qts, CAN0_BASE_ADDR + R_MSR_OFFSET, SNOOP_MODE);
328 qtest_writel(qts, CAN0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
329
330 qtest_writel(qts, CAN1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CAN);
331 qtest_writel(qts, CAN1_BASE_ADDR + R_MSR_OFFSET, NORMAL_MODE);
332
333
334 status = qtest_readl(qts, CAN0_BASE_ADDR + R_SR_OFFSET);
335 g_assert_cmpint(status, ==, STATUS_SNOOP_MODE);
336
337 status = qtest_readl(qts, CAN1_BASE_ADDR + R_SR_OFFSET);
338 g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
339
340 send_data(qts, CAN1_BASE_ADDR, buf_tx);
341
342 read_data(qts, CAN0_BASE_ADDR, buf_rx);
343
344 match_rx_tx_data(buf_tx, buf_rx, can_timestamp);
345
346 qtest_quit(qts);
347}
348
349int main(int argc, char **argv)
350{
351 g_test_init(&argc, &argv, NULL);
352
353 qtest_add_func("/net/can/can_bus", test_can_bus);
354 qtest_add_func("/net/can/can_loopback", test_can_loopback);
355 qtest_add_func("/net/can/can_filter", test_can_filter);
356 qtest_add_func("/net/can/can_test_snoopmode", test_can_snoopmode);
357 qtest_add_func("/net/can/can_test_sleepmode", test_can_sleepmode);
358
359 return g_test_run();
360}
361