Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_passthru.c
Show First 20 Lines • Show All 849 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
passthru_cfgread_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | passthru_cfgread_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
int coff, int bytes, uint32_t *rv); | int coff, int bytes, uint32_t *rv); | ||||
static int | static int | ||||
passthru_cfgwrite_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | passthru_cfgwrite_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
int coff, int bytes, uint32_t val); | int coff, int bytes, uint32_t val); | ||||
static int | static int | ||||
passthru_init_apu(struct vmctx *ctx, struct passthru_softc *sc); | |||||
static int | |||||
passthru_cfgread_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | |||||
int coff, int bytes, uint32_t *rv); | |||||
static int | |||||
passthru_cfgwrite_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | |||||
int coff, int bytes, uint32_t val); | |||||
static int | |||||
passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) | ||||
{ | { | ||||
char *opt; | char *opt; | ||||
int bus, slot, func, error, memflags; | int bus, slot, func, error, memflags; | ||||
struct passthru_softc *sc; | struct passthru_softc *sc; | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
cap_rights_t rights; | cap_rights_t rights; | ||||
cap_ioctl_t pci_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR }; | cap_ioctl_t pci_ioctls[] = { PCIOCREAD, PCIOCWRITE, PCIOCGETBAR }; | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | #endif | ||||
// init igd (integrated graphics device) | // init igd (integrated graphics device) | ||||
if (opt != NULL && strcmp(opt, "igd") == 0) { | if (opt != NULL && strcmp(opt, "igd") == 0) { | ||||
if ((error = passthru_init_igd(ctx, sc)) != 0) { | if ((error = passthru_init_igd(ctx, sc)) != 0) { | ||||
warnx("Failed to init igd"); | warnx("Failed to init igd"); | ||||
goto done; | goto done; | ||||
} | } | ||||
} | } | ||||
// init amd apu | |||||
if (opt != NULL && strcmp(opt, "apu") == 0) { | |||||
if ((error = passthru_init_apu(ctx, sc)) != 0) { | |||||
warnx("Failed to init apu"); | |||||
goto done; | |||||
} | |||||
} | |||||
error = 0; /* success */ | error = 0; /* success */ | ||||
done: | done: | ||||
if (error) { | if (error) { | ||||
free(sc); | free(sc); | ||||
vm_unassign_pptdev(ctx, bus, slot, func); | vm_unassign_pptdev(ctx, bus, slot, func); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 351 Lines • ▼ Show 20 Lines | done: | ||||
if (error) { | if (error) { | ||||
vm_unmap_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, opregion_gpa, opregion_size); | vm_unmap_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, opregion_gpa, opregion_size); | ||||
vm_unmap_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, gsm_gpa, gsm_size); | vm_unmap_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, gsm_gpa, gsm_size); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
passthru_init_apu(struct vmctx *ctx, struct passthru_softc *sc) | |||||
{ | |||||
int error; | |||||
uint16_t vendor = read_config(&sc->psc_sel, PCIR_VENDOR, 2); | |||||
uint16_t dev_id = read_config(&sc->psc_sel, PCIR_DEVICE, 2); | |||||
if ((error = vm_get_vbios(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, vendor, dev_id, &sc->psc_pi->vbios.hpa, &sc->psc_pi->vbios.len)) != 0) { | |||||
warnx("Failed to load vBIOS (%d)", error); | |||||
goto done; | |||||
} | |||||
if ((sc->psc_pi->vbios.gpa = pci_emul_alloc_mmio(PCIBAR_MEM32, roundup2(sc->psc_pi->vbios.len, PAGE_SIZE), 0x7FF)) == 0) { | |||||
warnx("Failed to alloc guest memory for vBIOS"); | |||||
error = -ENOMEM; | |||||
goto done; | |||||
} | |||||
if ((error = vm_map_pptdev_mmio(ctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, sc->psc_pi->vbios.gpa, roundup2(sc->psc_pi->vbios.len, PAGE_SIZE), sc->psc_pi->vbios.hpa)) != 0) { | |||||
warnx("Failed to map vBIOS to guest"); | |||||
goto done; | |||||
} | |||||
pci_set_cfgdata32(sc->psc_pi, PCIR_BIOS, sc->psc_pi->vbios.gpa | 0x01); | |||||
sc->psc_pi->pi_d->pe_cfgread = passthru_cfgread_apu; | |||||
sc->psc_pi->pi_d->pe_cfgwrite = passthru_cfgwrite_apu; | |||||
done: | |||||
return (error); | |||||
} | |||||
static int | |||||
bar_access(int coff) | bar_access(int coff) | ||||
{ | { | ||||
if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) | if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) | ||||
return (1); | return (1); | ||||
else | else | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | passthru_cfgread_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
*/ | */ | ||||
if ((coff >= PCIR_BDSM && coff < PCIR_BDSM + 4) || (coff >= PCIR_ASLS_CTL && coff < PCIR_ASLS_CTL + 4)) | if ((coff >= PCIR_BDSM && coff < PCIR_BDSM + 4) || (coff >= PCIR_ASLS_CTL && coff < PCIR_ASLS_CTL + 4)) | ||||
return (-1); | return (-1); | ||||
else | else | ||||
return passthru_cfgread(ctx, vcpu, pi, coff, bytes, rv); | return passthru_cfgread(ctx, vcpu, pi, coff, bytes, rv); | ||||
} | } | ||||
static int | static int | ||||
passthru_cfgread_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | |||||
int coff, int bytes, uint32_t *rv) | |||||
{ | |||||
if (coff >= PCIR_BIOS && coff < PCIR_BIOS + 4) | |||||
return (-1); | |||||
else | |||||
return passthru_cfgread(ctx, vcpu, pi, coff, bytes, rv); | |||||
} | |||||
static int | |||||
passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
int coff, int bytes, uint32_t val) | int coff, int bytes, uint32_t val) | ||||
{ | { | ||||
int error, msix_table_entries, i; | int error, msix_table_entries, i; | ||||
struct passthru_softc *sc; | struct passthru_softc *sc; | ||||
uint16_t cmd_old; | uint16_t cmd_old; | ||||
sc = pi->pi_arg; | sc = pi->pi_arg; | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | passthru_cfgwrite_igd_gen5_75(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | ||||
* | * | ||||
* BDSM: contains Base of Data Stolen Memory | * BDSM: contains Base of Data Stolen Memory | ||||
* ASLS_CTL: contains address of Opregion | * ASLS_CTL: contains address of Opregion | ||||
*/ | */ | ||||
if (coff == PCIR_BDSM || coff == PCIR_ASLS_CTL) | if (coff == PCIR_BDSM || coff == PCIR_ASLS_CTL) | ||||
return (0); | return (0); | ||||
else | else | ||||
return passthru_cfgwrite(ctx, vcpu, pi, coff, bytes, val); | return passthru_cfgwrite(ctx, vcpu, pi, coff, bytes, val); | ||||
} | |||||
static int | |||||
passthru_cfgwrite_apu(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, | |||||
int coff, int bytes, uint32_t val) | |||||
{ | |||||
if (coff == PCIR_BIOS) { | |||||
struct passthru_softc *sc; | |||||
sc = pi->pi_arg; | |||||
if ((val & ~0x7FF) == 0xFFFFF800) { | |||||
uint32_t lobits = pci_get_cfgdata32(pi, PCIR_BIOS) & 0x7FF; | |||||
uint32_t hibits = ~(roundup2(pi->vbios.len, PAGE_SIZE) - 1); | |||||
pci_set_cfgdata32(pi, PCIR_BIOS, hibits | lobits); | |||||
vm_unmap_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, pi->vbios.gpa, roundup2(pi->vbios.len, PAGE_SIZE)); | |||||
pi->vbios.gpa = 0; | |||||
} | |||||
else { | |||||
pci_set_cfgdata32(pi, PCIR_BIOS, val); | |||||
val &= ~0x7FF; | |||||
if (vm_map_pptdev_mmio(pi->pi_vmctx, sc->psc_sel.pc_bus, sc->psc_sel.pc_dev, sc->psc_sel.pc_func, val, roundup2(pi->vbios.len, PAGE_SIZE), pi->vbios.hpa)) | |||||
goto done; | |||||
pi->vbios.gpa = val; | |||||
} | |||||
} | |||||
else | |||||
return passthru_cfgwrite(ctx, vcpu, pi, coff, bytes, val); | |||||
done: | |||||
return (0); | |||||
} | } | ||||
static void | static void | ||||
passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, | passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, | ||||
uint64_t offset, int size, uint64_t value) | uint64_t offset, int size, uint64_t value) | ||||
{ | { | ||||
struct passthru_softc *sc; | struct passthru_softc *sc; | ||||
struct iodev_pio_req pio; | struct iodev_pio_req pio; | ||||
▲ Show 20 Lines • Show All 54 Lines • Show Last 20 Lines |