Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_emul.c
Show First 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | case PCIBAR_IO: | |||||||||||||
} else | } else | |||||||||||||
error = unregister_inout(&iop); | error = unregister_inout(&iop); | |||||||||||||
if (pe->pe_baraddr != NULL) | if (pe->pe_baraddr != NULL) | |||||||||||||
(*pe->pe_baraddr)(pi->pi_vmctx, pi, idx, registration, | (*pe->pe_baraddr)(pi->pi_vmctx, pi, idx, registration, | |||||||||||||
pi->pi_bar[idx].addr); | pi->pi_bar[idx].addr); | |||||||||||||
break; | break; | |||||||||||||
case PCIBAR_MEM32: | case PCIBAR_MEM32: | |||||||||||||
case PCIBAR_MEM64: | case PCIBAR_MEM64: | |||||||||||||
if (is_gvt_d(pi)) { | ||||||||||||||
error = passthru_modify_bar_registration(pi, idx, registration); | ||||||||||||||
break; | ||||||||||||||
} | ||||||||||||||
bzero(&mr, sizeof(struct mem_range)); | bzero(&mr, sizeof(struct mem_range)); | |||||||||||||
mr.name = pi->pi_name; | mr.name = pi->pi_name; | |||||||||||||
mr.base = pi->pi_bar[idx].addr; | mr.base = pi->pi_bar[idx].addr; | |||||||||||||
mr.size = pi->pi_bar[idx].size; | mr.size = pi->pi_bar[idx].size; | |||||||||||||
if (registration) { | if (registration) { | |||||||||||||
mr.flags = MEM_F_RW; | mr.flags = MEM_F_RW; | |||||||||||||
mr.handler = pci_emul_mem_handler; | mr.handler = pci_emul_mem_handler; | |||||||||||||
mr.arg1 = pi; | mr.arg1 = pi; | |||||||||||||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Lines | pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx, uint64_t hostbase, | |||||||||||||
/* Initialize the BAR register in config space */ | /* Initialize the BAR register in config space */ | |||||||||||||
bar = (addr & mask) | lobits; | bar = (addr & mask) | lobits; | |||||||||||||
pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar); | pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar); | |||||||||||||
if (type == PCIBAR_MEM64) { | if (type == PCIBAR_MEM64) { | |||||||||||||
assert(idx + 1 <= PCI_BARMAX); | assert(idx + 1 <= PCI_BARMAX); | |||||||||||||
pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; | pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; | |||||||||||||
pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); | pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); | |||||||||||||
khngUnsubmitted Done Inline Actions
khng: | ||||||||||||||
} | } | |||||||||||||
cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND); | cmd = pci_get_cfgdata16(pdi, PCIR_COMMAND); | |||||||||||||
if ((cmd & enbit) != enbit) | if ((cmd & enbit) != enbit) | |||||||||||||
pci_set_cfgdata16(pdi, PCIR_COMMAND, cmd | enbit); | pci_set_cfgdata16(pdi, PCIR_COMMAND, cmd | enbit); | |||||||||||||
register_bar(pdi, idx); | register_bar(pdi, idx); | |||||||||||||
return (0); | return (0); | |||||||||||||
} | ||||||||||||||
// mask should be a power of 2 minus 1 (e.g. 0x000FFFFF) | ||||||||||||||
uint64_t | ||||||||||||||
pci_emul_alloc_mmio(enum pcibar_type type, uint64_t size, uint64_t mask) | ||||||||||||||
{ | ||||||||||||||
uint64_t *baseptr, limit; | ||||||||||||||
switch (type) { | ||||||||||||||
case PCIBAR_IO: | ||||||||||||||
baseptr = &pci_emul_iobase; | ||||||||||||||
limit = PCI_EMUL_IOLIMIT; | ||||||||||||||
break; | ||||||||||||||
case PCIBAR_MEM32: | ||||||||||||||
baseptr = &pci_emul_membase32; | ||||||||||||||
limit = PCI_EMUL_MEMLIMIT32; | ||||||||||||||
break; | ||||||||||||||
case PCIBAR_MEM64: | ||||||||||||||
baseptr = &pci_emul_membase64; | ||||||||||||||
limit = PCI_EMUL_MEMLIMIT64; | ||||||||||||||
break; | ||||||||||||||
default: | ||||||||||||||
return 0; | ||||||||||||||
} | ||||||||||||||
// align base | ||||||||||||||
const uint64_t base = (*baseptr + mask) & ~mask; | ||||||||||||||
if (base + size > limit) | ||||||||||||||
return 0; | ||||||||||||||
*baseptr = base + size; | ||||||||||||||
return base; | ||||||||||||||
} | } | |||||||||||||
#define CAP_START_OFFSET 0x40 | #define CAP_START_OFFSET 0x40 | |||||||||||||
static int | static int | |||||||||||||
pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen) | pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen) | |||||||||||||
{ | { | |||||||||||||
int i, capoff, reallen; | int i, capoff, reallen; | |||||||||||||
uint16_t sts; | uint16_t sts; | |||||||||||||
▲ Show 20 Lines • Show All 1,651 Lines • Show Last 20 Lines |