Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_lpc.c
| Show All 27 Lines | |||||
| * | * | ||||
| * $FreeBSD$ | * $FreeBSD$ | ||||
| */ | */ | ||||
| #include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
| __FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
| #include <sys/types.h> | #include <sys/types.h> | ||||
| #include <sys/pciio.h> | |||||
| #include <machine/vmm.h> | #include <machine/vmm.h> | ||||
| #include <machine/vmm_snapshot.h> | #include <machine/vmm_snapshot.h> | ||||
| #include <err.h> | |||||
| #include <errno.h> | |||||
| #include <fcntl.h> | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include <vmmapi.h> | #include <vmmapi.h> | ||||
| #include "acpi.h" | #include "acpi.h" | ||||
| #include "debug.h" | #include "debug.h" | ||||
| Show All 33 Lines | |||||
| static const char *lpc_uart_names[LPC_UART_NUM] = { | static const char *lpc_uart_names[LPC_UART_NUM] = { | ||||
| "com1", "com2", "com3", "com4" | "com1", "com2", "com3", "com4" | ||||
| }; | }; | ||||
| static const char *lpc_uart_acpi_names[LPC_UART_NUM] = { | static const char *lpc_uart_acpi_names[LPC_UART_NUM] = { | ||||
| "COM1", "COM2", "COM3", "COM4" | "COM1", "COM2", "COM3", "COM4" | ||||
| }; | }; | ||||
| #ifndef _PATH_DEVPCI | |||||
| #define _PATH_DEVPCI "/dev/pci" | |||||
| #endif | |||||
| static int pcifd = -1; | |||||
| static uint32_t | |||||
| read_config(struct pcisel *sel, long reg, int width) | |||||
| { | |||||
| struct pci_io pi; | |||||
| pi.pi_sel.pc_domain = sel->pc_domain; | |||||
| pi.pi_sel.pc_bus = sel->pc_bus; | |||||
| pi.pi_sel.pc_dev = sel->pc_dev; | |||||
| pi.pi_sel.pc_func = sel->pc_func; | |||||
| pi.pi_reg = reg; | |||||
| pi.pi_width = width; | |||||
| if (ioctl(pcifd, PCIOCREAD, &pi) < 0) | |||||
| return (0); | |||||
| return (pi.pi_data); | |||||
| } | |||||
| /* | /* | ||||
| * LPC device configuration is in the following form: | * LPC device configuration is in the following form: | ||||
| * <lpc_device_name>[,<options>] | * <lpc_device_name>[,<options>] | ||||
| * For e.g. "com1,stdio" or "bootrom,/var/romfile" | * For e.g. "com1,stdio" or "bootrom,/var/romfile" | ||||
| */ | */ | ||||
| int | int | ||||
| lpc_device_parse(const char *opts) | lpc_device_parse(const char *opts) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Lines | pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl) | ||||
| if (lpc_init(ctx) != 0) | if (lpc_init(ctx) != 0) | ||||
| return (-1); | return (-1); | ||||
| /* initialize config space */ | /* initialize config space */ | ||||
| pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV); | pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV); | ||||
| pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR); | pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR); | ||||
| pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); | pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); | ||||
| pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); | pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); | ||||
| /* open host device */ | |||||
| if (pcifd < 0) { | |||||
| pcifd = open(_PATH_DEVPCI, O_RDWR, 0); | |||||
| if (pcifd < 0) { | |||||
| warn("failed to open %s", _PATH_DEVPCI); | |||||
| return (-1); | |||||
| } | |||||
| } | |||||
| /* on Intel systems lpc is always connected to 0:1f.0 */ | |||||
| struct pcisel sel; | |||||
| sel.pc_domain = 0; | |||||
| sel.pc_bus = 0; | |||||
| sel.pc_dev = 0x1f; | |||||
| sel.pc_func = 0; | |||||
| if (read_config(&sel, PCIR_VENDOR, 2) == PCI_VENDOR_INTEL) { | |||||
| /* | |||||
| * The VID, DID, REVID, SUBVID and SUBDID of igd-lpc need to be | |||||
| * aligned with the physical ones. Without these physical | |||||
| * values, GVT-d GOP driver couldn't work. | |||||
| */ | |||||
| pci_set_cfgdata16( | |||||
| pi, PCIR_DEVICE, read_config(&sel, PCIR_DEVICE, 2)); | |||||
| pci_set_cfgdata16( | |||||
| pi, PCIR_VENDOR, read_config(&sel, PCIR_VENDOR, 2)); | |||||
| pci_set_cfgdata8( | |||||
| pi, PCIR_REVID, read_config(&sel, PCIR_REVID, 1)); | |||||
| pci_set_cfgdata16( | |||||
| pi, PCIR_SUBVEND_0, read_config(&sel, PCIR_SUBVEND_0, 2)); | |||||
| pci_set_cfgdata16( | |||||
| pi, PCIR_SUBDEV_0, read_config(&sel, PCIR_SUBDEV_0, 2)); | |||||
| } | |||||
| lpc_bridge = pi; | lpc_bridge = pi; | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| char * | char * | ||||
| lpc_pirq_name(int pin) | lpc_pirq_name(int pin) | ||||
| ▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines | |||||