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 |