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