Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_emul.c
Show All 27 Lines | |||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/linker_set.h> | #include <sys/linker_set.h> | ||||
#include <vm/vm.h> | |||||
#include <vm/vm_param.h> | |||||
#include <vm/pmap.h> | |||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <pthread.h> | #include <pthread.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <strings.h> | #include <strings.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <machine/vmm.h> | #include <machine/vmm.h> | ||||
#include <machine/vmm_snapshot.h> | #include <machine/vmm_snapshot.h> | ||||
#include <machine/cpufunc.h> | |||||
#include <machine/specialreg.h> | |||||
#include <vmmapi.h> | #include <vmmapi.h> | ||||
#include "acpi.h" | #include "acpi.h" | ||||
#include "bhyverun.h" | #include "bhyverun.h" | ||||
#include "config.h" | #include "config.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "inout.h" | #include "inout.h" | ||||
#include "ioapic.h" | #include "ioapic.h" | ||||
#include "mem.h" | #include "mem.h" | ||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "pci_irq.h" | #include "pci_irq.h" | ||||
#include "pci_lpc.h" | #include "pci_lpc.h" | ||||
#define CONF1_ADDR_PORT 0x0cf8 | #define CONF1_ADDR_PORT 0x0cf8 | ||||
#define CONF1_DATA_PORT 0x0cfc | #define CONF1_DATA_PORT 0x0cfc | ||||
#define CONF1_ENABLE 0x80000000ul | #define CONF1_ENABLE 0x80000000ul | ||||
#define MAXBUSES (PCI_BUSMAX + 1) | #define MAXBUSES (PCI_BUSMAX + 1) | ||||
#define MAXSLOTS (PCI_SLOTMAX + 1) | #define MAXSLOTS (PCI_SLOTMAX + 1) | ||||
#define MAXFUNCS (PCI_FUNCMAX + 1) | #define MAXFUNCS (PCI_FUNCMAX + 1) | ||||
#define GB (1024 * 1024 * 1024UL) | |||||
struct funcinfo { | struct funcinfo { | ||||
nvlist_t *fi_config; | nvlist_t *fi_config; | ||||
struct pci_devemu *fi_pde; | struct pci_devemu *fi_pde; | ||||
struct pci_devinst *fi_devi; | struct pci_devinst *fi_devi; | ||||
}; | }; | ||||
struct intxinfo { | struct intxinfo { | ||||
int ii_count; | int ii_count; | ||||
Show All 25 Lines | |||||
#define PCI_EMUL_IOBASE 0x2000 | #define PCI_EMUL_IOBASE 0x2000 | ||||
#define PCI_EMUL_IOLIMIT 0x10000 | #define PCI_EMUL_IOLIMIT 0x10000 | ||||
#define PCI_EMUL_ECFG_BASE 0xE0000000 /* 3.5GB */ | #define PCI_EMUL_ECFG_BASE 0xE0000000 /* 3.5GB */ | ||||
#define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */ | #define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */ | ||||
SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); | SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); | ||||
#define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE | #define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE | ||||
#define PCI_EMUL_MEMSIZE64 (32*GB) | |||||
static struct pci_devemu *pci_emul_finddev(const char *name); | static struct pci_devemu *pci_emul_finddev(const char *name); | ||||
static void pci_lintr_route(struct pci_devinst *pi); | static void pci_lintr_route(struct pci_devinst *pi); | ||||
static void pci_lintr_update(struct pci_devinst *pi); | static void pci_lintr_update(struct pci_devinst *pi); | ||||
static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, | static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, | ||||
int func, int coff, int bytes, uint32_t *val); | int func, int coff, int bytes, uint32_t *val); | ||||
static __inline void | static __inline void | ||||
▲ Show 20 Lines • Show All 1,016 Lines • ▼ Show 20 Lines | init_pci(struct vmctx *ctx) | ||||
struct mem_range mr; | struct mem_range mr; | ||||
struct pci_devemu *pde; | struct pci_devemu *pde; | ||||
struct businfo *bi; | struct businfo *bi; | ||||
struct slotinfo *si; | struct slotinfo *si; | ||||
struct funcinfo *fi; | struct funcinfo *fi; | ||||
nvlist_t *nvl; | nvlist_t *nvl; | ||||
const char *emul; | const char *emul; | ||||
size_t lowmem; | size_t lowmem; | ||||
uint64_t cpu_maxphysaddr, pci_emul_memresv64; | int bus, slot, func; | ||||
u_int regs[4]; | int error; | ||||
int bus, slot, func, error; | |||||
pci_emul_iobase = PCI_EMUL_IOBASE; | pci_emul_iobase = PCI_EMUL_IOBASE; | ||||
pci_emul_membase32 = vm_get_lowmem_limit(ctx); | pci_emul_membase32 = vm_get_lowmem_limit(ctx); | ||||
do_cpuid(0x80000008, regs); | pci_emul_membase64 = 4*GB + vm_get_highmem_size(ctx); | ||||
cpu_maxphysaddr = 1ULL << (regs[0] & 0xff); | pci_emul_membase64 = roundup2(pci_emul_membase64, PCI_EMUL_MEMSIZE64); | ||||
if (cpu_maxphysaddr > VM_MAXUSER_ADDRESS_LA48) | pci_emul_memlim64 = pci_emul_membase64 + PCI_EMUL_MEMSIZE64; | ||||
cpu_maxphysaddr = VM_MAXUSER_ADDRESS_LA48; | |||||
pci_emul_memresv64 = cpu_maxphysaddr / 4; | |||||
/* | |||||
* Max power of 2 that is less then | |||||
* cpu_maxphysaddr - pci_emul_memresv64. | |||||
*/ | |||||
pci_emul_membase64 = 1ULL << (flsl(cpu_maxphysaddr - | |||||
pci_emul_memresv64) - 1); | |||||
pci_emul_memlim64 = cpu_maxphysaddr; | |||||
for (bus = 0; bus < MAXBUSES; bus++) { | for (bus = 0; bus < MAXBUSES; bus++) { | ||||
snprintf(node_name, sizeof(node_name), "pci.%d", bus); | snprintf(node_name, sizeof(node_name), "pci.%d", bus); | ||||
nvl = find_config_node(node_name); | nvl = find_config_node(node_name); | ||||
if (nvl == NULL) | if (nvl == NULL) | ||||
continue; | continue; | ||||
pci_businfo[bus] = calloc(1, sizeof(struct businfo)); | pci_businfo[bus] = calloc(1, sizeof(struct businfo)); | ||||
bi = pci_businfo[bus]; | bi = pci_businfo[bus]; | ||||
▲ Show 20 Lines • Show All 1,253 Lines • Show Last 20 Lines |