1 /*-
2 * Copyright (c) 2013 Neel Natu <neel@freebsd.org>
3 * Copyright (c) 2013 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD$
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdbool.h>
34 #include <sys/errno.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38
39 #include "dm.h"
40 #include "vmmapi.h"
41 #include "acpi.h"
42 #include "inout.h"
43 #include "pci_core.h"
44 #include "irq.h"
45 #include "lpc.h"
46 #include "pit.h"
47 #include "uart_core.h"
48
49 #define IO_ICU1 0x20
50 #define IO_ICU2 0xA0
51
52 SET_DECLARE(lpc_dsdt_set, struct lpc_dsdt);
53 SET_DECLARE(lpc_sysres_set, struct lpc_sysres);
54
55 #define ELCR_PORT 0x4d0
56 SYSRES_IO(ELCR_PORT, 2);
57
58 SYSRES_IO(NMISC_PORT, 1);
59
60 static struct pci_vdev *lpc_bridge;
61
62 #define LPC_UART_NUM 5
63 static struct lpc_uart_vdev {
64 struct uart_vdev *uart;
65 const char *opts;
66 int iobase;
67 int irq;
68 int enabled; /* enabled/configured by user */
69 } lpc_uart_vdev[LPC_UART_NUM];
70 #define LPC_S5_UART_NAME "COM5"
71
72 static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2", "COM3", "COM4", LPC_S5_UART_NAME};
73
74 /*
75 * LPC device configuration is in the following form:
76 * <lpc_device_name>[,<options>]
77 * For e.g. "com1,stdio"
78 * For S5 e.g. "com5,/dev/pts/0,0x9000,5"
79 */
80 int
lpc_device_parse(const char * opts)81 lpc_device_parse(const char *opts)
82 {
83 int unit, error;
84 char *str, *cpy, *lpcdev;
85 char *lpcopt, *lpcport, *endptr;
86 int s5_port = 0, s5_irq = 0;
87
88 error = -1;
89 str = cpy = strdup(opts);
90 lpcdev = strsep(&str, ",");
91 if (lpcdev != NULL) {
92 for (unit = 0; unit < LPC_UART_NUM; unit++) {
93 if (strcasecmp(lpcdev, lpc_uart_names[unit]) == 0) {
94 lpc_uart_vdev[unit].enabled = 1;
95 if(strcasecmp(lpcdev,LPC_S5_UART_NAME) == 0){
96 lpcopt = strsep(&str,",");
97 if(lpcopt != NULL){
98 lpc_uart_vdev[unit].opts = lpcopt;
99 }
100 lpcport = strsep(&str, ",");
101 if(lpcport != NULL){
102 if(dm_strtoul(lpcport, &endptr, 0, (long unsigned int*)&s5_port))
103 goto done;
104 if(dm_strtoul(str, &endptr, 0, (long unsigned int*)&s5_irq))
105 goto done;
106 }
107 if((s5_port != 0) && (s5_irq != 0)){
108 uart_legacy_reinit_res(unit, s5_port, s5_irq);
109 }
110 }
111 else{
112 lpc_uart_vdev[unit].opts = str;
113 }
114 error = 0;
115 goto done;
116 }
117 }
118 }
119
120 done:
121 if (error)
122 free(cpy);
123
124 return error;
125 }
126
127 static void
lpc_uart_intr_assert(void * arg)128 lpc_uart_intr_assert(void *arg)
129 {
130 struct lpc_uart_vdev *lpc_uart = arg;
131
132 if (lpc_uart->irq < 0) {
133 pr_warn("%s: Invalid irq pin lpc_uart\n", __func__);
134 return;
135 }
136
137 if (lpc_bridge)
138 vm_set_gsi_irq(lpc_bridge->vmctx,
139 lpc_uart->irq,
140 GSI_RAISING_PULSE);
141 }
142
143 static void
lpc_uart_intr_deassert(void * arg)144 lpc_uart_intr_deassert(void *arg)
145 {
146 /*
147 * The COM devices on the LPC bus generate edge triggered interrupts,
148 * so nothing more to do here.
149 */
150 }
151
152 static int
lpc_uart_io_handler(struct vmctx * ctx,int vcpu,int in,int port,int bytes,uint32_t * eax,void * arg)153 lpc_uart_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
154 uint32_t *eax, void *arg)
155 {
156 int offset;
157 struct lpc_uart_vdev *lpc_uart = arg;
158
159 offset = port - lpc_uart->iobase;
160
161 switch (bytes) {
162 case 1:
163 if (in)
164 *eax = uart_read(lpc_uart->uart, offset);
165 else
166 uart_write(lpc_uart->uart, offset, *eax);
167 break;
168 case 2:
169 if (in) {
170 *eax = uart_read(lpc_uart->uart, offset);
171 *eax |= uart_read(lpc_uart->uart, offset + 1) << 8;
172 } else {
173 uart_write(lpc_uart->uart, offset, *eax);
174 uart_write(lpc_uart->uart, offset + 1, *eax >> 8);
175 }
176 break;
177 default:
178 return -1;
179 }
180
181 return 0;
182 }
183
184 static void
lpc_deinit(struct vmctx * ctx)185 lpc_deinit(struct vmctx *ctx)
186 {
187 struct lpc_uart_vdev *lpc_uart;
188 struct inout_port iop;
189 const char *name;
190 int unit;
191
192 /* COM1 and COM2 */
193 for (unit = 0; unit < LPC_UART_NUM; unit++) {
194 name = lpc_uart_names[unit];
195 lpc_uart = &lpc_uart_vdev[unit];
196
197 if (lpc_uart->enabled == 0)
198 continue;
199
200 bzero(&iop, sizeof(struct inout_port));
201 iop.name = name;
202 iop.port = lpc_uart->iobase;
203 iop.size = UART_IO_BAR_SIZE;
204 iop.flags = IOPORT_F_INOUT;
205 unregister_inout(&iop);
206
207 uart_release_backend(lpc_uart->uart, lpc_uart->opts);
208 uart_legacy_dealloc(unit);
209 lpc_uart->uart = NULL;
210 }
211 }
212
213
214 static int
lpc_init(struct vmctx * ctx)215 lpc_init(struct vmctx *ctx)
216 {
217 struct lpc_uart_vdev *lpc_uart;
218 struct inout_port iop;
219 const char *name;
220 int unit, error;
221
222 /* COM1 and COM2 */
223 for (unit = 0; unit < LPC_UART_NUM; unit++) {
224 lpc_uart = &lpc_uart_vdev[unit];
225 name = lpc_uart_names[unit];
226
227 if (lpc_uart->enabled == 0)
228 continue;
229
230 if (uart_legacy_alloc(unit,
231 &lpc_uart->iobase,
232 &lpc_uart->irq) != 0) {
233 pr_err("Unable to allocate resources for "
234 "LPC device %s\n", name);
235 goto init_failed;
236 }
237 pci_irq_reserve(lpc_uart->irq);
238
239 lpc_uart->uart = uart_set_backend(lpc_uart_intr_assert, lpc_uart_intr_deassert,
240 lpc_uart, lpc_uart->opts);
241 if (lpc_uart->uart == NULL) {
242 uart_legacy_dealloc(unit);
243 goto init_failed;
244 }
245
246 bzero(&iop, sizeof(struct inout_port));
247 iop.name = name;
248 iop.port = lpc_uart->iobase;
249 iop.size = UART_IO_BAR_SIZE;
250 iop.flags = IOPORT_F_INOUT;
251 iop.handler = lpc_uart_io_handler;
252 iop.arg = lpc_uart;
253
254 error = register_inout(&iop);
255 if (error)
256 goto init_failed;
257 }
258
259 return 0;
260
261 init_failed:
262 lpc_deinit(ctx);
263 return -1;
264 }
265
266 static void
pci_lpc_write_dsdt(struct pci_vdev * dev)267 pci_lpc_write_dsdt(struct pci_vdev *dev)
268 {
269 struct lpc_dsdt **ldpp, *ldp;
270
271 dsdt_line("");
272 dsdt_line("Device (ISA)");
273 dsdt_line("{");
274 dsdt_line(" Name (_ADR, 0x%04X%04X)", dev->slot, dev->func);
275 dsdt_line(" OperationRegion (LPCR, PCI_Config, 0x00, 0x100)");
276 dsdt_line(" Field (LPCR, AnyAcc, NoLock, Preserve)");
277 dsdt_line(" {");
278 dsdt_line(" Offset (0x60),");
279 dsdt_line(" PIRA, 8,");
280 dsdt_line(" PIRB, 8,");
281 dsdt_line(" PIRC, 8,");
282 dsdt_line(" PIRD, 8,");
283 dsdt_line(" Offset (0x68),");
284 dsdt_line(" PIRE, 8,");
285 dsdt_line(" PIRF, 8,");
286 dsdt_line(" PIRG, 8,");
287 dsdt_line(" PIRH, 8");
288 dsdt_line(" }");
289 dsdt_line("");
290
291 dsdt_indent(1);
292 SET_FOREACH(ldpp, lpc_dsdt_set) {
293 ldp = *ldpp;
294 ldp->handler();
295 }
296
297 if(!is_rtvm) {
298 dsdt_line("");
299 dsdt_line("Device (PIC)");
300 dsdt_line("{");
301 dsdt_line(" Name (_HID, EisaId (\"PNP0000\"))");
302 dsdt_line(" Name (_CRS, ResourceTemplate ()");
303 dsdt_line(" {");
304 dsdt_indent(2);
305 dsdt_fixed_ioport(IO_ICU1, 2);
306 dsdt_fixed_ioport(IO_ICU2, 2);
307 dsdt_fixed_irq(2);
308 dsdt_unindent(2);
309 dsdt_line(" })");
310 dsdt_line("}");
311 }
312 dsdt_line("");
313 dsdt_line("Device (TIMR)");
314 dsdt_line("{");
315 dsdt_line(" Name (_HID, EisaId (\"PNP0100\"))");
316 dsdt_line(" Name (_CRS, ResourceTemplate ()");
317 dsdt_line(" {");
318 dsdt_indent(2);
319 dsdt_fixed_ioport(IO_TIMER1_PORT, 4);
320 dsdt_fixed_irq(0);
321 dsdt_unindent(2);
322 dsdt_line(" })");
323 dsdt_line("}");
324 dsdt_unindent(1);
325
326 dsdt_line("}");
327 }
328
329 static void
pci_lpc_sysres_dsdt(void)330 pci_lpc_sysres_dsdt(void)
331 {
332 struct lpc_sysres **lspp, *lsp;
333
334 dsdt_line("");
335 dsdt_line("Device (SIO)");
336 dsdt_line("{");
337 dsdt_line(" Name (_HID, EisaId (\"PNP0C02\"))");
338 dsdt_line(" Name (_CRS, ResourceTemplate ()");
339 dsdt_line(" {");
340
341 dsdt_indent(2);
342 SET_FOREACH(lspp, lpc_sysres_set) {
343 lsp = *lspp;
344 switch (lsp->type) {
345 case LPC_SYSRES_IO:
346 dsdt_fixed_ioport(lsp->base, lsp->length);
347 break;
348 case LPC_SYSRES_MEM:
349 dsdt_fixed_mem32(lsp->base, lsp->length);
350 break;
351 }
352 }
353 dsdt_unindent(2);
354
355 dsdt_line(" })");
356 dsdt_line("}");
357 }
358 LPC_DSDT(pci_lpc_sysres_dsdt);
359
360 static void
pci_lpc_uart_dsdt(void)361 pci_lpc_uart_dsdt(void)
362 {
363 struct lpc_uart_vdev *lpc_uart;
364 int unit;
365
366 for (unit = 0; unit < LPC_UART_NUM; unit++) {
367 lpc_uart = &lpc_uart_vdev[unit];
368 if (!lpc_uart->enabled)
369 continue;
370 dsdt_line("");
371 dsdt_line("Device (%s)", lpc_uart_names[unit]);
372 dsdt_line("{");
373 dsdt_line(" Name (_HID, EisaId (\"PNP0501\"))");
374 dsdt_line(" Name (_UID, %d)", unit + 1);
375 dsdt_line(" Name (_CRS, ResourceTemplate ()");
376 dsdt_line(" {");
377 dsdt_indent(2);
378 dsdt_fixed_ioport(lpc_uart->iobase, UART_IO_BAR_SIZE);
379 dsdt_fixed_irq(lpc_uart->irq);
380 dsdt_unindent(2);
381 dsdt_line(" })");
382 dsdt_line("}");
383 }
384 }
385 LPC_DSDT(pci_lpc_uart_dsdt);
386
387 static int
pci_lpc_cfgwrite(struct vmctx * ctx,int vcpu,struct pci_vdev * pi,int coff,int bytes,uint32_t val)388 pci_lpc_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_vdev *pi,
389 int coff, int bytes, uint32_t val)
390 {
391 int pirq_pin;
392
393 if (bytes == 1) {
394 pirq_pin = 0;
395 if (coff >= 0x60 && coff <= 0x63)
396 pirq_pin = coff - 0x60 + 1;
397 if (coff >= 0x68 && coff <= 0x6b)
398 pirq_pin = coff - 0x68 + 5;
399 if (pirq_pin != 0) {
400 pirq_write(ctx, pirq_pin, val);
401 pci_set_cfgdata8(pi, coff, pirq_read(pirq_pin));
402 return 0;
403 }
404 }
405 return -1;
406 }
407
408 static void
pci_lpc_write(struct vmctx * ctx,int vcpu,struct pci_vdev * pi,int baridx,uint64_t offset,int size,uint64_t value)409 pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_vdev *pi,
410 int baridx, uint64_t offset, int size, uint64_t value)
411 {
412 }
413
414 static uint64_t
pci_lpc_read(struct vmctx * ctx,int vcpu,struct pci_vdev * pi,int baridx,uint64_t offset,int size)415 pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_vdev *pi,
416 int baridx, uint64_t offset, int size)
417 {
418 return 0;
419 }
420
421 #define LPC_DEV 0x7000
422 #define LPC_VENDOR 0x8086
423
424 static int
pci_lpc_init(struct vmctx * ctx,struct pci_vdev * pi,char * opts)425 pci_lpc_init(struct vmctx *ctx, struct pci_vdev *pi, char *opts)
426 {
427 /*
428 * Do not allow more than one LPC bridge to be configured.
429 */
430 if (lpc_bridge != NULL) {
431 pr_err("Only one LPC bridge is allowed.\n");
432 return -1;
433 }
434
435 /*
436 * Enforce that the LPC can only be configured on bus 0. This
437 * simplifies the ACPI DSDT because it can provide a decode for
438 * all legacy i/o ports behind bus 0.
439 */
440 if (pi->bus != 0) {
441 pr_err("LPC bridge can be present only on bus 0.\n");
442 return -1;
443 }
444
445 if (lpc_init(ctx) != 0)
446 return -1;
447
448 /* initialize config space */
449 pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV);
450 pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR);
451 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE);
452 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA);
453
454 lpc_bridge = pi;
455
456 return 0;
457 }
458
459 static void
pci_lpc_deinit(struct vmctx * ctx,struct pci_vdev * pi,char * opts)460 pci_lpc_deinit(struct vmctx *ctx, struct pci_vdev *pi, char *opts)
461 {
462 lpc_bridge = NULL;
463 lpc_deinit(ctx);
464 }
465
466 char *
lpc_pirq_name(int pin)467 lpc_pirq_name(int pin)
468 {
469 char *name = NULL;
470
471 if (lpc_bridge == NULL)
472 return NULL;
473
474 if (asprintf(&name, "\\_SB.PCI0.ISA.LNK%c,", 'A' + pin - 1) < 0) {
475 if (name != NULL)
476 free(name);
477
478 return NULL;
479 }
480 return name;
481 }
482
483 void
lpc_pirq_routed(void)484 lpc_pirq_routed(void)
485 {
486 int pin;
487
488 if (lpc_bridge == NULL)
489 return;
490
491 for (pin = 0; pin < 4; pin++)
492 pci_set_cfgdata8(lpc_bridge, 0x60 + pin, pirq_read(pin + 1));
493 for (pin = 0; pin < 4; pin++)
494 pci_set_cfgdata8(lpc_bridge, 0x68 + pin, pirq_read(pin + 5));
495 }
496
497 static int
pci_igd_lpc_init(struct vmctx * ctx,struct pci_vdev * pi,char * opts)498 pci_igd_lpc_init(struct vmctx *ctx, struct pci_vdev *pi, char *opts)
499 {
500 int fd;
501 uint8_t host_config[PCI_REGMAX+1];
502 int ret;
503
504 fd = open("/sys/bus/pci/devices/0000:00:1f.0/config", O_RDONLY);
505 if (fd == -1) {
506 pr_err("lpcbridge:open host pci config failed\n");
507 return -1;
508 }
509
510 ret = pread(fd, host_config, PCI_REGMAX+1, 0);
511 if (ret <= PCI_REGMAX) {
512 pr_err("failed to read lpcbridge config space\n");
513 return -1;
514 }
515
516 close(fd);
517
518 /*
519 * The VID, DID, REVID, SUBVID, SUBDID of igd-lpc need aligned with physical one.
520 * Without these physical values, gvt-d GOP driver couldn't work.
521 */
522 pci_set_cfgdata16(pi, PCIR_DEVICE, *(uint16_t *)(host_config + PCIR_DEVICE));
523 pci_set_cfgdata16(pi, PCIR_VENDOR, *(uint16_t *)(host_config + PCIR_VENDOR));
524 pci_set_cfgdata8(pi, PCIR_REVID, host_config[PCIR_REVID]);
525 pci_set_cfgdata16(pi, PCIR_SUBVEND_0, *(uint16_t *)(host_config + PCIR_SUBVEND_0));
526 pci_set_cfgdata16(pi, PCIR_SUBDEV_0, *(uint16_t *)(host_config + PCIR_SUBDEV_0));
527
528 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE);
529 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA);
530 return 0;
531 }
532
533 struct pci_vdev_ops pci_ops_lpc = {
534 .class_name = "lpc",
535 .vdev_init = pci_lpc_init,
536 .vdev_deinit = pci_lpc_deinit,
537 .vdev_write_dsdt = pci_lpc_write_dsdt,
538 .vdev_cfgwrite = pci_lpc_cfgwrite,
539 .vdev_barwrite = pci_lpc_write,
540 .vdev_barread = pci_lpc_read
541 };
542 DEFINE_PCI_DEVTYPE(pci_ops_lpc);
543
544 /*
545 * Intel Graphics Device(IGD) passthrough on Windows guest has the restriction
546 * that it need a lpc bridge device located in 00:1f.0 PCI slot.
547 * Here, create an extra lpc class for this restriction.
548 */
549 struct pci_vdev_ops pci_ops_igd_lpc = {
550 .class_name = "igd-lpc",
551 .vdev_init = pci_igd_lpc_init,
552 };
553 DEFINE_PCI_DEVTYPE(pci_ops_igd_lpc);
554