Skip to content

Commit ac14779

Browse files
yliu80wenlingz
authored andcommitted
hv: implement SRIOV-Capable device detection.
if the device has PCIe capability, walks all PCIe extended capabilities for SRIOV discovery. v2: avoid type casting and refine naming. Tracked-On: #4433 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent c751a8e commit ac14779

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

hypervisor/hw/pci.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,31 @@ static inline uint32_t pci_pdev_get_nr_bars(uint8_t hdr_type)
477477
return nr_bars;
478478
}
479479

480+
/**
481+
* @pre pdev != NULL
482+
*/
483+
static void pci_read_ext_cap(struct pci_pdev *pdev) {
484+
485+
uint32_t hdr, pos;
486+
487+
pos = PCI_ECAP_BASE_PTR;
488+
489+
/* PCI Express Extended Capability must have 4 bytes header */
490+
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
491+
while (hdr != 0U) {
492+
if (PCI_ECAP_ID(hdr) == PCIZ_SRIOV) {
493+
pdev->sriov.capoff = pos;
494+
pdev->sriov.caplen = PCI_SRIOV_CAP_LEN;
495+
}
496+
pos = PCI_ECAP_NEXT(hdr);
497+
if (pos == 0U) {
498+
break;
499+
}
500+
501+
hdr = pci_pdev_read_cfg(pdev->bdf, pos, 4U);
502+
};
503+
}
504+
480505
/*
481506
* @pre pdev != NULL
482507
*/
@@ -487,6 +512,7 @@ static void pci_read_cap(struct pci_pdev *pdev)
487512
uint32_t len, idx;
488513
uint32_t table_info;
489514
uint32_t pcie_devcap, val;
515+
bool is_pcie = false;
490516

491517
pos = (uint8_t)pci_pdev_read_cfg(pdev->bdf, PCIR_CAP_PTR, 1U);
492518

@@ -520,6 +546,7 @@ static void pci_read_cap(struct pci_pdev *pdev)
520546
val = pci_pdev_read_cfg(pdev->bdf, pos + PCIR_PMCSR, 4U);
521547
pdev->has_pm_reset = ((val & PCIM_PMCSR_NO_SOFT_RST) == 0U);
522548
} else if (cap == PCIY_PCIE) {
549+
is_pcie = true;
523550
pcie_devcap = pci_pdev_read_cfg(pdev->bdf, pos + PCIR_PCIE_DEVCAP, 4U);
524551
pdev->has_flr = ((pcie_devcap & PCIM_PCIE_FLRCAP) != 0U);
525552
} else if (cap == PCIY_AF) {
@@ -531,6 +558,10 @@ static void pci_read_cap(struct pci_pdev *pdev)
531558

532559
pos = (uint8_t)pci_pdev_read_cfg(pdev->bdf, pos + PCICAP_NEXTPTR, 1U);
533560
}
561+
562+
if (is_pcie) {
563+
pci_read_ext_cap(pdev);
564+
}
534565
}
535566

536567
static void init_pdev(uint16_t pbdf, uint32_t drhd_index)

hypervisor/include/hw/pci.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@
106106
#define PCIY_MSI 0x05U
107107
#define PCIY_MSIX 0x11U
108108

109+
/* PCIe Extended Capability*/
110+
#define PCI_ECAP_BASE_PTR 0x100U
111+
#define PCI_ECAP_ID(hdr) ((uint32_t)((hdr) & 0xFFFFU))
112+
#define PCI_ECAP_NEXT(hdr) ((uint32_t)(((hdr) >> 20U) & 0xFFCU))
113+
#define PCIZ_SRIOV 0x10U
114+
115+
/* SRIOV Definitions */
116+
#define PCI_SRIOV_CAP_LEN 0x40U
117+
109118
/* PCI Message Signalled Interrupts (MSI) */
110119
#define PCIR_MSI_CTRL 0x02U
111120
#define PCIM_MSICTRL_64BIT 0x80U
@@ -192,6 +201,11 @@ struct pci_msix_cap {
192201
uint8_t cap[MSIX_CAPLEN];
193202
};
194203

204+
struct pci_sriov_cap {
205+
uint32_t capoff;
206+
uint32_t caplen;
207+
};
208+
195209
struct pci_pdev {
196210
uint8_t hdr_type;
197211

@@ -208,6 +222,7 @@ struct pci_pdev {
208222
uint32_t msi_capoff;
209223

210224
struct pci_msix_cap msix;
225+
struct pci_sriov_cap sriov;
211226

212227
bool has_pm_reset;
213228
bool has_flr;

0 commit comments

Comments
 (0)