Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_emul.c
Show First 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | CFGREAD(struct pci_devinst *pi, int coff, int bytes) | ||||
if (bytes == 1) | if (bytes == 1) | ||||
return (pci_get_cfgdata8(pi, coff)); | return (pci_get_cfgdata8(pi, coff)); | ||||
else if (bytes == 2) | else if (bytes == 2) | ||||
return (pci_get_cfgdata16(pi, coff)); | return (pci_get_cfgdata16(pi, coff)); | ||||
else | else | ||||
return (pci_get_cfgdata32(pi, coff)); | return (pci_get_cfgdata32(pi, coff)); | ||||
} | } | ||||
static int | |||||
is_pcir_bar(int coff) | |||||
{ | |||||
return (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)); | |||||
} | |||||
static int | |||||
is_pcir_bios(int coff) | |||||
{ | |||||
return (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4); | |||||
} | |||||
/* | /* | ||||
* I/O access | * I/O access | ||||
*/ | */ | ||||
/* | /* | ||||
* Slot options are in the form: | * Slot options are in the form: | ||||
* | * | ||||
* <bus>:<slot>:<func>,<emul>[,<config>] | * <bus>:<slot>:<func>,<emul>[,<config>] | ||||
▲ Show 20 Lines • Show All 1,925 Lines • ▼ Show 20 Lines | if (in) { | ||||
/* Let the device emulation override the default handler */ | /* Let the device emulation override the default handler */ | ||||
if (pe->pe_cfgwrite != NULL && | if (pe->pe_cfgwrite != NULL && | ||||
(*pe->pe_cfgwrite)(ctx, vcpu, pi, coff, bytes, *eax) == 0) | (*pe->pe_cfgwrite)(ctx, vcpu, pi, coff, bytes, *eax) == 0) | ||||
return; | return; | ||||
/* | /* | ||||
* Special handling for write to BAR and ROM registers | * Special handling for write to BAR and ROM registers | ||||
*/ | */ | ||||
if ((coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) || | if (is_pcir_bar(coff) || is_pcir_bios(coff)) { | ||||
(coff >= PCIR_BIOS && coff < PCIR_BIOS + 4)) { | |||||
/* | /* | ||||
* Ignore writes to BAR registers that are not | * Ignore writes to BAR registers that are not | ||||
* 4-byte aligned. | * 4-byte aligned. | ||||
*/ | */ | ||||
if (bytes != 4 || (coff & 0x3) != 0) | if (bytes != 4 || (coff & 0x3) != 0) | ||||
return; | return; | ||||
if (coff != PCIR_BIOS) { | |||||
if (is_pcir_bar(coff)) { | |||||
idx = (coff - PCIR_BAR(0)) / 4; | idx = (coff - PCIR_BAR(0)) / 4; | ||||
} else { | } else if (is_pcir_bios(coff)) { | ||||
idx = PCI_ROM_IDX; | idx = PCI_ROM_IDX; | ||||
} else { | |||||
errx(4, "%s: invalid BAR offset %d", __func__, | |||||
coff); | |||||
} | } | ||||
mask = ~(pi->pi_bar[idx].size - 1); | mask = ~(pi->pi_bar[idx].size - 1); | ||||
switch (pi->pi_bar[idx].type) { | switch (pi->pi_bar[idx].type) { | ||||
case PCIBAR_NONE: | case PCIBAR_NONE: | ||||
pi->pi_bar[idx].addr = bar = 0; | pi->pi_bar[idx].addr = bar = 0; | ||||
break; | break; | ||||
case PCIBAR_IO: | case PCIBAR_IO: | ||||
addr = *eax & mask; | addr = *eax & mask; | ||||
addr &= 0xffff; | addr &= 0xffff; | ||||
▲ Show 20 Lines • Show All 492 Lines • Show Last 20 Lines |