Changeset View
Changeset View
Standalone View
Standalone View
head/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 "debug.h" | #include "debug.h" | ||||
#include "inout.h" | #include "inout.h" | ||||
#include "ioapic.h" | #include "ioapic.h" | ||||
#include "mem.h" | #include "mem.h" | ||||
Show All 36 Lines | |||||
static struct businfo *pci_businfo[MAXBUSES]; | static struct businfo *pci_businfo[MAXBUSES]; | ||||
SET_DECLARE(pci_devemu_set, struct pci_devemu); | SET_DECLARE(pci_devemu_set, struct pci_devemu); | ||||
static uint64_t pci_emul_iobase; | static uint64_t pci_emul_iobase; | ||||
static uint64_t pci_emul_membase32; | static uint64_t pci_emul_membase32; | ||||
static uint64_t pci_emul_membase64; | static uint64_t pci_emul_membase64; | ||||
static uint64_t pci_emul_memlim64; | |||||
#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_MEMBASE64 0xD000000000UL | |||||
#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL | |||||
static struct pci_devemu *pci_emul_finddev(char *name); | static struct pci_devemu *pci_emul_finddev(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 | ||||
CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) | CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) | ||||
▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | case PCIBAR_MEM64: | ||||
if (size > 32 * 1024 * 1024) { | if (size > 32 * 1024 * 1024) { | ||||
/* | /* | ||||
* XXX special case for device requiring peer-peer DMA | * XXX special case for device requiring peer-peer DMA | ||||
*/ | */ | ||||
if (size == 0x100000000UL) | if (size == 0x100000000UL) | ||||
baseptr = &hostbase; | baseptr = &hostbase; | ||||
else | else | ||||
baseptr = &pci_emul_membase64; | baseptr = &pci_emul_membase64; | ||||
limit = PCI_EMUL_MEMLIMIT64; | limit = pci_emul_memlim64; | ||||
mask = PCIM_BAR_MEM_BASE; | mask = PCIM_BAR_MEM_BASE; | ||||
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | | lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | | ||||
PCIM_BAR_MEM_PREFETCH; | PCIM_BAR_MEM_PREFETCH; | ||||
} else { | } else { | ||||
baseptr = &pci_emul_membase32; | baseptr = &pci_emul_membase32; | ||||
limit = PCI_EMUL_MEMLIMIT32; | limit = PCI_EMUL_MEMLIMIT32; | ||||
mask = PCIM_BAR_MEM_BASE; | mask = PCIM_BAR_MEM_BASE; | ||||
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64; | lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64; | ||||
▲ Show 20 Lines • Show All 452 Lines • ▼ Show 20 Lines | |||||
init_pci(struct vmctx *ctx) | 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; | ||||
size_t lowmem; | size_t lowmem; | ||||
int bus, slot, func; | uint64_t cpu_maxphysaddr, pci_emul_memresv64; | ||||
int error; | u_int regs[4]; | ||||
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); | ||||
pci_emul_membase64 = PCI_EMUL_MEMBASE64; | |||||
do_cpuid(0x80000008, regs); | |||||
cpu_maxphysaddr = 1ULL << (regs[0] & 0xff); | |||||
if (cpu_maxphysaddr > VM_MAXUSER_ADDRESS_LA48) | |||||
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++) { | ||||
if ((bi = pci_businfo[bus]) == NULL) | if ((bi = pci_businfo[bus]) == NULL) | ||||
continue; | continue; | ||||
/* | /* | ||||
* Keep track of the i/o and memory resources allocated to | * Keep track of the i/o and memory resources allocated to | ||||
* this bus. | * this bus. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,226 Lines • Show Last 20 Lines |