Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_emul.c
| Show First 20 Lines • Show All 511 Lines • ▼ Show 20 Lines | default: | |||||||||||||
| break; | break; | |||||||||||||
| } | } | |||||||||||||
| assert(error == 0); | assert(error == 0); | |||||||||||||
| } | } | |||||||||||||
| static void | static void | |||||||||||||
| unregister_bar(struct pci_devinst *pi, int idx) | unregister_bar(struct pci_devinst *pi, int idx) | |||||||||||||
| { | { | |||||||||||||
| if (!is_gvt_d(pi)) | ||||||||||||||
| modify_bar_registration(pi, idx, 0); | modify_bar_registration(pi, idx, 0); | |||||||||||||
| else | ||||||||||||||
| /* | ||||||||||||||
| * Current implementation of BAR accesses for passthru devices doesn't work with GVT-d | ||||||||||||||
| * Therefore, use an own implementation for BAR accesses | ||||||||||||||
| * | ||||||||||||||
| * If handling of BAR accesses changes for passthru devices, it may be possible remove this func | ||||||||||||||
| */ | ||||||||||||||
| unregister_bar_gvt_d(pi, idx); | ||||||||||||||
| } | } | |||||||||||||
| static void | static void | |||||||||||||
| register_bar(struct pci_devinst *pi, int idx) | register_bar(struct pci_devinst *pi, int idx) | |||||||||||||
| { | { | |||||||||||||
| if (!is_gvt_d(pi)) | ||||||||||||||
| modify_bar_registration(pi, idx, 1); | modify_bar_registration(pi, idx, 1); | |||||||||||||
| else | ||||||||||||||
| /* | ||||||||||||||
| * Current implementation of BAR accesses for passthru devices doesn't work with GVT-d | ||||||||||||||
| * Therefore, use an own implementation for BAR accesses | ||||||||||||||
| * | ||||||||||||||
| * If handling of BAR accesses changes for passthru devices, it may be possible remove this func | ||||||||||||||
| */ | ||||||||||||||
| register_bar_gvt_d(pi, idx); | ||||||||||||||
| } | } | |||||||||||||
| /* Are we decoding i/o port accesses for the emulated pci device? */ | /* Are we decoding i/o port accesses for the emulated pci device? */ | |||||||||||||
| static int | static int | |||||||||||||
| porten(struct pci_devinst *pi) | porten(struct pci_devinst *pi) | |||||||||||||
| { | { | |||||||||||||
| uint16_t cmd; | uint16_t cmd; | |||||||||||||
| ▲ Show 20 Lines • Show All 139 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) | ||||||||||||||
| { | ||||||||||||||
| int error; | ||||||||||||||
| error = 1; | ||||||||||||||
| uint64_t *baseptr, limit, base; | ||||||||||||||
| 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 | ||||||||||||||
| 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 | ||||||||||||||