svn commit: r353705 - stable/12/usr.sbin/bhyve
John Baldwin
jhb at FreeBSD.org
Thu Oct 17 23:26:39 UTC 2019
Author: jhb
Date: Thu Oct 17 23:26:39 2019
New Revision: 353705
URL: https://svnweb.freebsd.org/changeset/base/353705
Log:
MFC 348778,348998: Enable memory and I/O decoding in PCI devices on demand.
348778:
Enable memory and I/O decoding in PCI devices on demand.
Rather than uncoditionally setting the MEMEN and PORTEN bits in
PCIR_COMMAND for PCI devices, set the respective bit when the first
BAR of a given type is added to the device. This more closely matches
what firmware does on bare metal.
BUSMASTEREN is still set unconditionally. Eventually this bit should
move into the device models as not all device models need this set.
348998:
Remove a spurious break when setting up a 64-bit memory BAR.
This was causing 'enbit' to not be initialized in this case.
Modified:
stable/12/usr.sbin/bhyve/pci_emul.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- stable/12/usr.sbin/bhyve/pci_emul.c Thu Oct 17 23:22:00 2019 (r353704)
+++ stable/12/usr.sbin/bhyve/pci_emul.c Thu Oct 17 23:26:39 2019 (r353705)
@@ -586,6 +586,7 @@ pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx,
{
int error;
uint64_t *baseptr, limit, addr, mask, lobits, bar;
+ uint16_t cmd, enbit;
assert(idx >= 0 && idx <= PCI_BARMAX);
@@ -604,13 +605,14 @@ pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx,
switch (type) {
case PCIBAR_NONE:
baseptr = NULL;
- addr = mask = lobits = 0;
+ addr = mask = lobits = enbit = 0;
break;
case PCIBAR_IO:
baseptr = &pci_emul_iobase;
limit = PCI_EMUL_IOLIMIT;
mask = PCIM_BAR_IO_BASE;
lobits = PCIM_BAR_IO_SPACE;
+ enbit = PCIM_CMD_PORTEN;
break;
case PCIBAR_MEM64:
/*
@@ -632,19 +634,20 @@ pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx,
mask = PCIM_BAR_MEM_BASE;
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 |
PCIM_BAR_MEM_PREFETCH;
- break;
} else {
baseptr = &pci_emul_membase32;
limit = PCI_EMUL_MEMLIMIT32;
mask = PCIM_BAR_MEM_BASE;
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64;
}
+ enbit = PCIM_CMD_MEMEN;
break;
case PCIBAR_MEM32:
baseptr = &pci_emul_membase32;
limit = PCI_EMUL_MEMLIMIT32;
mask = PCIM_BAR_MEM_BASE;
lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32;
+ enbit = PCIM_CMD_MEMEN;
break;
default:
printf("pci_emul_alloc_base: invalid bar type %d\n", type);
@@ -671,6 +674,9 @@ pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx,
pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32);
}
+ cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND);
+ if ((cmd & enbit) != enbit)
+ pci_set_cfgdata16(pdi, PCIR_COMMAND, cmd | enbit);
register_bar(pdi, idx);
return (0);
@@ -756,8 +762,7 @@ pci_emul_init(struct vmctx *ctx, struct pci_devemu *pd
pci_set_cfgdata8(pdi, PCIR_INTLINE, 255);
pci_set_cfgdata8(pdi, PCIR_INTPIN, 0);
- pci_set_cfgdata8(pdi, PCIR_COMMAND,
- PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
+ pci_set_cfgdata8(pdi, PCIR_COMMAND, PCIM_CMD_BUSMASTEREN);
err = (*pde->pe_init)(ctx, pdi, fi->fi_param);
if (err == 0)
More information about the svn-src-all
mailing list