1 /*
2 * QTest testcase for the remote I3C device, using the AST2600 I3C controller.
3 *
4 * Copyright 2023 Google LLC
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "qemu/osdep.h"
18 #include "libqtest-single.h"
19 #include "hw/registerfields.h"
20 #include "hw/i3c/i3c.h"
21 #include "hw/i3c/remote-i3c.h"
22 #include "hw/i3c/aspeed_i3c.h"
23
24 /* Starting address of the AST2600 I3C block. */
25 #define ASPEED_I3C_BASE 0x1e7a0000
26 /* Offset to the first controller in the block. */
27 #define ASPEED_I3C_CONTROLLER_OFFSET 0x2000
28 #define I3C(x) (ASPEED_I3C_BASE + ASPEED_I3C_CONTROLLER_OFFSET + ((x) * 0x1000))
29 #define TARGET_ADDR 0x10
30
31 /* I3C Device Registers */
32 REG32(DEVICE_CTRL, 0x00)
33 FIELD(DEVICE_CTRL, I3C_BROADCAST_ADDR_INC, 0, 1)
34 FIELD(DEVICE_CTRL, I2C_SLAVE_PRESENT, 7, 1)
35 FIELD(DEVICE_CTRL, HOT_JOIN_ACK_NACK_CTRL, 8, 1)
36 FIELD(DEVICE_CTRL, IDLE_CNT_MULTIPLIER, 24, 2)
37 FIELD(DEVICE_CTRL, SLV_ADAPT_TO_I2C_I3C_MODE, 27, 1)
38 FIELD(DEVICE_CTRL, DMA_HANDSHAKE_EN, 28, 1)
39 FIELD(DEVICE_CTRL, I3C_ABORT, 29, 1)
40 FIELD(DEVICE_CTRL, I3C_RESUME, 30, 1)
41 FIELD(DEVICE_CTRL, I3C_EN, 31, 1)
42 REG32(COMMAND_QUEUE_PORT, 0x0c)
43 FIELD(COMMAND_QUEUE_PORT, CMD_ATTR, 0, 3)
44 /* Transfer command structure */
45 FIELD(COMMAND_QUEUE_PORT, TID, 3, 4)
46 FIELD(COMMAND_QUEUE_PORT, CMD, 7, 8)
47 FIELD(COMMAND_QUEUE_PORT, CP, 15, 1)
48 FIELD(COMMAND_QUEUE_PORT, DEV_INDEX, 16, 5)
49 FIELD(COMMAND_QUEUE_PORT, SPEED, 21, 3)
50 FIELD(COMMAND_QUEUE_PORT, ROC, 26, 1)
51 FIELD(COMMAND_QUEUE_PORT, SDAP, 27, 1)
52 FIELD(COMMAND_QUEUE_PORT, RNW, 28, 1)
53 FIELD(COMMAND_QUEUE_PORT, TOC, 30, 1)
54 FIELD(COMMAND_QUEUE_PORT, PEC, 31, 1)
55 /* Transfer argument data structure */
56 FIELD(COMMAND_QUEUE_PORT, DB, 8, 8)
57 FIELD(COMMAND_QUEUE_PORT, DL, 16, 16)
58 /* Short data argument data structure */
59 FIELD(COMMAND_QUEUE_PORT, BYTE_STRB, 3, 3)
60 FIELD(COMMAND_QUEUE_PORT, BYTE0, 8, 8)
61 FIELD(COMMAND_QUEUE_PORT, BYTE1, 16, 8)
62 FIELD(COMMAND_QUEUE_PORT, BYTE2, 24, 8)
63 /* Address assignment command structure */
64 /*
65 * bits 3..21 and 26..31 are the same as the transfer command structure, or
66 * marked as reserved.
67 */
68 FIELD(COMMAND_QUEUE_PORT, DEV_COUNT, 21, 3)
69 REG32(RESPONSE_QUEUE_PORT, 0x10)
70 FIELD(RESPONSE_QUEUE_PORT, DL, 0, 16)
71 FIELD(RESPONSE_QUEUE_PORT, CCCT, 16, 8)
72 FIELD(RESPONSE_QUEUE_PORT, TID, 24, 4)
73 FIELD(RESPONSE_QUEUE_PORT, ERR_STATUS, 28, 4)
74 REG32(RX_TX_DATA_PORT, 0x14)
75 REG32(IBI_QUEUE_STATUS, 0x18)
76 FIELD(IBI_QUEUE_STATUS, IBI_DATA_LEN, 0, 8)
77 FIELD(IBI_QUEUE_STATUS, IBI_ID, 8, 8)
78 FIELD(IBI_QUEUE_STATUS, IBI_RX_STATUS, 28, 4)
79 REG32(IBI_QUEUE_DATA, 0x18)
80 REG32(QUEUE_STATUS_LEVEL, 0x4c)
81 FIELD(QUEUE_STATUS_LEVEL, CMD_QUEUE_EMPTY_LOC, 0, 8)
82 FIELD(QUEUE_STATUS_LEVEL, RESP_BUF_BLR, 8, 8)
83 FIELD(QUEUE_STATUS_LEVEL, IBI_BUF_BLR, 16, 8)
84 FIELD(QUEUE_STATUS_LEVEL, IBI_STATUS_CNT, 24, 5)
85 REG32(DATA_BUFFER_STATUS_LEVEL, 0x50)
86 FIELD(DATA_BUFFER_STATUS_LEVEL, TX_BUF_EMPTY_LOC, 0, 8)
87 FIELD(DATA_BUFFER_STATUS_LEVEL, RX_BUF_BLR, 16, 8)
88 /* Dev addr table fields */
89 REG32(DEVICE_ADDR_TABLE_LOC1, 0x280)
90 FIELD(DEVICE_ADDR_TABLE_LOC1, DEV_DYNAMIC_ADDR, 16, 8)
91
92 typedef union AspeedI3CResponse {
93 uint32_t word;
94 uint16_t data_len;
95 uint8_t ccc_type;
96 uint8_t tid:4;
97 uint8_t err:4;
98 } AspeedI3CResponse;
99
100 static int sock;
101 static int fd;
102
open_socket(void)103 static in_port_t open_socket(void)
104 {
105 struct sockaddr_in myaddr;
106 struct timeval timeout = { .tv_sec = 1, };
107 socklen_t addrlen;
108
109 myaddr.sin_family = AF_INET;
110 myaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
111 myaddr.sin_port = 0;
112 sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
113 g_assert(sock != -1);
114 g_assert(bind(sock, (struct sockaddr *) &myaddr, sizeof(myaddr)) != -1);
115 setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
116
117 addrlen = sizeof(myaddr);
118 g_assert(getsockname(sock, (struct sockaddr *) &myaddr , &addrlen) != -1);
119 g_assert(listen(sock, 1) != -1);
120 return ntohs(myaddr.sin_port);
121 }
122
setup_fd(void)123 static void setup_fd(void)
124 {
125 fd_set readfds;
126
127 FD_ZERO(&readfds);
128 FD_SET(sock, &readfds);
129 g_assert(select(sock + 1, &readfds, NULL, NULL, NULL) == 1);
130
131 fd = accept(sock, NULL, 0);
132 }
133
aspeed_i3c_create_xfer_cmd(uint8_t cmd,uint8_t dev_index,bool rnw,bool dbp)134 static AspeedI3CTransferCmd aspeed_i3c_create_xfer_cmd(uint8_t cmd,
135 uint8_t dev_index,
136 bool rnw,
137 bool dbp)
138 {
139 return ((AspeedI3CTransferCmd) {
140 .cmd_attr = ASPEED_I3C_CMD_ATTR_TRANSFER_CMD,
141 .tid = 0x01,
142 .cmd = cmd,
143 .cp = (cmd != 0) ? 1 : 0,
144 .dev_index = dev_index,
145 .speed = 0, /* SDR */
146 .dbp = dbp,
147 .roc = 1,
148 .sdap = (cmd == 0x02) ? 1 : 0, /* Short data arg present. */
149 .rnw = rnw,
150 .toc = 1,
151 .pec = 0
152 });
153 }
154
aspeed_i3c_create_xfer_arg(uint8_t db,uint16_t data_len)155 static AspeedI3CTransferArg aspeed_i3c_create_xfer_arg(uint8_t db,
156 uint16_t data_len)
157 {
158 return ((AspeedI3CTransferArg) {
159 .cmd_attr = ASPEED_I3C_CMD_ATTR_TRANSFER_ARG,
160 .db = db,
161 .data_len = data_len,
162 });
163 }
164
aspeed_i3c_enable(uint32_t base)165 static void aspeed_i3c_enable(uint32_t base)
166 {
167 uint32_t val = readl(base + A_DEVICE_CTRL);
168 val = FIELD_DP32(val, DEVICE_CTRL, I3C_RESUME, 1);
169 val = FIELD_DP32(val, DEVICE_CTRL, I3C_EN, 1);
170 writel(base + A_DEVICE_CTRL, val);
171 /*
172 * Sanity check the enable write. I3C_RESUME is auto-cleared so don't
173 * check it.
174 */
175 g_assert(readl(base + A_DEVICE_CTRL) & R_DEVICE_CTRL_I3C_EN_MASK);
176 }
177
aspeed_i3c_read_resp(uint32_t base)178 static AspeedI3CResponse aspeed_i3c_read_resp(uint32_t base)
179 {
180 AspeedI3CResponse resp;
181 uint32_t queue_status = readl(base + A_QUEUE_STATUS_LEVEL);
182 /* No response to read. */
183 if (FIELD_EX32(queue_status, QUEUE_STATUS_LEVEL, RESP_BUF_BLR) == 0) {
184 resp.word = 0;
185 } else {
186 resp.word = readl(base + A_DEVICE_CTRL);
187 }
188 return resp;
189 }
190
aspeed_i3c_send(uint32_t base,uint8_t dev_index,const uint32_t * data,uint16_t len)191 static void aspeed_i3c_send(uint32_t base, uint8_t dev_index,
192 const uint32_t *data, uint16_t len)
193 {
194 AspeedI3CCmdQueueData cmd;
195 AspeedI3CCmdQueueData arg;
196 uint16_t words_txed = 0;
197
198 /* Start doing the transfer. */
199 while (words_txed < len) {
200 /* Push data to the TX queue. */
201 uint32_t tx_num_empty = FIELD_EX32(readl(base +
202 A_DATA_BUFFER_STATUS_LEVEL),
203 DATA_BUFFER_STATUS_LEVEL,
204 TX_BUF_EMPTY_LOC);
205 for (uint16_t i = 0; i < tx_num_empty; i++) {
206 writel(base + A_RX_TX_DATA_PORT, data[words_txed]);
207 words_txed++;
208 /* We have no more to transfer, bail early. */
209 if (words_txed >= len) {
210 break;
211 }
212 }
213
214 /* Now that the data is in the queue, we can start our transfer. */
215 /*
216 * CMD is ignored due to this not being a CCC, and there is no defining
217 * byte, also because this isn't a CCC.
218 */
219 cmd.transfer_cmd = aspeed_i3c_create_xfer_cmd(0, dev_index, false,
220 false);
221 arg.transfer_arg = aspeed_i3c_create_xfer_arg(0, len * sizeof(*data));
222 /* Order to push is arg then command. */
223 writel(base + A_COMMAND_QUEUE_PORT, arg.word);
224 writel(base + A_COMMAND_QUEUE_PORT, cmd.word);
225 }
226 }
227
aspeed_i3c_send_ccc(uint32_t base,uint8_t ccc_cmd)228 static void aspeed_i3c_send_ccc(uint32_t base, uint8_t ccc_cmd)
229 {
230 AspeedI3CCmdQueueData cmd;
231 AspeedI3CCmdQueueData arg;
232
233 cmd.transfer_cmd = aspeed_i3c_create_xfer_cmd(ccc_cmd, 0, false,
234 false);
235 arg.transfer_arg = aspeed_i3c_create_xfer_arg(0, 0);
236 /* Order to push is arg then command. */
237 writel(base + A_COMMAND_QUEUE_PORT, arg.word);
238 writel(base + A_COMMAND_QUEUE_PORT, cmd.word);
239 }
240
aspeed_i3c_recv(uint32_t base,uint8_t dev_index,uint8_t * data,uint16_t len)241 static void aspeed_i3c_recv(uint32_t base, uint8_t dev_index, uint8_t *data,
242 uint16_t len)
243 {
244 AspeedI3CCmdQueueData cmd;
245 AspeedI3CCmdQueueData arg;
246 uint16_t bytes_rxed = 0;
247 uint32_t *p32_data = (uint32_t *)data;
248
249 /* Start doing the transfer. */
250 while (bytes_rxed < len) {
251 /* Send the RX request. */
252 /*
253 * CMD is ignored due to this not being a CCC, and there is no defining
254 * byte, also because this isn't a CCC.
255 */
256 cmd.transfer_cmd = aspeed_i3c_create_xfer_cmd(0, dev_index, true,
257 false);
258 uint16_t num_to_rx = (len - bytes_rxed) > ASPEED_I3C_RX_QUEUE_CAPACITY ?
259 ASPEED_I3C_RX_QUEUE_CAPACITY : (len - bytes_rxed);
260 arg.transfer_arg = aspeed_i3c_create_xfer_arg(0, num_to_rx);
261 /* Order to push is arg then command. */
262 writel(base + A_COMMAND_QUEUE_PORT, arg.word);
263 writel(base + A_COMMAND_QUEUE_PORT, cmd.word);
264
265 /* Read the data from the data RX queue. */
266 uint32_t rx_word_num =
267 FIELD_EX32(readl(base + A_DATA_BUFFER_STATUS_LEVEL),
268 DATA_BUFFER_STATUS_LEVEL, RX_BUF_BLR);
269 for (uint16_t i = 0; i < rx_word_num; i++) {
270 *p32_data = readl(base + A_RX_TX_DATA_PORT);
271 p32_data++;
272 bytes_rxed += 4;
273 }
274 }
275 }
276
assert_good_resp(uint32_t base)277 static void assert_good_resp(uint32_t base)
278 {
279 /* We expect a good response from this. */
280 AspeedI3CResponse resp = aspeed_i3c_read_resp(base);
281 g_assert(resp.err == ASPEED_I3C_RESP_QUEUE_ERR_NONE);
282 }
283
read_data(uint8_t * data,size_t len)284 static void read_data(uint8_t *data, size_t len)
285 {
286 ssize_t ret;
287 size_t len_read = 0;
288
289 while (len_read < len) {
290 ret = read(fd, &data[len_read], len);
291 g_assert(ret != -1);
292 len_read += ret;
293 }
294 }
295
remote_i3c_read_and_verify(const uint8_t * expected_data,size_t len)296 static void remote_i3c_read_and_verify(const uint8_t *expected_data, size_t len)
297 {
298 g_autofree uint8_t *data_read = g_new0(uint8_t, len);
299
300 read_data(data_read, len);
301 g_assert(memcmp(data_read, expected_data, len) == 0);
302 }
303
add_targets_to_bus(uint32_t base)304 static void add_targets_to_bus(uint32_t base)
305 {
306 /* Arbitrary large enough size. */
307 uint8_t remote_target_expected_data[8];
308
309 /* Send SATAASA to the remote target. */
310 aspeed_i3c_send_ccc(base, I3C_CCC_SETAASA);
311 /*
312 * Verify everything is good.
313 * The remote target should receive:
314 * - an I3C_START event
315 * - the size of the CCC packet as a LE uint32
316 * - the CCC
317 * - then an I3C_STOP event.
318 * The controller should have a good response in the queue.
319 */
320 assert_good_resp(base);
321 remote_target_expected_data[0] = REMOTE_I3C_START_SEND;
322 remote_target_expected_data[1] = REMOTE_I3C_HANDLE_CCC_WRITE;
323 uint32_t *p32 = (uint32_t *)&remote_target_expected_data[2];
324 *p32 = htole32(1);
325 remote_target_expected_data[6] = I3C_CCC_SETAASA;
326 remote_target_expected_data[7] = REMOTE_I3C_STOP;
327 remote_i3c_read_and_verify(remote_target_expected_data, 8);
328
329 /*
330 * Populate the device table. On a real system we would either:
331 * - populate the table and send ENTDAA, then probe the addresses to see who
332 * exists.
333 * - SETAASA and then go through a list addresses to see who exists, probe
334 * them, and add them to the table.
335 * We're doing the SETAASA way, minus the probing portion, so just add the
336 * known address to the table.
337 */
338 uint32_t val = 0;
339 val = FIELD_DP32(val, DEVICE_ADDR_TABLE_LOC1, DEV_DYNAMIC_ADDR,
340 TARGET_ADDR);
341 writel(base + A_DEVICE_ADDR_TABLE_LOC1, val);
342 }
343
send_and_verify(uint32_t i3c_base,const uint32_t * data,size_t len)344 static void send_and_verify(uint32_t i3c_base, const uint32_t *data, size_t len)
345 {
346 /*
347 * Add padding to the data_read packet, since the remote target will receive
348 * extra bytes that include the I3C START and STOP events, along with the
349 * length of the packet, and the data packet itself.
350 */
351 uint32_t data_size = len * sizeof(*data);
352 size_t expected_data_len = data_size + 7;
353 g_autofree uint8_t *remote_target_expected_data = g_new0(uint8_t,
354 expected_data_len);
355 remote_target_expected_data[0] = REMOTE_I3C_START_SEND;
356 remote_target_expected_data[1] = REMOTE_I3C_SEND;
357 uint32_t *p32 = (uint32_t *)&remote_target_expected_data[2];
358 *p32 = htole32(data_size);
359 memcpy(&remote_target_expected_data[6], data, data_size);
360 remote_target_expected_data[data_size + 6] = REMOTE_I3C_STOP;
361
362 aspeed_i3c_send(i3c_base, 0, data, len);
363 assert_good_resp(i3c_base);
364 remote_i3c_read_and_verify(remote_target_expected_data, expected_data_len);
365 }
366
367 /* Remote target RX, e.g. controller -> target. */
test_remote_i3c_rx(gconstpointer test_data)368 static void test_remote_i3c_rx(gconstpointer test_data)
369 {
370 uint32_t controller_num = *(uint32_t *)test_data;
371 uint32_t i3c_base = I3C(controller_num);
372 /*
373 * The Aspeed controller expects data in 32-bit words, so make this 32-bits.
374 */
375 const uint32_t data[] = {7, 6, 5, 4, 3, 2, 1, 0};
376 /* Enable the controller. */
377 aspeed_i3c_enable(i3c_base);
378 /*
379 * Tell the target to use its static address as its dynamic address, and
380 * populate the device table.
381 */
382 add_targets_to_bus(i3c_base);
383 /* Now we can test sending data to the target. */
384 send_and_verify(i3c_base, data, ARRAY_SIZE(data));
385 }
386
read_and_verify(uint32_t i3c_base,const uint8_t * data,size_t len)387 static void read_and_verify(uint32_t i3c_base, const uint8_t *data, size_t len)
388 {
389 g_autofree uint8_t *data_received = g_new0(uint8_t, len);
390
391 /* Send the I3C recv request. */
392 aspeed_i3c_recv(i3c_base, 0, data_received, len);
393 /*
394 * Verify everything is okay. Anything on the remote I3C protocol level is
395 * handled by the remote target thread. We just need to check that we
396 * received what we expected.
397 */
398 assert_good_resp(i3c_base);
399 g_assert(memcmp(data_received, data, len) == 0);
400 }
401
remote_target_thread(void * arg)402 static void *remote_target_thread(void *arg)
403 {
404 uint8_t byte;
405 uint32_t bytes_to_send;
406 uint32_t bytes_to_send_le;
407 const uint8_t *data = (const uint8_t *)arg;
408
409 /* Loop forever reading and parsing incoming data. */
410 while (1) {
411 /*
412 * We can error out during program teardown due to the socket closing,
413 * so don't assert.
414 * If this has a proper error during test, the main thread will error
415 * due to the target thread (this one) not sending anything.
416 */
417 if (read(fd, &byte, 1) != 1) {
418 break;
419 }
420
421 switch (byte) {
422 case REMOTE_I3C_START_RECV:
423 case REMOTE_I3C_STOP:
424 /* Don't care, do nothing. */
425 break;
426 case REMOTE_I3C_RECV:
427 /* Read in the number of bytes the controller wants. */
428 g_assert(read(fd, &bytes_to_send_le, sizeof(bytes_to_send_le)) ==
429 sizeof(bytes_to_send_le));
430 bytes_to_send = le32toh(bytes_to_send_le);
431
432 /*
433 * Send the data. We first send the number of bytes we're sending as
434 * a uint32 LE word (which is the same as the number of bytes the
435 * controller is expecting), followed by the data.
436 */
437 g_assert(write(fd, (uint8_t *)&bytes_to_send_le,
438 sizeof(bytes_to_send_le)) ==
439 sizeof(bytes_to_send_le));
440 g_assert(write(fd, data, bytes_to_send) == bytes_to_send);
441 break;
442 default:
443 g_printerr("Remote target received unknown byte 0x%.2x\n", byte);
444 g_assert_not_reached();
445 }
446 }
447
448 return NULL;
449 }
450
451 /* Remote target TX, e.g. target -> controller. */
test_remote_i3c_tx(gconstpointer test_data)452 static void test_remote_i3c_tx(gconstpointer test_data)
453 {
454 uint32_t controller_num = *(uint32_t *)test_data;
455 uint32_t i3c_base = I3C(controller_num);
456 /* Non-const since the thread prototype needs a non-const pointer. */
457 uint8_t data[] = {7, 6, 5, 4, 3, 2, 1, 0};
458 GThread *target_thread;
459 /* Enable the controller. */
460 aspeed_i3c_enable(i3c_base);
461 /*
462 * Tell the target to use its static address as its dynamic address, and
463 * populate the device table.
464 */
465 add_targets_to_bus(i3c_base);
466
467 /*
468 * Now we can test receiving data from the target.
469 * The target will need to respond while the controller is doing the I3C
470 * receive (meaning we will be blocked on the remote target sending data to
471 * us), so we need to make a separate thread for the remote target to send
472 * data to the controller.
473 */
474 target_thread = g_thread_new("remote-target", remote_target_thread, data);
475 read_and_verify(i3c_base, data, ARRAY_SIZE(data));
476 g_thread_join(target_thread);
477 }
478
remote_i3c_ibi(const uint32_t * data,uint32_t len)479 static void remote_i3c_ibi(const uint32_t *data, uint32_t len)
480 {
481 /* Convert len to bytes to make math cleaner. */
482 len *= sizeof(uint32_t);
483 /*
484 * IBI format is:
485 * - 1-byte REMOTE_I3C_IBI request.
486 * - 1-byte address of target sending the IBI.
487 * - 1-byte RnW bit.
488 * - 4-byte size of IBI payload.
489 * - n-byte IBI payload.
490 */
491 size_t ibi_req_size = 7 + len;
492 g_autofree uint8_t *ibi_req = g_new0(uint8_t, ibi_req_size);
493 uint32_t len_le;
494 uint8_t ibi_resp;
495
496 ibi_req[0] = REMOTE_I3C_IBI;
497 ibi_req[1] = TARGET_ADDR;
498 ibi_req[2] = 0; /* RnW = 0 to make this a target interrupt request. */
499 len_le = htole32(len);
500 memcpy(&ibi_req[3], &len_le, sizeof(len_le));
501 memcpy(&ibi_req[7], data, len);
502
503 /* Send the request and read back the ACK. */
504 g_assert(write(fd, ibi_req, ibi_req_size) == ibi_req_size);
505 g_assert(read(fd, &ibi_resp, sizeof(ibi_resp)) == sizeof(ibi_resp));
506 g_assert(ibi_resp == REMOTE_I3C_IBI_ACK);
507 }
508
aspeed_i3c_read_ibi_and_verify(uint32_t i3c_base,const uint32_t * data,size_t len)509 static void aspeed_i3c_read_ibi_and_verify(uint32_t i3c_base,
510 const uint32_t *data, size_t len)
511 {
512 g_autofree uint32_t *ibi_data = g_new0(uint32_t, len * sizeof(uint32_t));
513
514 /* Make sure there's actually something to read in the IBI queue. */
515 uint8_t ibi_buf_lvl = FIELD_EX32(readl(i3c_base + A_QUEUE_STATUS_LEVEL),
516 QUEUE_STATUS_LEVEL, IBI_BUF_BLR);
517 /*
518 * ibi_buf_level should have 1-byte for IBI status, plus data size in words.
519 */
520 g_assert(ibi_buf_lvl == 1 + len);
521 uint32_t ibi_status = readl(i3c_base + A_IBI_QUEUE_STATUS);
522 /* IBI_ID is target address << 1 | RnW bit (which is 0) */
523 g_assert(FIELD_EX32(ibi_status, IBI_QUEUE_STATUS, IBI_ID) ==
524 (TARGET_ADDR << 1));
525 /* IBI data length in the register is stored in bytes. */
526 uint32_t ibi_data_len = FIELD_EX32(ibi_status, IBI_QUEUE_STATUS,
527 IBI_DATA_LEN);
528 g_assert(ibi_data_len == len * sizeof(uint32_t));
529
530 /*
531 * Read in the IBI bytes, if they aren't word-aligned, read in an extra
532 * word.
533 */
534 for (size_t i = 0; i < (ibi_data_len / 4) +
535 (ibi_data_len & 0x03) ? 1 : 0; i++) {
536 ibi_data[i] = readl(i3c_base + A_IBI_QUEUE_DATA);
537 }
538 /* Make sure the data matches. */
539 g_assert(memcmp(ibi_data, data, len) == 0);
540 }
541
ibi_and_verify(uint32_t i3c_base,const uint32_t * data,size_t len)542 static void ibi_and_verify(uint32_t i3c_base, const uint32_t *data, size_t len)
543 {
544 /* Send the IBI request. */
545 remote_i3c_ibi(data, len);
546 /* Read it and verify it matches what we expect. */
547 aspeed_i3c_read_ibi_and_verify(i3c_base, data, len);
548 }
549
550 /* Remote target IBI. */
test_remote_i3c_ibi(gconstpointer test_data)551 static void test_remote_i3c_ibi(gconstpointer test_data)
552 {
553 uint32_t controller_num = *(uint32_t *)test_data;
554 uint32_t i3c_base = I3C(controller_num);
555 uint32_t data = 0xaa55cc33;
556 /* Enable the controller. */
557 aspeed_i3c_enable(i3c_base);
558 /*
559 * Tell the target to use its static address as its dynamic address, and
560 * populate the device table.
561 */
562 add_targets_to_bus(i3c_base);
563
564 /*
565 * To test IBIing, we will:
566 * - Have the target IBI the controller by writing to the socket.
567 * - The controller ACKs and enqueues the IBI request.
568 * - The ACK is sent over socket, we verify it's there.
569 * - We read the request from the controller IBI queue.
570 */
571 ibi_and_verify(i3c_base, &data, 1);
572 }
573
main(int argc,char ** argv)574 int main(int argc, char **argv)
575 {
576 int ret;
577 int port;
578 /* Global register base address + offset of first controller. */
579 uint32_t i3c_controller_num = 0;
580 g_test_init(&argc, &argv, NULL);
581 port = open_socket();
582
583 global_qtest = qtest_initf("-machine ast2600-evb "
584 "-chardev socket,id=remote-i3c-chr,port=%d,host=localhost "
585 "-device %s,"
586 "chardev=remote-i3c-chr,"
587 "device-name=remote-target,"
588 "bus=aspeed.i3c.device.0,"
589 "pid=0xfeedf00dd00d,"
590 "dcr=0xaa,"
591 "bcr=0x55,"
592 "static-address=%d",
593 port, TYPE_REMOTE_I3C, TARGET_ADDR);
594 setup_fd();
595
596 /* Remote target RXing, i.e. controller -> target. */
597 qtest_add_data_func("remote-i3c-rx", (void *)&i3c_controller_num,
598 test_remote_i3c_rx);
599 /* Remote target TXing, i.e. controller -> target. */
600 qtest_add_data_func("remote-i3c-tx", (void *)&i3c_controller_num,
601 test_remote_i3c_tx);
602 /* Remote target IBIing. */
603 qtest_add_data_func("remote-i3c-ibi", (void *)&i3c_controller_num,
604 test_remote_i3c_ibi);
605
606 ret = g_test_run();
607 qtest_end();
608
609 return ret;
610 }
611