xref: /openbmc/qemu/hw/i3c/mock-target.c (revision c6fd2f5f0e58d243b3423aff23d081adc61350c8)
1*c6fd2f5fSJoe Komlodi /*
2*c6fd2f5fSJoe Komlodi  * Mock I3C Device
3*c6fd2f5fSJoe Komlodi  *
4*c6fd2f5fSJoe Komlodi  * Copyright (c) 2023 Google LLC
5*c6fd2f5fSJoe Komlodi  *
6*c6fd2f5fSJoe Komlodi  * The mock I3C device can be thought of as a simple EEPROM. It has a buffer,
7*c6fd2f5fSJoe Komlodi  * and the pointer in the buffer is reset to 0 on an I3C STOP.
8*c6fd2f5fSJoe Komlodi  * To write to the buffer, issue a private write and send data.
9*c6fd2f5fSJoe Komlodi  * To read from the buffer, issue a private read.
10*c6fd2f5fSJoe Komlodi  *
11*c6fd2f5fSJoe Komlodi  * The mock target also supports sending target interrupt IBIs.
12*c6fd2f5fSJoe Komlodi  * To issue an IBI, set the 'ibi-magic-num' property to a non-zero number, and
13*c6fd2f5fSJoe Komlodi  * send that number in a private transaction. The mock target will issue an IBI
14*c6fd2f5fSJoe Komlodi  * after 1 second.
15*c6fd2f5fSJoe Komlodi  *
16*c6fd2f5fSJoe Komlodi  * It also supports a handful of CCCs that are typically used when probing I3C
17*c6fd2f5fSJoe Komlodi  * devices.
18*c6fd2f5fSJoe Komlodi  *
19*c6fd2f5fSJoe Komlodi  * This program is free software; you can redistribute it and/or modify it
20*c6fd2f5fSJoe Komlodi  * under the terms of the GNU General Public License as published by the
21*c6fd2f5fSJoe Komlodi  * Free Software Foundation; either version 2 of the License, or
22*c6fd2f5fSJoe Komlodi  * (at your option) any later version.
23*c6fd2f5fSJoe Komlodi  *
24*c6fd2f5fSJoe Komlodi  * This program is distributed in the hope that it will be useful, but WITHOUT
25*c6fd2f5fSJoe Komlodi  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26*c6fd2f5fSJoe Komlodi  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27*c6fd2f5fSJoe Komlodi  * for more details.
28*c6fd2f5fSJoe Komlodi  */
29*c6fd2f5fSJoe Komlodi 
30*c6fd2f5fSJoe Komlodi #include "qemu/osdep.h"
31*c6fd2f5fSJoe Komlodi #include "qemu/log.h"
32*c6fd2f5fSJoe Komlodi #include "trace.h"
33*c6fd2f5fSJoe Komlodi #include "hw/i3c/i3c.h"
34*c6fd2f5fSJoe Komlodi #include "hw/i3c/mock-target.h"
35*c6fd2f5fSJoe Komlodi #include "hw/irq.h"
36*c6fd2f5fSJoe Komlodi #include "hw/qdev-properties.h"
37*c6fd2f5fSJoe Komlodi #include "qapi/error.h"
38*c6fd2f5fSJoe Komlodi #include "qemu/module.h"
39*c6fd2f5fSJoe Komlodi 
40*c6fd2f5fSJoe Komlodi #ifndef MOCK_TARGET_DEBUG
41*c6fd2f5fSJoe Komlodi #define MOCK_TARGET_DEBUG 0
42*c6fd2f5fSJoe Komlodi #endif
43*c6fd2f5fSJoe Komlodi 
44*c6fd2f5fSJoe Komlodi #define DB_PRINTF(...) do { \
45*c6fd2f5fSJoe Komlodi         if (MOCK_TARGET_DEBUG) { \
46*c6fd2f5fSJoe Komlodi             qemu_log("%s: ", __func__); \
47*c6fd2f5fSJoe Komlodi             qemu_log(__VA_ARGS__); \
48*c6fd2f5fSJoe Komlodi         } \
49*c6fd2f5fSJoe Komlodi     } while (0)
50*c6fd2f5fSJoe Komlodi 
51*c6fd2f5fSJoe Komlodi #define IBI_DELAY_NS (1 * 1000 * 1000)
52*c6fd2f5fSJoe Komlodi 
mock_target_rx(I3CTarget * i3c,uint8_t * data,uint32_t num_to_read)53*c6fd2f5fSJoe Komlodi static uint32_t mock_target_rx(I3CTarget *i3c, uint8_t *data,
54*c6fd2f5fSJoe Komlodi                                uint32_t num_to_read)
55*c6fd2f5fSJoe Komlodi {
56*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
57*c6fd2f5fSJoe Komlodi     uint32_t i;
58*c6fd2f5fSJoe Komlodi 
59*c6fd2f5fSJoe Komlodi     /* Bounds check. */
60*c6fd2f5fSJoe Komlodi     if (s->p_buf == s->cfg.buf_size) {
61*c6fd2f5fSJoe Komlodi         return 0;
62*c6fd2f5fSJoe Komlodi     }
63*c6fd2f5fSJoe Komlodi 
64*c6fd2f5fSJoe Komlodi     for (i = 0; i < num_to_read; i++) {
65*c6fd2f5fSJoe Komlodi         data[i] = s->buf[s->p_buf];
66*c6fd2f5fSJoe Komlodi         trace_mock_target_rx(data[i]);
67*c6fd2f5fSJoe Komlodi         s->p_buf++;
68*c6fd2f5fSJoe Komlodi         if (s->p_buf == s->cfg.buf_size) {
69*c6fd2f5fSJoe Komlodi             break;
70*c6fd2f5fSJoe Komlodi         }
71*c6fd2f5fSJoe Komlodi     }
72*c6fd2f5fSJoe Komlodi 
73*c6fd2f5fSJoe Komlodi     /* Return the number of bytes we're sending to the controller. */
74*c6fd2f5fSJoe Komlodi     return i;
75*c6fd2f5fSJoe Komlodi }
76*c6fd2f5fSJoe Komlodi 
mock_target_ibi_timer_start(MockTargetState * s)77*c6fd2f5fSJoe Komlodi static void mock_target_ibi_timer_start(MockTargetState *s)
78*c6fd2f5fSJoe Komlodi {
79*c6fd2f5fSJoe Komlodi     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
80*c6fd2f5fSJoe Komlodi     timer_mod(&s->qtimer, now + IBI_DELAY_NS);
81*c6fd2f5fSJoe Komlodi }
82*c6fd2f5fSJoe Komlodi 
mock_target_tx(I3CTarget * i3c,const uint8_t * data,uint32_t num_to_send,uint32_t * num_sent)83*c6fd2f5fSJoe Komlodi static int mock_target_tx(I3CTarget *i3c, const uint8_t *data,
84*c6fd2f5fSJoe Komlodi                           uint32_t num_to_send, uint32_t *num_sent)
85*c6fd2f5fSJoe Komlodi {
86*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
87*c6fd2f5fSJoe Komlodi     int ret;
88*c6fd2f5fSJoe Komlodi     uint32_t to_write;
89*c6fd2f5fSJoe Komlodi 
90*c6fd2f5fSJoe Komlodi     if (s->cfg.ibi_magic && num_to_send == 1 && s->cfg.ibi_magic == *data) {
91*c6fd2f5fSJoe Komlodi         mock_target_ibi_timer_start(s);
92*c6fd2f5fSJoe Komlodi         return 0;
93*c6fd2f5fSJoe Komlodi     }
94*c6fd2f5fSJoe Komlodi 
95*c6fd2f5fSJoe Komlodi     /* Bounds check. */
96*c6fd2f5fSJoe Komlodi     if (num_to_send + s->p_buf > s->cfg.buf_size) {
97*c6fd2f5fSJoe Komlodi         to_write = s->cfg.buf_size - s->p_buf;
98*c6fd2f5fSJoe Komlodi         ret = -1;
99*c6fd2f5fSJoe Komlodi     } else {
100*c6fd2f5fSJoe Komlodi         to_write = num_to_send;
101*c6fd2f5fSJoe Komlodi         ret = 0;
102*c6fd2f5fSJoe Komlodi     }
103*c6fd2f5fSJoe Komlodi     for (uint32_t i = 0; i < to_write; i++) {
104*c6fd2f5fSJoe Komlodi         trace_mock_target_tx(data[i]);
105*c6fd2f5fSJoe Komlodi         s->buf[s->p_buf] = data[i];
106*c6fd2f5fSJoe Komlodi         s->p_buf++;
107*c6fd2f5fSJoe Komlodi     }
108*c6fd2f5fSJoe Komlodi     return ret;
109*c6fd2f5fSJoe Komlodi }
110*c6fd2f5fSJoe Komlodi 
mock_target_event(I3CTarget * i3c,enum I3CEvent event)111*c6fd2f5fSJoe Komlodi static int mock_target_event(I3CTarget *i3c, enum I3CEvent event)
112*c6fd2f5fSJoe Komlodi {
113*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
114*c6fd2f5fSJoe Komlodi 
115*c6fd2f5fSJoe Komlodi     trace_mock_target_event(event);
116*c6fd2f5fSJoe Komlodi     if (event == I3C_STOP) {
117*c6fd2f5fSJoe Komlodi         s->in_ccc = false;
118*c6fd2f5fSJoe Komlodi         s->curr_ccc = 0;
119*c6fd2f5fSJoe Komlodi         s->ccc_byte_offset = 0;
120*c6fd2f5fSJoe Komlodi         s->p_buf = 0;
121*c6fd2f5fSJoe Komlodi     }
122*c6fd2f5fSJoe Komlodi 
123*c6fd2f5fSJoe Komlodi     return 0;
124*c6fd2f5fSJoe Komlodi }
125*c6fd2f5fSJoe Komlodi 
mock_target_handle_ccc_read(I3CTarget * i3c,uint8_t * data,uint32_t num_to_read,uint32_t * num_read)126*c6fd2f5fSJoe Komlodi static int mock_target_handle_ccc_read(I3CTarget *i3c, uint8_t *data,
127*c6fd2f5fSJoe Komlodi                                        uint32_t num_to_read, uint32_t *num_read)
128*c6fd2f5fSJoe Komlodi {
129*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
130*c6fd2f5fSJoe Komlodi 
131*c6fd2f5fSJoe Komlodi     switch (s->curr_ccc) {
132*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMXDS:
133*c6fd2f5fSJoe Komlodi         /* Default data rate for I3C. */
134*c6fd2f5fSJoe Komlodi         while (s->ccc_byte_offset < num_to_read) {
135*c6fd2f5fSJoe Komlodi             if (s->ccc_byte_offset >= 2) {
136*c6fd2f5fSJoe Komlodi                 break;
137*c6fd2f5fSJoe Komlodi             }
138*c6fd2f5fSJoe Komlodi             data[s->ccc_byte_offset] = 0;
139*c6fd2f5fSJoe Komlodi             *num_read = s->ccc_byte_offset;
140*c6fd2f5fSJoe Komlodi             s->ccc_byte_offset++;
141*c6fd2f5fSJoe Komlodi         }
142*c6fd2f5fSJoe Komlodi         break;
143*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETCAPS:
144*c6fd2f5fSJoe Komlodi         /* Support I3C version 1.1.x, no other features. */
145*c6fd2f5fSJoe Komlodi         while (s->ccc_byte_offset < num_to_read) {
146*c6fd2f5fSJoe Komlodi             if (s->ccc_byte_offset >= 2) {
147*c6fd2f5fSJoe Komlodi                 break;
148*c6fd2f5fSJoe Komlodi             }
149*c6fd2f5fSJoe Komlodi             if (s->ccc_byte_offset == 0) {
150*c6fd2f5fSJoe Komlodi                 data[s->ccc_byte_offset] = 0;
151*c6fd2f5fSJoe Komlodi             } else {
152*c6fd2f5fSJoe Komlodi                 data[s->ccc_byte_offset] = 0x01;
153*c6fd2f5fSJoe Komlodi             }
154*c6fd2f5fSJoe Komlodi             *num_read = s->ccc_byte_offset;
155*c6fd2f5fSJoe Komlodi             s->ccc_byte_offset++;
156*c6fd2f5fSJoe Komlodi         }
157*c6fd2f5fSJoe Komlodi         break;
158*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMWL:
159*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMRL:
160*c6fd2f5fSJoe Komlodi         /* MWL/MRL is MSB first. */
161*c6fd2f5fSJoe Komlodi         while (s->ccc_byte_offset < num_to_read) {
162*c6fd2f5fSJoe Komlodi             if (s->ccc_byte_offset >= 2) {
163*c6fd2f5fSJoe Komlodi                 break;
164*c6fd2f5fSJoe Komlodi             }
165*c6fd2f5fSJoe Komlodi             data[s->ccc_byte_offset] = (s->cfg.buf_size &
166*c6fd2f5fSJoe Komlodi                                         (0xff00 >> (s->ccc_byte_offset * 8))) >>
167*c6fd2f5fSJoe Komlodi                                         (8 - (s->ccc_byte_offset * 8));
168*c6fd2f5fSJoe Komlodi             s->ccc_byte_offset++;
169*c6fd2f5fSJoe Komlodi             *num_read = num_to_read;
170*c6fd2f5fSJoe Komlodi         }
171*c6fd2f5fSJoe Komlodi         break;
172*c6fd2f5fSJoe Komlodi     case I3C_CCC_ENTDAA:
173*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETPID:
174*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETBCR:
175*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETDCR:
176*c6fd2f5fSJoe Komlodi         /* Nothing to do. */
177*c6fd2f5fSJoe Komlodi         break;
178*c6fd2f5fSJoe Komlodi     default:
179*c6fd2f5fSJoe Komlodi         qemu_log_mask(LOG_GUEST_ERROR, "Unhandled CCC 0x%.2x\n", s->curr_ccc);
180*c6fd2f5fSJoe Komlodi         return -1;
181*c6fd2f5fSJoe Komlodi     }
182*c6fd2f5fSJoe Komlodi 
183*c6fd2f5fSJoe Komlodi     trace_mock_target_handle_ccc_read(*num_read, num_to_read);
184*c6fd2f5fSJoe Komlodi     return 0;
185*c6fd2f5fSJoe Komlodi }
186*c6fd2f5fSJoe Komlodi 
mock_target_handle_ccc_write(I3CTarget * i3c,const uint8_t * data,uint32_t num_to_send,uint32_t * num_sent)187*c6fd2f5fSJoe Komlodi static int mock_target_handle_ccc_write(I3CTarget *i3c, const uint8_t *data,
188*c6fd2f5fSJoe Komlodi                                         uint32_t num_to_send,
189*c6fd2f5fSJoe Komlodi                                         uint32_t *num_sent)
190*c6fd2f5fSJoe Komlodi {
191*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
192*c6fd2f5fSJoe Komlodi 
193*c6fd2f5fSJoe Komlodi     if (!s->curr_ccc) {
194*c6fd2f5fSJoe Komlodi         s->in_ccc = true;
195*c6fd2f5fSJoe Komlodi         s->curr_ccc = *data;
196*c6fd2f5fSJoe Komlodi         trace_mock_target_new_ccc(s->curr_ccc);
197*c6fd2f5fSJoe Komlodi     }
198*c6fd2f5fSJoe Komlodi 
199*c6fd2f5fSJoe Komlodi     *num_sent = 1;
200*c6fd2f5fSJoe Komlodi     switch (s->curr_ccc) {
201*c6fd2f5fSJoe Komlodi     case I3C_CCC_ENEC:
202*c6fd2f5fSJoe Komlodi         s->can_ibi = true;
203*c6fd2f5fSJoe Komlodi         break;
204*c6fd2f5fSJoe Komlodi     case I3C_CCC_DISEC:
205*c6fd2f5fSJoe Komlodi         s->can_ibi = false;
206*c6fd2f5fSJoe Komlodi         break;
207*c6fd2f5fSJoe Komlodi     case I3C_CCC_ENTDAA:
208*c6fd2f5fSJoe Komlodi     case I3C_CCC_SETAASA:
209*c6fd2f5fSJoe Komlodi     case I3C_CCC_RSTDAA:
210*c6fd2f5fSJoe Komlodi     case I3C_CCCD_SETDASA:
211*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETPID:
212*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETBCR:
213*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETDCR:
214*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMWL:
215*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMRL:
216*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETMXDS:
217*c6fd2f5fSJoe Komlodi     case I3C_CCCD_GETCAPS:
218*c6fd2f5fSJoe Komlodi         /* Nothing to do. */
219*c6fd2f5fSJoe Komlodi         break;
220*c6fd2f5fSJoe Komlodi     default:
221*c6fd2f5fSJoe Komlodi         qemu_log_mask(LOG_GUEST_ERROR, "Unhandled CCC 0x%.2x\n", s->curr_ccc);
222*c6fd2f5fSJoe Komlodi         return -1;
223*c6fd2f5fSJoe Komlodi     }
224*c6fd2f5fSJoe Komlodi 
225*c6fd2f5fSJoe Komlodi     trace_mock_target_handle_ccc_read(*num_sent, num_to_send);
226*c6fd2f5fSJoe Komlodi     return 0;
227*c6fd2f5fSJoe Komlodi }
228*c6fd2f5fSJoe Komlodi 
mock_target_do_ibi(MockTargetState * s)229*c6fd2f5fSJoe Komlodi static void mock_target_do_ibi(MockTargetState *s)
230*c6fd2f5fSJoe Komlodi {
231*c6fd2f5fSJoe Komlodi     if (!s->can_ibi) {
232*c6fd2f5fSJoe Komlodi         DB_PRINTF("IBIs disabled by controller");
233*c6fd2f5fSJoe Komlodi         return;
234*c6fd2f5fSJoe Komlodi     }
235*c6fd2f5fSJoe Komlodi 
236*c6fd2f5fSJoe Komlodi     trace_mock_target_do_ibi(s->i3c.address, true);
237*c6fd2f5fSJoe Komlodi     int nack = i3c_target_send_ibi(&s->i3c, s->i3c.address, /*is_recv=*/true);
238*c6fd2f5fSJoe Komlodi     /* Getting NACKed isn't necessarily an error, just print it out. */
239*c6fd2f5fSJoe Komlodi     if (nack) {
240*c6fd2f5fSJoe Komlodi         DB_PRINTF("NACKed from controller when sending target interrupt.\n");
241*c6fd2f5fSJoe Komlodi     }
242*c6fd2f5fSJoe Komlodi }
243*c6fd2f5fSJoe Komlodi 
mock_target_timer_elapsed(void * opaque)244*c6fd2f5fSJoe Komlodi static void mock_target_timer_elapsed(void *opaque)
245*c6fd2f5fSJoe Komlodi {
246*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(opaque);
247*c6fd2f5fSJoe Komlodi     timer_del(&s->qtimer);
248*c6fd2f5fSJoe Komlodi     mock_target_do_ibi(s);
249*c6fd2f5fSJoe Komlodi }
250*c6fd2f5fSJoe Komlodi 
mock_target_reset(I3CTarget * i3c)251*c6fd2f5fSJoe Komlodi static void mock_target_reset(I3CTarget *i3c)
252*c6fd2f5fSJoe Komlodi {
253*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(i3c);
254*c6fd2f5fSJoe Komlodi     s->can_ibi = false;
255*c6fd2f5fSJoe Komlodi }
256*c6fd2f5fSJoe Komlodi 
mock_target_realize(DeviceState * dev,Error ** errp)257*c6fd2f5fSJoe Komlodi static void mock_target_realize(DeviceState *dev, Error **errp)
258*c6fd2f5fSJoe Komlodi {
259*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(dev);
260*c6fd2f5fSJoe Komlodi     s->buf = g_new0(uint8_t, s->cfg.buf_size);
261*c6fd2f5fSJoe Komlodi     mock_target_reset(&s->i3c);
262*c6fd2f5fSJoe Komlodi }
263*c6fd2f5fSJoe Komlodi 
mock_target_init(Object * obj)264*c6fd2f5fSJoe Komlodi static void mock_target_init(Object *obj)
265*c6fd2f5fSJoe Komlodi {
266*c6fd2f5fSJoe Komlodi     MockTargetState *s = MOCK_TARGET(obj);
267*c6fd2f5fSJoe Komlodi     s->can_ibi = false;
268*c6fd2f5fSJoe Komlodi 
269*c6fd2f5fSJoe Komlodi     /* For IBIs. */
270*c6fd2f5fSJoe Komlodi     timer_init_ns(&s->qtimer, QEMU_CLOCK_VIRTUAL, mock_target_timer_elapsed, s);
271*c6fd2f5fSJoe Komlodi }
272*c6fd2f5fSJoe Komlodi 
273*c6fd2f5fSJoe Komlodi static Property remote_i3c_props[] = {
274*c6fd2f5fSJoe Komlodi     /* The size of the internal buffer. */
275*c6fd2f5fSJoe Komlodi     DEFINE_PROP_UINT32("buf-size", MockTargetState, cfg.buf_size, 0x100),
276*c6fd2f5fSJoe Komlodi     /*
277*c6fd2f5fSJoe Komlodi      * If the mock target receives this number, it will issue an IBI after
278*c6fd2f5fSJoe Komlodi      * 1 second. Disabled if the IBI magic number is 0.
279*c6fd2f5fSJoe Komlodi      */
280*c6fd2f5fSJoe Komlodi     DEFINE_PROP_UINT8("ibi-magic-num", MockTargetState, cfg.ibi_magic, 0x00),
281*c6fd2f5fSJoe Komlodi     DEFINE_PROP_END_OF_LIST(),
282*c6fd2f5fSJoe Komlodi };
283*c6fd2f5fSJoe Komlodi 
mock_target_class_init(ObjectClass * klass,void * data)284*c6fd2f5fSJoe Komlodi static void mock_target_class_init(ObjectClass *klass, void *data)
285*c6fd2f5fSJoe Komlodi {
286*c6fd2f5fSJoe Komlodi     DeviceClass *dc = DEVICE_CLASS(klass);
287*c6fd2f5fSJoe Komlodi     I3CTargetClass *k = I3C_TARGET_CLASS(klass);
288*c6fd2f5fSJoe Komlodi 
289*c6fd2f5fSJoe Komlodi     dc->realize = mock_target_realize;
290*c6fd2f5fSJoe Komlodi     k->event = mock_target_event;
291*c6fd2f5fSJoe Komlodi     k->recv = mock_target_rx;
292*c6fd2f5fSJoe Komlodi     k->send = mock_target_tx;
293*c6fd2f5fSJoe Komlodi     k->handle_ccc_read = mock_target_handle_ccc_read;
294*c6fd2f5fSJoe Komlodi     k->handle_ccc_write = mock_target_handle_ccc_write;
295*c6fd2f5fSJoe Komlodi 
296*c6fd2f5fSJoe Komlodi     device_class_set_props(dc, remote_i3c_props);
297*c6fd2f5fSJoe Komlodi }
298*c6fd2f5fSJoe Komlodi 
299*c6fd2f5fSJoe Komlodi static const TypeInfo mock_target_info = {
300*c6fd2f5fSJoe Komlodi     .name          = TYPE_MOCK_TARGET,
301*c6fd2f5fSJoe Komlodi     .parent        = TYPE_I3C_TARGET,
302*c6fd2f5fSJoe Komlodi     .instance_size = sizeof(MockTargetState),
303*c6fd2f5fSJoe Komlodi     .instance_init = mock_target_init,
304*c6fd2f5fSJoe Komlodi     .class_init    = mock_target_class_init,
305*c6fd2f5fSJoe Komlodi };
306*c6fd2f5fSJoe Komlodi 
mock_target_register_types(void)307*c6fd2f5fSJoe Komlodi static void mock_target_register_types(void)
308*c6fd2f5fSJoe Komlodi {
309*c6fd2f5fSJoe Komlodi     type_register_static(&mock_target_info);
310*c6fd2f5fSJoe Komlodi }
311*c6fd2f5fSJoe Komlodi 
312*c6fd2f5fSJoe Komlodi type_init(mock_target_register_types)
313