xref: /openbmc/qemu/hw/i3c/core.c (revision 80ee30153dd3b96a7c82b8f0c3bf18bbce8db1e5)
1 /*
2  * QEMU I3C bus interface.
3  *
4  * Copyright 2025 Google LLC
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "qemu/osdep.h"
10 #include "qemu/log.h"
11 #include "qapi/error.h"
12 #include "trace.h"
13 #include "hw/i3c/i3c.h"
14 #include "hw/qdev-properties.h"
15 
16 /*
17  * In test mode (enabled by ENTTM CCC) we're supposed to send a random PID
18  * during ENTDAA, so we'll just send "QEMU".
19  */
20 #define TEST_MODE_PROVISIONED_ID 0x0000554d4551ULL
21 
22 static const Property i3c_props[] = {
23     DEFINE_PROP_UINT8("static-address", struct I3CTarget, static_address, 0),
24     DEFINE_PROP_UINT8("dcr", struct I3CTarget, dcr, 0),
25     DEFINE_PROP_UINT8("bcr", struct I3CTarget, bcr, 0),
26     DEFINE_PROP_UINT64("pid", struct I3CTarget, pid, 0),
27 };
28 
29 static const TypeInfo i3c_bus_info = {
30     .name = TYPE_I3C_BUS,
31     .parent = TYPE_BUS,
32     .instance_size = sizeof(I3CBus),
33     .class_size = sizeof(I3CBusClass),
34 };
35 
36 I3CBus *i3c_init_bus(DeviceState *parent, const char *name)
37 {
38     return i3c_init_bus_type(TYPE_I3C_BUS, parent, name);
39 }
40 
41 I3CBus *i3c_init_bus_type(const char *type, DeviceState *parent,
42                           const char *name)
43 {
44     I3CBus *bus;
45 
46     bus = I3C_BUS(qbus_new(type, parent, name));
47     QLIST_INIT(&bus->current_devs);
48     bus->broadcast = false;
49     bus->in_entdaa = false;
50     bus->in_ccc = false;
51 
52     /* I2C init. */
53     g_autofree gchar *i2c_bus_name = g_strdup_printf("%s-legacy-i2c", name);
54     bus->i2c_bus = i2c_init_bus(parent, i2c_bus_name);
55 
56     return bus;
57 }
58 
59 bool i3c_bus_busy(I3CBus *bus)
60 {
61     return !QLIST_EMPTY(&bus->current_devs);
62 }
63 
64 static bool i3c_target_match(I3CTarget *candidate, uint8_t address,
65                              bool is_recv, bool broadcast, bool in_entdaa)
66 {
67     /* Once a target has a dynamic address, it only responds to that. */
68     uint8_t targ_addr = candidate->address ? candidate->address :
69                                              candidate->static_address;
70 
71     if (in_entdaa) {
72         if (address != I3C_BROADCAST) {
73             g_autofree char *path =
74                 object_get_canonical_path(OBJECT(candidate));
75             qemu_log_mask(LOG_GUEST_ERROR, "%s: I3C Address 0x%.2x sent during "
76                           "ENTDAA instead of a broadcast address\n",
77                           path, address);
78             return false;
79         }
80 
81         /*
82          * Targets should only ACK ENTDAA broadcasts if they have no dynamic
83          * address.
84          */
85         return candidate->address == 0;
86     }
87 
88     /* Return if our addresses match, or if it's a broadcast. */
89     return targ_addr == address || broadcast;
90 }
91 
92 bool i3c_target_match_and_add(I3CBus *bus, I3CTarget *target, uint8_t address,
93                               enum I3CEvent event)
94 {
95     I3CTargetClass *tc = I3C_TARGET_GET_CLASS(target);
96     bool matched = tc->target_match(target, address, event == I3C_START_RECV,
97                                     bus->broadcast, bus->in_entdaa);
98 
99     if (matched) {
100         I3CNode *node = g_new(struct I3CNode, 1);
101         node->target = target;
102         QLIST_INSERT_HEAD(&bus->current_devs, node, next);
103     }
104     return matched;
105 }
106 
107 bool i3c_scan_bus(I3CBus *bus, uint8_t address, enum I3CEvent event)
108 {
109     BusChild *child;
110     I3CNode *node, *next;
111 
112     /* Clear out any devices from a previous (re-)START. */
113     QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
114         QLIST_REMOVE(node, next);
115         g_free(node);
116     }
117 
118     QTAILQ_FOREACH(child, &bus->qbus.children, sibling) {
119         DeviceState *qdev = child->child;
120         I3CTarget *target = I3C_TARGET(qdev);
121 
122         if (i3c_target_match_and_add(bus, target, address, event)) {
123             return true;
124         }
125     }
126 
127     /* No one on the bus could respond. */
128     return false;
129 }
130 
131 /* Class-level event handling, since we do some CCCs at the class level. */
132 static int i3c_target_event(I3CTarget *t, enum I3CEvent event)
133 {
134     I3CTargetClass *tc = I3C_TARGET_GET_CLASS(t);
135     trace_i3c_target_event(t->address, event);
136 
137     if (event == I3C_STOP) {
138         t->curr_ccc = 0;
139         t->ccc_byte_offset = 0;
140         t->in_ccc = false;
141     }
142     return tc->event(t, event);
143 }
144 
145 /*
146  * Sends a START or repeated START and the address for an I3C transaction.
147  *
148  * This function returns 0 if a device on the bus was able to respond to the
149  * address, and non-zero otherwise.
150  * A non-zero return represents a NACK.
151  */
152 static int i3c_do_start_transfer(I3CBus *bus, uint8_t address,
153                                  enum I3CEvent event)
154 {
155     I3CTargetClass *tc;
156     I3CNode *node;
157 
158     if (address == I3C_BROADCAST) {
159         bus->broadcast = true;
160         /* If we're not in ENTDAA, a broadcast is the start of a new CCC. */
161         if (!bus->in_entdaa) {
162             bus->in_ccc = false;
163         }
164     } else {
165         bus->broadcast = false;
166     }
167 
168     /* No one responded to the address, NACK it. */
169     if (!i3c_scan_bus(bus, address, event)) {
170         return -1;
171     }
172 
173     QLIST_FOREACH(node, &bus->current_devs, next) {
174         I3CTarget *t = node->target;
175 
176         tc = I3C_TARGET_GET_CLASS(t);
177         if (tc->event) {
178             int rv = i3c_target_event(t, event);
179             if (rv && !bus->broadcast) {
180                 return rv;
181             }
182         }
183     }
184 
185     return 0;
186 }
187 
188 int i3c_start_transfer(I3CBus *bus, uint8_t address, bool is_recv)
189 {
190     trace_i3c_start_transfer(address, is_recv);
191     return i3c_do_start_transfer(bus, address, is_recv
192                                                ? I3C_START_RECV
193                                                : I3C_START_SEND);
194 }
195 
196 int i3c_start_recv(I3CBus *bus, uint8_t address)
197 {
198     trace_i3c_start_transfer(address, true);
199     return i3c_do_start_transfer(bus, address, I3C_START_RECV);
200 }
201 
202 int i3c_start_send(I3CBus *bus, uint8_t address)
203 {
204     trace_i3c_start_transfer(address, false);
205     return i3c_do_start_transfer(bus, address, I3C_START_SEND);
206 }
207 
208 void i3c_end_transfer(I3CBus *bus)
209 {
210     I3CTargetClass *tc;
211     I3CNode *node, *next;
212 
213     trace_i3c_end_transfer();
214 
215     /*
216      * If we're in ENTDAA, we need to notify all devices when ENTDAA is done.
217      * This is because everyone initially participates due to the broadcast,
218      * but gradually drops out as they get assigned addresses.
219      * Since the current_devs list only stores who's currently participating,
220      * and not everyone who previously participated, we send the STOP to all
221      * children.
222      */
223     if (bus->in_entdaa) {
224         BusChild *child;
225 
226         QTAILQ_FOREACH(child, &bus->qbus.children, sibling) {
227             DeviceState *qdev = child->child;
228             I3CTarget *t = I3C_TARGET(qdev);
229             tc = I3C_TARGET_GET_CLASS(t);
230             if (tc->event) {
231                 i3c_target_event(t, I3C_STOP);
232             }
233         }
234     } else {
235         QLIST_FOREACH_SAFE(node, &bus->current_devs, next, next) {
236             I3CTarget *t = node->target;
237             tc = I3C_TARGET_GET_CLASS(t);
238             if (tc->event) {
239                 i3c_target_event(t, I3C_STOP);
240             }
241             QLIST_REMOVE(node, next);
242             g_free(node);
243         }
244     }
245     bus->broadcast = false;
246     bus->in_entdaa = false;
247     bus->in_ccc = false;
248 }
249 
250 /*
251  * Any CCCs that are universal across all I3C devices should be handled here.
252  * Once they're handled, we pass the CCC up to the I3C target to do anything
253  * else it may want with the bytes.
254  */
255 static int i3c_target_handle_ccc_write(I3CTarget *t, const uint8_t *data,
256                                        uint32_t num_to_send, uint32_t *num_sent)
257 {
258     I3CTargetClass *tc = I3C_TARGET_GET_CLASS(t);
259     *num_sent = 0;
260 
261     /* Is this the start of a new CCC? */
262     if (!t->in_ccc) {
263         t->curr_ccc = *data;
264         t->in_ccc = true;
265         *num_sent = 1;
266         trace_i3c_target_handle_ccc(t->address, t->curr_ccc);
267     }
268 
269     switch (t->curr_ccc) {
270     case I3C_CCC_ENTDAA:
271         /*
272          * This is the last byte of ENTDAA, the controller is assigning us an
273          * address.
274          */
275         if (t->ccc_byte_offset == 8) {
276             t->address = *data;
277             t->in_ccc = false;
278             t->curr_ccc = 0;
279             t->ccc_byte_offset = 0;
280             *num_sent = 1;
281         }
282         break;
283     case I3C_CCCD_SETDASA:
284         t->address = t->static_address;
285         break;
286     case I3C_CCC_SETAASA:
287         t->address = t->static_address;
288         break;
289     case I3C_CCC_RSTDAA:
290         t->address = 0;
291         break;
292     case I3C_CCCD_SETNEWDA:
293         /* If this isn't the CCC byte, it's our new address. */
294         if (*num_sent == 0) {
295             t->address = *data;
296             *num_sent = 1;
297         }
298         break;
299     case I3C_CCC_ENTTM:
300         /*
301          * If there are still more to look at, the next byte is the test mode
302          * byte.
303          */
304         if (*num_sent != num_to_send) {
305             /* Enter test mode if the byte is non-zero. Otherwise exit. */
306             t->in_test_mode = !!data[*num_sent];
307             ++*num_sent;
308         }
309         break;
310     /* Ignore other CCCs it's better to handle on a device-by-device basis. */
311     default:
312         break;
313     }
314     return tc->handle_ccc_write(t, data, num_to_send, num_sent);
315 }
316 
317 int i3c_send_byte(I3CBus *bus, uint8_t data)
318 {
319     /*
320      * Ignored, the caller can determine how many were sent based on if this was
321      * ACKed/NACKed.
322      */
323     uint32_t num_sent;
324     return i3c_send(bus, &data, 1, &num_sent);
325 }
326 
327 int i3c_send(I3CBus *bus, const uint8_t *data, uint32_t num_to_send,
328              uint32_t *num_sent)
329 {
330     I3CTargetClass *tc;
331     I3CTarget *t;
332     I3CNode *node;
333     int ret = 0;
334 
335     /* If this message is a broadcast and no CCC has been found, grab it. */
336     if (bus->broadcast && !bus->in_ccc) {
337         bus->ccc = *data;
338         bus->in_ccc = true;
339         /*
340          * We need to keep track if we're currently in ENTDAA.
341          * On any other CCC, the CCC is over on a RESTART or STOP, but ENTDAA
342          * is only over on a STOP.
343          */
344         if (bus->ccc == I3C_CCC_ENTDAA) {
345             bus->in_entdaa = true;
346         }
347     }
348 
349     QLIST_FOREACH(node, &bus->current_devs, next) {
350         t = node->target;
351         tc = I3C_TARGET_GET_CLASS(t);
352         if (bus->in_ccc) {
353             if (!tc->handle_ccc_write) {
354                 ret = -1;
355                 continue;
356             }
357             ret = i3c_target_handle_ccc_write(t, data, num_to_send, num_sent);
358             /* Targets should only NACK on a direct CCC. */
359             if (ret && !CCC_IS_DIRECT(bus->ccc)) {
360                 ret = 0;
361             }
362         } else {
363             if (tc->send) {
364                 ret = ret || tc->send(t, data, num_to_send, num_sent);
365             } else {
366                 ret = -1;
367             }
368         }
369     }
370 
371     trace_i3c_send(*num_sent, num_to_send, ret == 0);
372 
373     return ret ? -1 : 0;
374 }
375 
376 static int i3c_target_handle_ccc_read(I3CTarget *t, uint8_t *data,
377                                       uint32_t num_to_read, uint32_t *num_read)
378 {
379     I3CTargetClass *tc = I3C_TARGET_GET_CLASS(t);
380     uint8_t read_count = 0;
381     uint64_t pid;
382 
383     switch (t->curr_ccc) {
384     case I3C_CCC_ENTDAA:
385         if (t->in_test_mode) {
386             pid = TEST_MODE_PROVISIONED_ID;
387         } else {
388             pid = t->pid;
389         }
390         /* Return the 6-byte PID, followed by BCR then DCR. */
391         while (t->ccc_byte_offset < 6) {
392             if (read_count >= num_to_read) {
393                 break;
394             }
395             data[read_count] = (pid >> (t->ccc_byte_offset * 8)) & 0xff;
396             t->ccc_byte_offset++;
397             read_count++;
398         }
399         if (read_count < num_to_read) {
400             data[read_count] = t->bcr;
401             t->ccc_byte_offset++;
402             read_count++;
403         }
404         if (read_count < num_to_read) {
405             data[read_count] = t->dcr;
406             t->ccc_byte_offset++;
407             read_count++;
408         }
409         *num_read = read_count;
410         break;
411     case I3C_CCCD_GETPID:
412         while (t->ccc_byte_offset < 6) {
413             if (read_count >= num_to_read) {
414                 break;
415             }
416             data[read_count] = (t->pid >> (t->ccc_byte_offset * 8)) & 0xff;
417             t->ccc_byte_offset++;
418             read_count++;
419         }
420         *num_read = read_count;
421         break;
422     case I3C_CCCD_GETBCR:
423         *data = t->bcr;
424         *num_read = 1;
425         break;
426     case I3C_CCCD_GETDCR:
427         *data = t->dcr;
428         *num_read = 1;
429         break;
430     default:
431         /* Unhandled on the I3CTarget class level. */
432         break;
433     }
434 
435     return tc->handle_ccc_read(t, data, num_to_read, num_read);
436 }
437 
438 int i3c_recv_byte(I3CBus *bus, uint8_t *data)
439 {
440      /*
441       * Ignored, the caller can determine how many bytes were read based on if
442       * this is ACKed/NACKed.
443       */
444     uint32_t num_read;
445     return i3c_recv(bus, data, 1, &num_read);
446 }
447 
448 int i3c_recv(I3CBus *bus, uint8_t *data, uint32_t num_to_read,
449              uint32_t *num_read)
450 {
451     int ret = 0;
452     I3CTargetClass *tc;
453     I3CTarget *t;
454 
455     *data = 0xff;
456     if (!QLIST_EMPTY(&bus->current_devs)) {
457         tc = I3C_TARGET_GET_CLASS(QLIST_FIRST(&bus->current_devs)->target);
458         t = QLIST_FIRST(&bus->current_devs)->target;
459         if (bus->in_ccc) {
460             if (!tc->handle_ccc_read) {
461                 return -1;
462             }
463             ret = i3c_target_handle_ccc_read(t, data, num_to_read, num_read);
464         } else {
465             if (tc->recv) {
466                 /*
467                  * Targets cannot NACK on a direct transfer, so the data
468                  * is returned directly.
469                  */
470                 *num_read = tc->recv(t, data, num_to_read);
471             }
472         }
473     }
474 
475     trace_i3c_recv(*num_read, num_to_read, ret == 0);
476 
477     return ret;
478 }
479 
480 void i3c_nack(I3CBus *bus)
481 {
482     I3CTargetClass *tc;
483     I3CNode *node;
484 
485     if (QLIST_EMPTY(&bus->current_devs)) {
486         return;
487     }
488 
489     QLIST_FOREACH(node, &bus->current_devs, next) {
490         tc = I3C_TARGET_GET_CLASS(node->target);
491         if (tc->event) {
492             i3c_target_event(node->target, I3C_NACK);
493         }
494     }
495 }
496 
497 int i3c_target_send_ibi(I3CTarget *t, uint8_t addr, bool is_recv)
498 {
499     I3CBus *bus = I3C_BUS(t->qdev.parent_bus);
500     I3CBusClass *bc = I3C_BUS_GET_CLASS(bus);
501     trace_i3c_target_send_ibi(addr, is_recv);
502     return bc->ibi_handle(bus, addr, is_recv);
503 }
504 
505 int i3c_target_send_ibi_bytes(I3CTarget *t, uint8_t data)
506 {
507     I3CBus *bus = I3C_BUS(t->qdev.parent_bus);
508     I3CBusClass *bc = I3C_BUS_GET_CLASS(bus);
509     trace_i3c_target_send_ibi_bytes(data);
510     return bc->ibi_recv(bus, data);
511 }
512 
513 int i3c_target_ibi_finish(I3CTarget *t, uint8_t data)
514 {
515     I3CBus *bus = I3C_BUS(t->qdev.parent_bus);
516     I3CBusClass *bc = I3C_BUS_GET_CLASS(bus);
517     trace_i3c_target_ibi_finish();
518     return bc->ibi_finish(bus);
519 }
520 
521 static bool i3c_addr_is_rsvd(uint8_t addr)
522 {
523     const bool is_rsvd[255] = {
524         [0x00] = true,
525         [0x01] = true,
526         [0x02] = true,
527         [0x3e] = true,
528         [0x5e] = true,
529         [0x6e] = true,
530         [0x76] = true,
531         [0x7a] = true,
532         [0x7c] = true,
533         [0x7e] = true,
534         [0x7f] = true,
535     };
536 
537     return is_rsvd[addr];
538 }
539 
540 I3CTarget *i3c_target_new(const char *name, uint8_t addr, uint8_t dcr,
541                           uint8_t bcr, uint64_t pid)
542 {
543     DeviceState *dev;
544 
545     dev = qdev_new(name);
546     qdev_prop_set_uint8(dev, "static-address", addr);
547     qdev_prop_set_uint8(dev, "dcr", dcr);
548     qdev_prop_set_uint8(dev, "bcr", bcr);
549     qdev_prop_set_uint64(dev, "pid", pid);
550 
551     if (i3c_addr_is_rsvd(addr)) {
552         g_autofree char *path = object_get_canonical_path(OBJECT(dev));
553         qemu_log_mask(LOG_GUEST_ERROR, "%s: I3C target created with reserved "
554                       "address 0x%.2x\n", path, addr);
555     }
556     return I3C_TARGET(dev);
557 }
558 
559 bool i3c_target_realize_and_unref(I3CTarget *dev, I3CBus *bus, Error **errp)
560 {
561     return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp);
562 }
563 
564 I3CTarget *i3c_target_create_simple(I3CBus *bus, const char *name, uint8_t addr,
565                                     uint8_t dcr, uint8_t bcr, uint64_t pid)
566 {
567     I3CTarget *dev = i3c_target_new(name, addr, dcr, bcr, pid);
568     dev->address = 0;
569     i3c_target_realize_and_unref(dev, bus, &error_abort);
570 
571     return dev;
572 }
573 
574 /* Legacy I2C functions. */
575 void legacy_i2c_nack(I3CBus *bus)
576 {
577     trace_legacy_i2c_nack();
578     i2c_nack(bus->i2c_bus);
579 }
580 
581 uint8_t legacy_i2c_recv(I3CBus *bus)
582 {
583     uint8_t byte = i2c_recv(bus->i2c_bus);
584     trace_legacy_i2c_recv(byte);
585     return byte;
586 }
587 
588 int legacy_i2c_send(I3CBus *bus, uint8_t data)
589 {
590     trace_legacy_i2c_send(data);
591     return i2c_send(bus->i2c_bus, data);
592 }
593 
594 int legacy_i2c_start_transfer(I3CBus *bus, uint8_t address, bool is_recv)
595 {
596     trace_legacy_i2c_start_transfer(address, is_recv);
597     return i2c_start_transfer(bus->i2c_bus, address, is_recv);
598 }
599 
600 int legacy_i2c_start_recv(I3CBus *bus, uint8_t address)
601 {
602     trace_legacy_i2c_start_transfer(address, true);
603     return i2c_start_transfer(bus->i2c_bus, address, /*is_recv=*/true);
604 }
605 
606 int legacy_i2c_start_send(I3CBus *bus, uint8_t address)
607 {
608     trace_legacy_i2c_start_transfer(address, false);
609     return i2c_start_transfer(bus->i2c_bus, address, /*is_recv=*/false);
610 }
611 
612 void legacy_i2c_end_transfer(I3CBus *bus)
613 {
614     trace_legacy_i2c_end_transfer();
615     i2c_end_transfer(bus->i2c_bus);
616 }
617 
618 I2CSlave *legacy_i2c_device_create_simple(I3CBus *bus, const char *name,
619                                           uint8_t addr)
620 {
621     I2CSlave *dev = i2c_slave_new(name, addr);
622 
623     i2c_slave_realize_and_unref(dev, bus->i2c_bus, &error_abort);
624     return dev;
625 }
626 
627 static void i3c_target_class_init(ObjectClass *klass, const void *data)
628 {
629     DeviceClass *k = DEVICE_CLASS(klass);
630     I3CTargetClass *sc = I3C_TARGET_CLASS(klass);
631     set_bit(DEVICE_CATEGORY_MISC, k->categories);
632     k->bus_type = TYPE_I3C_BUS;
633     device_class_set_props(k, i3c_props);
634     sc->target_match = i3c_target_match;
635 }
636 
637 static const TypeInfo i3c_target_type_info = {
638     .name = TYPE_I3C_TARGET,
639     .parent = TYPE_DEVICE,
640     .instance_size = sizeof(I3CTarget),
641     .abstract = true,
642     .class_size = sizeof(I3CTargetClass),
643     .class_init = i3c_target_class_init,
644 };
645 
646 static void i3c_register_types(void)
647 {
648     type_register_static(&i3c_bus_info);
649     type_register_static(&i3c_target_type_info);
650 }
651 
652 type_init(i3c_register_types)
653