Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/pci_emul.c
Show First 20 Lines • Show All 721 Lines • ▼ Show 20 Lines | pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, | ||||
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); | ||||
} | } | ||||
#define CAP_START_OFFSET 0x40 | #define CAP_START_OFFSET 0x40 | ||||
static int | 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 *capoffp) | |||||
{ | { | ||||
int i, capoff, reallen; | int i, capoff, reallen; | ||||
uint16_t sts; | uint16_t sts; | ||||
assert(caplen > 0); | assert(caplen > 0); | ||||
reallen = roundup2(caplen, 4); /* dword aligned */ | reallen = roundup2(caplen, 4); /* dword aligned */ | ||||
Show All 18 Lines | pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen, | ||||
for (i = 0; i < caplen; i++) | for (i = 0; i < caplen; i++) | ||||
pci_set_cfgdata8(pi, capoff + i, capdata[i]); | pci_set_cfgdata8(pi, capoff + i, capdata[i]); | ||||
/* Set the next capability pointer */ | /* Set the next capability pointer */ | ||||
pci_set_cfgdata8(pi, capoff + 1, 0); | pci_set_cfgdata8(pi, capoff + 1, 0); | ||||
pi->pi_prevcap = capoff; | pi->pi_prevcap = capoff; | ||||
pi->pi_capend = capoff + reallen - 1; | pi->pi_capend = capoff + reallen - 1; | ||||
if (capoffp != NULL) | |||||
*capoffp = capoff; | |||||
return (0); | return (0); | ||||
} | } | ||||
static struct pci_devemu * | static struct pci_devemu * | ||||
pci_emul_finddev(const char *name) | pci_emul_finddev(const char *name) | ||||
{ | { | ||||
struct pci_devemu **pdpp, *pdp; | struct pci_devemu **pdpp, *pdp; | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
pci_emul_add_msicap(struct pci_devinst *pi, int msgnum) | pci_emul_add_msicap(struct pci_devinst *pi, int msgnum) | ||||
{ | { | ||||
struct msicap msicap; | struct msicap msicap; | ||||
pci_populate_msicap(&msicap, msgnum, 0); | pci_populate_msicap(&msicap, msgnum, 0); | ||||
return (pci_emul_add_capability(pi, (u_char *)&msicap, sizeof(msicap))); | return (pci_emul_add_capability(pi, (u_char *)&msicap, sizeof(msicap), | ||||
NULL)); | |||||
} | } | ||||
static void | static void | ||||
pci_populate_msixcap(struct msixcap *msixcap, int msgnum, int barnum, | pci_populate_msixcap(struct msixcap *msixcap, int msgnum, int barnum, | ||||
uint32_t msix_tab_size) | uint32_t msix_tab_size) | ||||
{ | { | ||||
assert(msix_tab_size % 4096 == 0); | assert(msix_tab_size % 4096 == 0); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum) | ||||
pci_populate_msixcap(&msixcap, msgnum, barnum, tab_size); | pci_populate_msixcap(&msixcap, msgnum, barnum, tab_size); | ||||
/* allocate memory for MSI-X Table and PBA */ | /* allocate memory for MSI-X Table and PBA */ | ||||
pci_emul_alloc_bar(pi, barnum, PCIBAR_MEM32, | pci_emul_alloc_bar(pi, barnum, PCIBAR_MEM32, | ||||
tab_size + pi->pi_msix.pba_size); | tab_size + pi->pi_msix.pba_size); | ||||
return (pci_emul_add_capability(pi, (u_char *)&msixcap, | return (pci_emul_add_capability(pi, (u_char *)&msixcap, | ||||
sizeof(msixcap))); | sizeof(msixcap), NULL)); | ||||
} | } | ||||
static void | static void | ||||
msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, | msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, | ||||
int bytes, uint32_t val) | int bytes, uint32_t val) | ||||
{ | { | ||||
uint16_t msgctrl, rwmask; | uint16_t msgctrl, rwmask; | ||||
int off; | int off; | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | pci_emul_add_pciecap(struct pci_devinst *pi, int type) | ||||
pciecap.capid = PCIY_EXPRESS; | pciecap.capid = PCIY_EXPRESS; | ||||
pciecap.pcie_capabilities = PCIECAP_VERSION | type; | pciecap.pcie_capabilities = PCIECAP_VERSION | type; | ||||
if (type != PCIEM_TYPE_ROOT_INT_EP) { | if (type != PCIEM_TYPE_ROOT_INT_EP) { | ||||
pciecap.link_capabilities = 0x411; /* gen1, x1 */ | pciecap.link_capabilities = 0x411; /* gen1, x1 */ | ||||
pciecap.link_status = 0x11; /* gen1, x1 */ | pciecap.link_status = 0x11; /* gen1, x1 */ | ||||
} | } | ||||
err = pci_emul_add_capability(pi, (u_char *)&pciecap, sizeof(pciecap)); | err = pci_emul_add_capability(pi, (u_char *)&pciecap, sizeof(pciecap), | ||||
NULL); | |||||
return (err); | return (err); | ||||
} | } | ||||
/* | /* | ||||
* This function assumes that 'coff' is in the capabilities region of the | * This function assumes that 'coff' is in the capabilities region of the | ||||
* config space. A capoff parameter of zero will force a search for the | * config space. A capoff parameter of zero will force a search for the | ||||
* offset and type. | * offset and type. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 1,403 Lines • Show Last 20 Lines |