1 /*
2 * Copyright (C) 2019-2022 Intel Corporation.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <sys/param.h>
9 #include <sys/uio.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <pthread.h>
15 #include <openssl/md5.h>
16 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
17 #include <openssl/evp.h>
18 #endif
19 #include <linux/i2c.h>
20 #include <linux/i2c-dev.h>
21 #include <sys/ioctl.h>
22 #include <sys/queue.h>
23 #include <stdbool.h>
24 #include <pthread.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27
28 #include "dm.h"
29 #include "pci_core.h"
30 #include "virtio.h"
31 #include "acpi.h"
32
33 /* I2c adapter virtualization architecture
34 *
35 * +-----------------------------+
36 * | ACRN DM |
37 * | +----------------------+ | virtqueue
38 * | | |<--+-----------+
39 * | | virtio i2c mediator | | |
40 * | | | | |
41 * | +--+-----+-----+-------+ | |
42 * +-----+-----+-----+-----------+ |
43 * User space +-------+ | +-----------+ |
44 * v v v |
45 * +---------+----+ +-----+--------+ +-----+------+ | +-----------+
46 * ---+ /dev/i2c-0 +--+ /dev/i2c-1 +--+ /dev/i2c-n +----+--+User VM: |
47 * | | | | | | |/dev/i2c-n |
48 * +----------+---+ +-------+------+ +-----+------+ | +-----+-----+
49 * Kernel space v v v | v
50 * +-----+-------+ +----+--------+ +----+--------+ | +-----+------------+
51 * |i2c adapter 0| |i2c adapter 1| |i2c adapter n| +->|User VM: |
52 * | | | | | |virtio i2c adapter|
53 * +-----+-------+ +-------------+ +-------------+ +------------------+
54 * --------------+-----------------------------------------
55 * Hardware +----------+
56 * | |
57 * bus 0v v ....
58 * +-----+----+ +----+-----+
59 * |i2c client| |i2c client| ....
60 * +----------+ +----------+
61 */
62
63 static int virtio_i2c_debug=0;
64 #define VIRTIO_I2C_PREF "virtio_i2c: "
65 #define DPRINTF(fmt, args...) \
66 do { if (virtio_i2c_debug) pr_info(VIRTIO_I2C_PREF fmt, ##args); } while (0)
67 #define WPRINTF(fmt, args...) pr_err(VIRTIO_I2C_PREF fmt, ##args)
68
69 #define MAX_NODE_NAME_LEN 20
70 #define MAX_I2C_VDEV 128
71 #define MAX_NATIVE_I2C_ADAPTER 16
72 #define I2C_MSG_OK 0
73 #define I2C_MSG_ERR 1
74 #define I2C_NO_DEV 2
75
76 #define I2C_NO_FLAGS 0
77
78 #define VIRTIO_I2C_FLAGS_FAIL_NEXT 1 << 0
79 #define VIRTIO_I2C_FLAGS_M_RD 1 << 1
80
81 #define VIRTIO_I2C_F_ZERO_LENGTH_REQUEST 0
82 #define VIRTIO_I2C_HOSTCAPS (1UL << VIRTIO_F_VERSION_1) | \
83 (1UL << VIRTIO_I2C_F_ZERO_LENGTH_REQUEST)
84
85 static int acpi_i2c_adapter_num = 0;
86 static void acpi_add_i2c_adapter(struct pci_vdev *dev, int i2c_bus);
87 static void acpi_add_cam1(struct pci_vdev *dev, int i2c_bus);
88 static void acpi_add_cam2(struct pci_vdev *dev, int i2c_bus);
89 static void acpi_add_hdac(struct pci_vdev *dev, int i2c_bus);
90 static void acpi_add_default(struct pci_vdev *dev, int i2c_bus);
91
92 struct acpi_node {
93 char node_name[MAX_NODE_NAME_LEN];
94 void (*add_node_fn)(struct pci_vdev *, int);
95 };
96
97 static struct acpi_node acpi_node_table[] = {
98 /* cam1, cam2 and hdac is dump from MRB board */
99 {"cam1", acpi_add_cam1},
100 {"cam2", acpi_add_cam2},
101 {"hdac", acpi_add_hdac},
102 {"default", acpi_add_default},
103 };
104
105 struct virtio_i2c_out_hdr {
106 uint16_t addr; /* client address */
107 uint16_t padding;
108 uint32_t flags;
109 };
110
111 struct virtio_i2c_in_hdr {
112 uint8_t status;
113 };
114
115 struct native_i2c_adapter {
116 int fd;
117 int bus;
118 bool i2cdev_enable[MAX_I2C_VDEV];
119 };
120
121 /*
122 * Per-device struct
123 */
124 struct virtio_i2c {
125 struct virtio_base base;
126 pthread_mutex_t mtx;
127 struct native_i2c_adapter *native_adapter[MAX_NATIVE_I2C_ADAPTER];
128 int native_adapter_num;
129 uint16_t adapter_map[MAX_I2C_VDEV];
130 char acpi_nodes[MAX_I2C_VDEV][MAX_NODE_NAME_LEN];
131 struct virtio_vq_info vq;
132 char ident[256];
133 pthread_t req_tid;
134 pthread_mutex_t req_mtx;
135 pthread_cond_t req_cond;
136 int in_process;
137 int closing;
138 };
139
140 static void virtio_i2c_reset(void *);
141 static void virtio_i2c_notify(void *, struct virtio_vq_info *);
142
143 static struct virtio_ops virtio_i2c_ops = {
144 "virtio_i2c", /* our name */
145 1, /* we support 1 virtqueue */
146 0, /* config reg size */
147 virtio_i2c_reset, /* reset */
148 virtio_i2c_notify, /* device-wide qnotify */
149 NULL, /* read PCI config */
150 NULL, /* write PCI config */
151 NULL, /* apply negotiated features */
152 NULL, /* called on guest set status */
153 };
154
155 static void
acpi_add_i2c_adapter(struct pci_vdev * dev,int i2c_bus)156 acpi_add_i2c_adapter(struct pci_vdev *dev, int i2c_bus)
157 {
158 dsdt_line("Device (I2C%d)", i2c_bus);
159 dsdt_line("{");
160 dsdt_line(" Name (_ADR, 0x%04X%04X)", dev->slot, dev->func);
161 dsdt_line(" Name (_DDN, \"Intel(R) I2C Controller #%d\")", i2c_bus);
162 dsdt_line(" Name (_UID, One)");
163 dsdt_line(" Name (LINK, \"\\\\_SB.PCI%d.I2C%d\")", dev->bus, i2c_bus);
164 dsdt_line(" Name (RBUF, ResourceTemplate ()");
165 dsdt_line(" {");
166 dsdt_line(" })");
167 dsdt_line(" Name (IC0S, 0x00061A80)");
168 dsdt_line(" Name (_DSD, Package (0x02)");
169 dsdt_line(" {");
170 dsdt_line(" ToUUID (\"daffd814-6eba-4d8c-8a91-bc9bbf4aa301\")"
171 " ,");
172 dsdt_line(" Package (0x01)");
173 dsdt_line(" {");
174 dsdt_line(" Package (0x02)");
175 dsdt_line(" {");
176 dsdt_line(" \"clock-frequency\", ");
177 dsdt_line(" IC0S");
178 dsdt_line(" }");
179 dsdt_line(" }");
180 dsdt_line(" })");
181 dsdt_line("");
182 dsdt_line("}");
183 }
184
185 static void
acpi_add_cam1(struct pci_vdev * dev,int i2c_bus)186 acpi_add_cam1(struct pci_vdev *dev, int i2c_bus)
187 {
188 dsdt_line("Scope(I2C%d)", i2c_bus);
189 dsdt_line("{");
190 dsdt_line(" Device (CAM1)");
191 dsdt_line(" {");
192 dsdt_line(" Name (_ADR, Zero) // _ADR: Address");
193 dsdt_line(" Name (_HID, \"ADV7481A\") // _HID: Hardware ID");
194 dsdt_line(" Name (_CID, \"ADV7481A\") // _CID: Compatible ID");
195 dsdt_line(" Name (_UID, One) // _UID: Unique ID");
196 dsdt_line(" Method (_CRS, 0, Serialized)");
197 dsdt_line(" {");
198 dsdt_line(" Name (SBUF, ResourceTemplate ()");
199 dsdt_line(" {");
200 dsdt_line(" GpioIo (Exclusive, PullDefault, 0x0000, "
201 "0x0000, IoRestrictionInputOnly,");
202 dsdt_line(" \"\\\\_SB.GPO0\", 0x00, "
203 "ResourceConsumer, ,");
204 dsdt_line(" )");
205 dsdt_line(" { // Pin list");
206 dsdt_line(" 0x001E");
207 dsdt_line(" }");
208 dsdt_line(" I2cSerialBusV2 (0x0070, "
209 "ControllerInitiated, 0x00061A80,");
210 dsdt_line(" AddressingMode7Bit, "
211 "\"\\\\_SB.PCI%d.I2C%d\",",
212 dev->bus, i2c_bus);
213 dsdt_line(" 0x00, ResourceConsumer, , Exclusive,");
214 dsdt_line(" )");
215 dsdt_line(" })");
216 dsdt_line(" Return (SBUF)");
217 dsdt_line(" }");
218 dsdt_line(" Method (_DSM, 4, NotSerialized)");
219 dsdt_line(" {");
220 dsdt_line(" If ((Arg0 == ToUUID ("
221 "\"377ba76a-f390-4aff-ab38-9b1bf33a3015\")))");
222 dsdt_line(" {");
223 dsdt_line(" Return (\"ADV7481A\")");
224 dsdt_line(" }");
225 dsdt_line("");
226 dsdt_line(" If ((Arg0 == ToUUID ("
227 "\"ea3b7bd8-e09b-4239-ad6e-ed525f3f26ab\")))");
228 dsdt_line(" {");
229 dsdt_line(" Return (0x40)");
230 dsdt_line(" }");
231 dsdt_line("");
232 dsdt_line(" If ((Arg0 == ToUUID ("
233 "\"8dbe2651-70c1-4c6f-ac87-a37cb46e4af6\")))");
234 dsdt_line(" {");
235 dsdt_line(" Return (0xFF)");
236 dsdt_line(" }");
237 dsdt_line("");
238 dsdt_line(" If ((Arg0 == ToUUID ("
239 "\"26257549-9271-4ca4-bb43-c4899d5a4881\")))");
240 dsdt_line(" {");
241 dsdt_line(" If (Arg2 == One)");
242 dsdt_line(" {");
243 dsdt_line(" Return (0x02)");
244 dsdt_line(" }");
245 dsdt_line(" If (Arg2 == 0x02)");
246 dsdt_line(" {");
247 dsdt_line(" Return (0x02001000)");
248 dsdt_line(" }");
249 dsdt_line(" If (Arg2 == 0x03)");
250 dsdt_line(" {");
251 dsdt_line(" Return (0x02000E01)");
252 dsdt_line(" }");
253 dsdt_line(" }");
254 dsdt_line(" Return (Zero)");
255 dsdt_line(" }");
256 dsdt_line(" }");
257 dsdt_line("}");
258 }
259
260 static void
acpi_add_cam2(struct pci_vdev * dev,int i2c_bus)261 acpi_add_cam2(struct pci_vdev *dev, int i2c_bus)
262 {
263 dsdt_line("Scope(I2C%d)", i2c_bus);
264 dsdt_line("{");
265 dsdt_line(" Device (CAM2)");
266 dsdt_line(" {");
267 dsdt_line(" Name (_ADR, Zero) // _ADR: Address");
268 dsdt_line(" Name (_HID, \"ADV7481B\") // _HID: Hardware ID");
269 dsdt_line(" Name (_CID, \"ADV7481B\") // _CID: Compatible ID");
270 dsdt_line(" Name (_UID, One) // _UID: Unique ID");
271 dsdt_line(" Method (_CRS, 0, Serialized)");
272 dsdt_line(" {");
273 dsdt_line(" Name (SBUF, ResourceTemplate ()");
274 dsdt_line(" {");
275 dsdt_line(" GpioIo (Exclusive, PullDefault, 0x000, "
276 "0x0000, IoRestrictionInputOnly,");
277 dsdt_line(" \"\\\\_SB.GPO0\", 0x00, "
278 "ResourceConsumer, ,");
279 dsdt_line(" )");
280 dsdt_line(" { // Pin list");
281 dsdt_line(" 0x001E");
282 dsdt_line(" }");
283 dsdt_line(" I2cSerialBusV2 (0x0071, "
284 "ControllerInitiated, 0x00061A80,");
285 dsdt_line(" AddressingMode7Bit, "
286 "\"\\\\_SB.PCI%d.I2C%d\",",
287 dev->bus, i2c_bus);
288 dsdt_line(" 0x00, ResourceConsumer, , Exclusive,");
289 dsdt_line(" )");
290 dsdt_line(" })");
291 dsdt_line(" Return (SBUF)");
292 dsdt_line(" }");
293 dsdt_line(" Method (_DSM, 4, NotSerialized) ");
294 dsdt_line(" {");
295 dsdt_line(" If ((Arg0 == ToUUID ("
296 "\"377ba76a-f390-4aff-ab38-9b1bf33a3015\")))");
297 dsdt_line(" {");
298 dsdt_line(" Return (\"ADV7481B\")");
299 dsdt_line(" }");
300 dsdt_line("");
301 dsdt_line(" If ((Arg0 == ToUUID ("
302 "\"ea3b7bd8-e09b-4239-ad6e-ed525f3f26ab\")))");
303 dsdt_line(" {");
304 dsdt_line(" Return (0x14)");
305 dsdt_line(" }");
306 dsdt_line("");
307 dsdt_line(" If ((Arg0 == ToUUID ("
308 "\"8dbe2651-70c1-4c6f-ac87-a37cb46e4af6\")))");
309 dsdt_line(" {");
310 dsdt_line(" Return (0xFF)");
311 dsdt_line(" }");
312 dsdt_line("");
313 dsdt_line(" If ((Arg0 == ToUUID ("
314 "\"26257549-9271-4ca4-bb43-c4899d5a4881\")))");
315 dsdt_line(" {");
316 dsdt_line(" If (Arg2 == One)");
317 dsdt_line(" {");
318 dsdt_line(" Return (0x02)");
319 dsdt_line(" }");
320 dsdt_line(" If (Arg2 == 0x02)");
321 dsdt_line(" {");
322 dsdt_line(" Return (0x02001000)");
323 dsdt_line(" }");
324 dsdt_line(" If (Arg2 == 0x03)");
325 dsdt_line(" {");
326 dsdt_line(" Return (0x02000E01)");
327 dsdt_line(" }");
328 dsdt_line(" }");
329 dsdt_line(" Return (Zero)");
330 dsdt_line(" }");
331 dsdt_line(" }");
332 dsdt_line("");
333 dsdt_line("}");
334 }
335
336 static void
acpi_add_hdac(struct pci_vdev * dev,int i2c_bus)337 acpi_add_hdac(struct pci_vdev *dev, int i2c_bus)
338 {
339 dsdt_line("Scope(I2C%d)", i2c_bus);
340 dsdt_line("{");
341 dsdt_line(" Device (HDAC)");
342 dsdt_line(" {");
343 dsdt_line(" Name (_HID, \"INT34C3\") // _HID: Hardware ID");
344 dsdt_line(" Name (_CID, \"INT34C3\") // _CID: Compatible ID");
345 dsdt_line(" Name (_DDN, \"Intel(R) Smart Sound Technology "
346 "Audio Codec\") // _DDN: DOS Device Name");
347 dsdt_line(" Name (_UID, One) // _UID: Unique ID");
348 dsdt_line(" Method (_INI, 0, NotSerialized)");
349 dsdt_line(" {");
350 dsdt_line(" }");
351 dsdt_line("");
352 dsdt_line(" Method (_CRS, 0, NotSerialized)");
353 dsdt_line(" {");
354 dsdt_line(" Name (SBFB, ResourceTemplate ()");
355 dsdt_line(" {");
356 dsdt_line(" I2cSerialBusV2 (0x006C, "
357 "ControllerInitiated, 0x00061A80,");
358 dsdt_line(" AddressingMode7Bit, "
359 "\"\\\\_SB.PCI%d.I2C%d\",",
360 dev->bus, i2c_bus);
361 dsdt_line(" 0x00, ResourceConsumer, , Exclusive,");
362 dsdt_line(" )");
363 dsdt_line(" })");
364 dsdt_line(" Name (SBFI, ResourceTemplate ()");
365 dsdt_line(" {");
366 dsdt_line(" })");
367 dsdt_line(" Return (ConcatenateResTemplate (SBFB, SBFI))");
368 dsdt_line(" }");
369 dsdt_line("");
370 dsdt_line(" Method (_STA, 0, NotSerialized) // _STA: Status");
371 dsdt_line(" {");
372 dsdt_line(" Return (0x0F)");
373 dsdt_line(" }");
374 dsdt_line(" }");
375 dsdt_line("}");
376 }
377
378 static void
acpi_add_default(struct pci_vdev * dev,int i2c_bus)379 acpi_add_default(struct pci_vdev *dev, int i2c_bus)
380 {
381 /* Add nothing */
382 }
383
384 static bool
native_client_access_ok(struct native_i2c_adapter * adapter,uint16_t addr)385 native_client_access_ok(struct native_i2c_adapter *adapter, uint16_t addr)
386 {
387 if (ioctl(adapter->fd, I2C_SLAVE, addr) < 0) {
388 if (errno == EBUSY) {
389 WPRINTF("i2c_core: client device %x is busy!\n", addr);
390 } else {
391 WPRINTF("i2c_core: client device %d is not exsit!\n", addr);
392 }
393 return false;
394 }
395 return true;
396 }
397
398 static struct native_i2c_adapter *
native_adapter_find(struct virtio_i2c * vi2c,uint16_t addr)399 native_adapter_find(struct virtio_i2c *vi2c, uint16_t addr)
400 {
401 int idx;
402
403 if (addr < MAX_I2C_VDEV && ((idx = vi2c->adapter_map[addr]) != 0)) {
404 return vi2c->native_adapter[idx - 1];
405 }
406 return NULL;
407 }
408
409 static uint8_t
native_adapter_proc(struct virtio_i2c * vi2c,struct i2c_msg * msg)410 native_adapter_proc(struct virtio_i2c *vi2c, struct i2c_msg *msg)
411 {
412 int ret;
413 uint16_t addr;
414 struct i2c_rdwr_ioctl_data work_queue;
415 struct native_i2c_adapter *adapter;
416 uint8_t status;
417
418 addr = msg->addr;
419 adapter = native_adapter_find(vi2c, addr);
420 if (!adapter) {
421 DPRINTF("%s: could not find device for addr %x\n", __func__, msg->addr);
422 return I2C_MSG_ERR;
423 }
424
425 work_queue.nmsgs = 1;
426 work_queue.msgs = msg;
427
428 ret = ioctl(adapter->fd, I2C_RDWR, &work_queue);
429 if (ret < 0)
430 status = I2C_MSG_ERR;
431 else
432 status = I2C_MSG_OK;
433 if (msg->len)
434 DPRINTF("i2c_core: i2c msg: flags=0x%x, addr=0x%x, len=0x%x buf=%x\n",
435 msg->flags,
436 msg->addr,
437 msg->len,
438 msg->buf[0]);
439 else
440 DPRINTF("i2c_core: i2c msg: flags=0x%x, addr=0x%x, len=0x%x\n",
441 msg->flags,
442 msg->addr,
443 msg->len);
444 return status;
445 }
446
447 static struct native_i2c_adapter *
native_adapter_create(int bus,uint16_t client_addr[],int n_client)448 native_adapter_create(int bus, uint16_t client_addr[], int n_client)
449 {
450 int fd;
451 struct native_i2c_adapter *native_adapter;
452 char native_path[20];
453 int i;
454 unsigned long funcs;
455
456 if (bus < 0)
457 return NULL;
458
459 native_adapter = calloc(1, sizeof(struct native_i2c_adapter));
460 if (native_adapter == NULL) {
461 WPRINTF("i2c_core: failed to calloc struct virtio_i2c_vdev");
462 return NULL;
463 }
464
465 snprintf(native_path, sizeof(native_path), "/dev/i2c-%d", bus);
466 native_path[sizeof(native_path) - 1] = '\0';
467
468 fd = open(native_path, O_RDWR);
469 if (fd < 0) {
470 WPRINTF("virtio_i2c: failed to open %s\n", native_path);
471 goto fail;
472 }
473 if (ioctl(fd, I2C_FUNCS, &funcs) < 0) {
474 WPRINTF("virtio_i2c: failed to get the funcs \n");
475 goto fail;
476 }
477
478 if (!(funcs & I2C_FUNC_I2C)) {
479 WPRINTF("virtio_i2c: this adapter %s doesn't support I2C_FUNC_I2C mode "
480 "(plain i2c-level commands)!\n", native_path);
481 goto fail;
482 }
483 native_adapter->fd = fd;
484 native_adapter->bus = bus;
485 for (i = 0; i < n_client; i++) {
486 if (client_addr[i]) {
487 if (native_client_access_ok(native_adapter, client_addr[i])) {
488 if (native_adapter->i2cdev_enable[client_addr[i]]) {
489 WPRINTF("client addr 0x%x repeat, not allowed.\n", client_addr[i]);
490 goto fail;
491 }
492 native_adapter->i2cdev_enable[client_addr[i]] = true;
493 DPRINTF("virtio_i2c: add client 0x%x\n", client_addr[i]);
494 } else {
495 goto fail;
496 }
497 }
498 }
499 return native_adapter;
500
501 fail:
502 free(native_adapter);
503 return NULL;
504 }
505
506 static void
native_adapter_remove(struct virtio_i2c * vi2c)507 native_adapter_remove(struct virtio_i2c *vi2c)
508 {
509 int i;
510 struct native_i2c_adapter *native_adapter;
511
512 for (i = 0; i < MAX_NATIVE_I2C_ADAPTER; i++) {
513 native_adapter = vi2c->native_adapter[i];
514 if (native_adapter) {
515 if (native_adapter->fd > 0)
516 close(native_adapter->fd);
517 free(native_adapter);
518 vi2c->native_adapter[i] = NULL;
519 }
520 }
521 }
522
523 static void
virtio_i2c_req_stop(struct virtio_i2c * vi2c)524 virtio_i2c_req_stop(struct virtio_i2c *vi2c)
525 {
526 void *jval;
527
528 pthread_mutex_lock(&vi2c->req_mtx);
529 vi2c->closing = 1;
530 pthread_cond_broadcast(&vi2c->req_cond);
531 pthread_mutex_unlock(&vi2c->req_mtx);
532 pthread_join(vi2c->req_tid, &jval);
533 }
534
535 static void *
virtio_i2c_proc_thread(void * arg)536 virtio_i2c_proc_thread(void *arg)
537 {
538 struct virtio_i2c *vi2c = arg;
539 struct virtio_vq_info *vq = &vi2c->vq;
540 struct iovec iov[3];
541 uint16_t idx, flags[3];
542 struct i2c_msg msg;
543 int n;
544 bool fail_next = false;
545 struct virtio_i2c_out_hdr *out_hdr;
546 struct virtio_i2c_in_hdr *in_hdr;
547
548 for (;;) {
549 pthread_mutex_lock(&vi2c->req_mtx);
550
551 vi2c->in_process = 0;
552 while (!vq_has_descs(vq) && !vi2c->closing)
553 pthread_cond_wait(&vi2c->req_cond, &vi2c->req_mtx);
554
555 if (vi2c->closing) {
556 pthread_mutex_unlock(&vi2c->req_mtx);
557 return NULL;
558 }
559 vi2c->in_process = 1;
560 pthread_mutex_unlock(&vi2c->req_mtx);
561 do {
562 n = vq_getchain(vq, &idx, iov, 3, flags);
563 if (n < 2 || n > 3) {
564 WPRINTF("virtio_i2c_proc: failed to get iov from virtqueue\n");
565 continue;
566 }
567 out_hdr = iov[0].iov_base;
568 /* From v1.2-cs01 virtio spec, 7-bit address is defined as:
569 * -----------------------------------------------------------
570 * Bits |15|14|13|12|11|10|9|8|7 |6 |5 |4 |3 |2 |1 |0|
571 * -------------+--+--+--+--+--+--+-+-+--+--+--+--+--+--+--+-+
572 * 7-bit address|0 |0 |0 |0 |0 |0 |0|0|A6|A5|A4|A3|A2|A1|A0|0|
573 * -------------+--+--+--+--+--+--+-+-+--+--+--+--+--+--+--+-+
574 */
575 msg.addr = out_hdr->addr >> 1;
576 if (out_hdr->flags & VIRTIO_I2C_FLAGS_M_RD)
577 msg.flags = I2C_M_RD;
578 else
579 msg.flags = I2C_NO_FLAGS;
580 if (n == 3) {
581 msg.buf = iov[1].iov_base;
582 msg.len = iov[1].iov_len;
583 in_hdr = iov[2].iov_base;
584 } else {
585 // this is a zero-length request
586 msg.buf = NULL;
587 msg.len = 0;
588 in_hdr = iov[1].iov_base;
589 }
590
591 /*
592 * From v1.2-cs01 virtio spec:
593 * VIRTIO_I2C_FLAGS_FAIL_NEXT(0) is used to group the requests. For a group requests,
594 * a driver clears this bit on the final request and sets it on the other requests.
595 * If this bit is set and a device fails to process the current request, it needs to
596 * fail the next request instead of attempting to execute it.
597 */
598 if (!fail_next) {
599 in_hdr->status = native_adapter_proc(vi2c, &msg);
600 if ((out_hdr->flags & VIRTIO_I2C_FLAGS_FAIL_NEXT) && (in_hdr->status == I2C_MSG_ERR))
601 fail_next = true;
602 } else {
603 in_hdr->status = I2C_MSG_ERR;
604 }
605 vq_relchain(vq, idx, 1);
606
607 if (!(out_hdr->flags & VIRTIO_I2C_FLAGS_FAIL_NEXT))
608 fail_next = false;
609 } while (vq_has_descs(vq));
610 vq_endchains(vq, 0);
611 }
612 }
613
614 static int
virtio_i2c_map(struct virtio_i2c * vi2c)615 virtio_i2c_map(struct virtio_i2c *vi2c)
616 {
617 int i, client_addr;
618 struct native_i2c_adapter *native_adapter;
619
620 /*
621 * Flatten the map for client address and native adapter to the array:
622 *
623 * adapter_map[MAX_I2C_VDEV]:
624 *
625 * Native Adapter | adapter2 | none | adapter1 | adapter3 | none | none| (val)
626 * |----------|-------|----------|----------|------|-----|
627 * Slave Address | addr 1 | none | addr 2 | addr 3 | none | none| (idx)
628 * |<-----------------------MAX_I2C_VDEV---------------->|
629 */
630 for (i = 0; i < vi2c->native_adapter_num; i++) {
631 native_adapter = vi2c->native_adapter[i];
632 for (client_addr = 0; client_addr < MAX_I2C_VDEV; client_addr++) {
633 if (native_adapter->i2cdev_enable[client_addr]) {
634 if (vi2c->adapter_map[client_addr]) {
635 WPRINTF("client addr %x repeat, not support!\n", client_addr);
636 return -1;
637 }
638 /* As 0 is the initiate value, + 1 for index */
639 vi2c->adapter_map[client_addr] = i + 1;
640 DPRINTF("client:%d -> native adapter: %d\n",
641 client_addr,
642 native_adapter->bus);
643 }
644 }
645 }
646 return 0;
647 }
648
649 static int
virtio_i2c_parse(struct virtio_i2c * vi2c,char * optstr)650 virtio_i2c_parse(struct virtio_i2c *vi2c, char *optstr)
651 {
652 char *cp, *t, *dsdt_str, *p;
653 uint16_t client_addr[MAX_I2C_VDEV];
654 int addr, bus, n_adapter, n_client;
655
656 /*
657 * virtio-i2c,<bus>:<client_addr[@<node>]>[:<client_addr[@<node>]>],
658 * [<bus>:<client_addr[@<node>]>[:<client_addr>[@<node>]]]
659 *
660 * bus (dec): native adatper bus number.
661 * e.g. 2 for /dev/i2c-2
662 * client_addr (hex): address for native client device
663 * e.g. 0x1C or 1C
664 * @<node>: node is the acpi node name defined in acpi_node_table[]
665 * e.g. @cam1 means adding 'cam1' node to dsdt table.
666 *
667 * Note: client address can not repeat.
668 */
669 n_adapter = 0;
670 while (optstr != NULL) {
671 cp = strsep(&optstr, ",");
672 /*
673 * <bus>:<client_addr>[:<client_addr>]...
674 */
675 n_client = 0;
676 bus = -1;
677 while (cp != NULL && *cp !='\0') {
678 if (*cp == ':')
679 cp++;
680
681 if (bus == -1) {
682 if (dm_strtoi(cp, &t, 10, &bus) || bus < 0)
683 return -1;
684 } else {
685 if (dm_strtoi(cp, &t, 16, &addr) || addr < 0)
686 return -1;
687 if (n_client > MAX_I2C_VDEV) {
688 WPRINTF("too many devices, only support %d \n", MAX_I2C_VDEV);
689 return -1;
690 }
691 client_addr[n_client] = (uint16_t)(addr & (MAX_I2C_VDEV - 1));
692 p = &vi2c->acpi_nodes[client_addr[n_client]][0];
693 if (t != NULL && *t == '@') {
694 t++;
695 dsdt_str = strsep(&t, ":,");
696 snprintf(p, MAX_NODE_NAME_LEN, "%s", dsdt_str);
697 } else {
698 snprintf(p, MAX_NODE_NAME_LEN, "default");
699 }
700 DPRINTF("native i2c adapter %d:0x%x (%s)\n",
701 bus,
702 client_addr[n_client],
703 p);
704 n_client++;
705 }
706 cp = t;
707 }
708 if (n_adapter >= MAX_NATIVE_I2C_ADAPTER) {
709 WPRINTF("too many adapter, only support %d \n", MAX_NATIVE_I2C_ADAPTER);
710 return -1;
711 }
712 vi2c->native_adapter[n_adapter] = native_adapter_create(bus, client_addr, n_client);
713 if (!vi2c->native_adapter[n_adapter])
714 return -1;
715 n_adapter++;
716 }
717 vi2c->native_adapter_num = n_adapter;
718
719 return 0;
720 }
721
722 static void
virtio_i2c_dsdt(struct pci_vdev * dev)723 virtio_i2c_dsdt(struct pci_vdev *dev)
724 {
725 int i, j, node_num;
726 struct acpi_node *anode;
727 int i2c_bus;
728 int found;
729 struct virtio_i2c *vi2c = (struct virtio_i2c *) dev->arg;
730
731 /* i2c bus number in acpi start from 0 */
732 i2c_bus = acpi_i2c_adapter_num;
733 /* add i2c adapter */
734 acpi_add_i2c_adapter(dev, i2c_bus);
735 DPRINTF("add dsdt for i2c adapter %d\n", i2c_bus);
736
737 /* add client devices */
738 node_num = sizeof(acpi_node_table) / sizeof(struct acpi_node);
739 for (i = 0; i < MAX_I2C_VDEV; i++) {
740 if (!native_adapter_find(vi2c, i))
741 continue;
742
743 found = 0;
744 for (j = 0; j < node_num; j++) {
745 anode = &acpi_node_table[j];
746 if (!strncmp(anode->node_name, vi2c->acpi_nodes[i], sizeof(anode->node_name))) {
747 found = 1;
748 if (anode->add_node_fn) {
749 anode->add_node_fn(dev, i2c_bus);
750 DPRINTF("add dsdt for %s \n", anode->node_name);
751 }
752 }
753 }
754 if (!found)
755 WPRINTF("cannot find acpi node info for %s \n", vi2c->acpi_nodes[i]);
756 }
757 acpi_i2c_adapter_num++;
758 }
759
760 static void
virtio_i2c_reset(void * vdev)761 virtio_i2c_reset(void *vdev)
762 {
763 struct virtio_i2c *vi2c = vdev;
764
765 DPRINTF("device reset requested !\n");
766 virtio_reset_dev(&vi2c->base);
767 }
768
769 static void
virtio_i2c_notify(void * vdev,struct virtio_vq_info * vq)770 virtio_i2c_notify(void *vdev, struct virtio_vq_info *vq)
771 {
772 struct virtio_i2c *vi2c = vdev;
773
774 if (!vq_has_descs(vq))
775 return;
776
777 pthread_mutex_lock(&vi2c->req_mtx);
778 if (!vi2c->in_process)
779 pthread_cond_signal(&vi2c->req_cond);
780 pthread_mutex_unlock(&vi2c->req_mtx);
781 }
782
783 static int
virtio_i2c_init(struct vmctx * ctx,struct pci_vdev * dev,char * opts)784 virtio_i2c_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
785 {
786 u_char digest[16];
787 struct virtio_i2c *vi2c;
788 pthread_mutexattr_t attr;
789 int rc = -1;
790
791 vi2c = calloc(1, sizeof(struct virtio_i2c));
792 if (!vi2c) {
793 WPRINTF("calloc returns NULL\n");
794 return -ENOMEM;
795 }
796
797 if (virtio_i2c_parse(vi2c, opts)) {
798 WPRINTF("failed to parse parameters %s \n", opts);
799 goto mtx_fail;
800 }
801
802 if (virtio_i2c_map(vi2c))
803 goto mtx_fail;
804
805 /* init mutex attribute properly to avoid deadlock */
806 rc = pthread_mutexattr_init(&attr);
807 if (rc) {
808 WPRINTF("mutexattr init failed with erro %d!\n", rc);
809 goto mtx_fail;
810 }
811 rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
812 if (rc) {
813 WPRINTF("mutexattr_settype failed with "
814 "error %d!\n", rc);
815 goto mtx_fail;
816 }
817
818 rc = pthread_mutex_init(&vi2c->mtx, &attr);
819 if (rc) {
820 WPRINTF("pthread_mutex_init failed with "
821 "error %d!\n", rc);
822 goto mtx_fail;
823 }
824
825 /* init virtio struct and virtqueues */
826 virtio_linkup(&vi2c->base, &virtio_i2c_ops, vi2c, dev, &vi2c->vq, BACKEND_VBSU);
827 vi2c->base.mtx = &vi2c->mtx;
828 vi2c->base.device_caps = VIRTIO_I2C_HOSTCAPS;
829 vi2c->vq.qsize = 64;
830 vi2c->native_adapter_num = 0;
831
832 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
833 EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
834 EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
835 EVP_DigestUpdate(mdctx, "vi2c", strlen("vi2c"));
836 EVP_DigestFinal_ex(mdctx, digest, NULL);
837 EVP_MD_CTX_free(mdctx);
838 #else
839 MD5_CTX mdctx;
840 MD5_Init(&mdctx);
841 MD5_Update(&mdctx, "vi2c", strlen("vi2c"));
842 MD5_Final(digest, &mdctx);
843 #endif
844 rc = snprintf(vi2c->ident, sizeof(vi2c->ident),
845 "ACRN--%02X%02X-%02X%02X-%02X%02X", digest[0],
846 digest[1], digest[2], digest[3], digest[4],
847 digest[5]);
848 if (rc < 0) {
849 WPRINTF("create ident failed");
850 goto fail;
851 }
852 if (rc >= sizeof(vi2c->ident)) {
853 WPRINTF("ident too long\n");
854 }
855
856 pci_set_cfgdata16(dev, PCIR_DEVICE, VIRTIO_DEV_I2C);
857 pci_set_cfgdata16(dev, PCIR_VENDOR, VIRTIO_VENDOR);
858 pci_set_cfgdata8(dev, PCIR_CLASS, PCIS_SERIALBUS_SMBUS);
859 pci_set_cfgdata16(dev, PCIR_SUBDEV_0, VIRTIO_TYPE_I2C);
860 pci_set_cfgdata16(dev, PCIR_SUBVEND_0, VIRTIO_VENDOR);
861
862 if (virtio_interrupt_init(&vi2c->base, virtio_uses_msix())) {
863 WPRINTF("failed to init interrupt");
864 rc = -1;
865 goto fail;
866 }
867 rc = virtio_set_modern_bar(&vi2c->base, false);
868 vi2c->in_process = 0;
869 vi2c->closing = 0;
870 pthread_mutex_init(&vi2c->req_mtx, NULL);
871 pthread_cond_init(&vi2c->req_cond, NULL);
872 pthread_create(&vi2c->req_tid, NULL, virtio_i2c_proc_thread, vi2c);
873 pthread_setname_np(vi2c->req_tid, "virtio-i2c");
874 return 0;
875
876 fail:
877 pthread_mutex_destroy(&vi2c->mtx);
878 mtx_fail:
879 native_adapter_remove(vi2c);
880 free(vi2c);
881 return rc;
882 }
883
884 static void
virtio_i2c_deinit(struct vmctx * ctx,struct pci_vdev * dev,char * opts)885 virtio_i2c_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
886 {
887 struct virtio_i2c *vi2c;
888
889 if (dev->arg) {
890 DPRINTF("deinit\n");
891 vi2c = (struct virtio_i2c *) dev->arg;
892 virtio_i2c_req_stop(vi2c);
893 native_adapter_remove(vi2c);
894 pthread_mutex_destroy(&vi2c->req_mtx);
895 pthread_mutex_destroy(&vi2c->mtx);
896 virtio_i2c_reset(vi2c);
897 acpi_i2c_adapter_num--;
898 assert(acpi_i2c_adapter_num >= 0);
899 free(vi2c);
900 dev->arg = NULL;
901 }
902 }
903
904 struct pci_vdev_ops pci_ops_virtio_i2c = {
905 .class_name = "virtio-i2c",
906 .vdev_init = virtio_i2c_init,
907 .vdev_deinit = virtio_i2c_deinit,
908 .vdev_barwrite = virtio_pci_write,
909 .vdev_barread = virtio_pci_read,
910 .vdev_write_dsdt = virtio_i2c_dsdt,
911 };
912 DEFINE_PCI_DEVTYPE(pci_ops_virtio_i2c);
913