Advertise PCI-E capability in the hostbridge device presented to the guest.
FreeBSD wants to see this capability in at least one device in the PCI hierarchy before it allows use of MSI or MSI-X. Obtained from: NetApp
This commit is contained in:
parent
a1137de941
commit
74f80b236d
@ -740,6 +740,38 @@ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
|
||||
CFGWRITE(pi, offset, val, bytes);
|
||||
}
|
||||
|
||||
void
|
||||
pciecap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
|
||||
int bytes, uint32_t val)
|
||||
{
|
||||
|
||||
/* XXX don't write to the readonly parts */
|
||||
CFGWRITE(pi, offset, val, bytes);
|
||||
}
|
||||
|
||||
#define PCIECAP_VERSION 0x2
|
||||
int
|
||||
pci_emul_add_pciecap(struct pci_devinst *pi, int type)
|
||||
{
|
||||
int err;
|
||||
struct pciecap pciecap;
|
||||
|
||||
CTASSERT(sizeof(struct pciecap) == 60);
|
||||
|
||||
if (type != PCIEM_TYPE_ROOT_PORT)
|
||||
return (-1);
|
||||
|
||||
bzero(&pciecap, sizeof(pciecap));
|
||||
|
||||
pciecap.capid = PCIY_EXPRESS;
|
||||
pciecap.pcie_capabilities = PCIECAP_VERSION | PCIEM_TYPE_ROOT_PORT;
|
||||
pciecap.link_capabilities = 0x411; /* gen1, x1 */
|
||||
pciecap.link_status = 0x11; /* gen1, x1 */
|
||||
|
||||
err = pci_emul_add_capability(pi, (u_char *)&pciecap, sizeof(pciecap));
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function assumes that 'coff' is in the capabilities region of the
|
||||
* config space.
|
||||
@ -782,6 +814,9 @@ pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val)
|
||||
case PCIY_MSIX:
|
||||
msixcap_cfgwrite(pi, capoff, offset, bytes, val);
|
||||
break;
|
||||
case PCIY_EXPRESS:
|
||||
pciecap_cfgwrite(pi, capoff, offset, bytes, val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -150,6 +150,40 @@ struct msixcap {
|
||||
uint32_t pba_info; /* bar index and offset within it */
|
||||
} __packed;
|
||||
|
||||
struct pciecap {
|
||||
uint8_t capid;
|
||||
uint8_t nextptr;
|
||||
uint16_t pcie_capabilities;
|
||||
|
||||
uint32_t dev_capabilities; /* all devices */
|
||||
uint16_t dev_control;
|
||||
uint16_t dev_status;
|
||||
|
||||
uint32_t link_capabilities; /* devices with links */
|
||||
uint16_t link_control;
|
||||
uint16_t link_status;
|
||||
|
||||
uint32_t slot_capabilities; /* ports with slots */
|
||||
uint16_t slot_control;
|
||||
uint16_t slot_status;
|
||||
|
||||
uint16_t root_control; /* root ports */
|
||||
uint16_t root_capabilities;
|
||||
uint32_t root_status;
|
||||
|
||||
uint32_t dev_capabilities2; /* all devices */
|
||||
uint16_t dev_control2;
|
||||
uint16_t dev_status2;
|
||||
|
||||
uint32_t link_capabilities2; /* devices with links */
|
||||
uint16_t link_control2;
|
||||
uint16_t link_status2;
|
||||
|
||||
uint32_t slot_capabilities2; /* ports with slots */
|
||||
uint16_t slot_control2;
|
||||
uint16_t slot_status2;
|
||||
} __packed;
|
||||
|
||||
void init_pci(struct vmctx *ctx);
|
||||
void msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
|
||||
int bytes, uint32_t val);
|
||||
@ -161,6 +195,7 @@ int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx,
|
||||
int pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx,
|
||||
uint64_t hostbase, enum pcibar_type type, uint64_t size);
|
||||
int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum);
|
||||
int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type);
|
||||
int pci_is_legacy(struct pci_devinst *pi);
|
||||
void pci_generate_msi(struct pci_devinst *pi, int msgnum);
|
||||
void pci_generate_msix(struct pci_devinst *pi, int msgnum);
|
||||
|
@ -42,6 +42,8 @@ pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
|
||||
pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE);
|
||||
pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST);
|
||||
|
||||
pci_emul_add_pciecap(pi, PCIEM_TYPE_ROOT_PORT);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user