bhyve: move 64 bit BAR location to match OVMF assumptions

OVMF will fail, if large 64 bit BARs are used. GCD-Map doesn't cover
64 bit addresses of BARs.
OVMF assumes that 64 bit addresses of BARS are located on next 32 GB
boundary behind Top of High RAM.

This patch moves 64 bit BARs on next 32 GB boundary behind Top of High
RAM to match OVMF assumptions.

Differential Revision:	https://reviews.freebsd.org/D27970
Sponsored by: Beckhoff Automation GmbH & Co. KG
This commit is contained in:
Corvin Köhne 2021-11-22 16:22:48 +01:00 committed by Emmanuel Vadot
parent 28ba36c65d
commit 4a4053e1b0

View File

@ -33,9 +33,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/linker_set.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <ctype.h>
#include <errno.h>
@ -49,8 +46,6 @@ __FBSDID("$FreeBSD$");
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
#include <vmmapi.h>
#include "acpi.h"
@ -73,6 +68,8 @@ __FBSDID("$FreeBSD$");
#define MAXSLOTS (PCI_SLOTMAX + 1)
#define MAXFUNCS (PCI_FUNCMAX + 1)
#define GB (1024 * 1024 * 1024UL)
struct funcinfo {
nvlist_t *fi_config;
struct pci_devemu *fi_pde;
@ -114,6 +111,7 @@ static uint64_t pci_emul_memlim64;
SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE);
#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 void pci_lintr_route(struct pci_devinst *pi);
@ -1155,25 +1153,15 @@ init_pci(struct vmctx *ctx)
nvlist_t *nvl;
const char *emul;
size_t lowmem;
uint64_t cpu_maxphysaddr, pci_emul_memresv64;
u_int regs[4];
int bus, slot, func, error;
int bus, slot, func;
int error;
pci_emul_iobase = PCI_EMUL_IOBASE;
pci_emul_membase32 = vm_get_lowmem_limit(ctx);
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;
pci_emul_membase64 = 4*GB + vm_get_highmem_size(ctx);
pci_emul_membase64 = roundup2(pci_emul_membase64, PCI_EMUL_MEMSIZE64);
pci_emul_memlim64 = pci_emul_membase64 + PCI_EMUL_MEMSIZE64;
for (bus = 0; bus < MAXBUSES; bus++) {
snprintf(node_name, sizeof(node_name), "pci.%d", bus);