1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <commonlib/bsd/helpers.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci_def.h>
7 #include <device/pciexp.h>
8 #include <device/resource.h>
13 void pciexp_vf_read_resources(struct device
*dev
)
15 uint32_t sriov_cap_offset
, supported_page_size
, system_page_size
;
16 uint16_t num_vfs
, index
;
18 struct resource
*resource
;
20 sriov_cap_offset
= pciexp_find_extended_cap(dev
, PCIE_EXT_CAP_SRIOV_ID
, 0);
21 if (sriov_cap_offset
== 0) {
22 printk(BIOS_DEBUG
, "No SRIOV capability for %s!\n", dev_path(dev
));
26 printk(BIOS_DEBUG
, "%s SRIOV capability found at offset 0x%x\n", dev_path(dev
),
29 supported_page_size
= pci_read_config32(
30 dev
, sriov_cap_offset
+ PCIE_EXT_CAP_SRIOV_SUPPORTED_PAGE_SIZE
);
31 if (supported_page_size
== 0) {
32 printk(BIOS_DEBUG
, "No supported page size for %s!\n", dev_path(dev
));
37 pci_read_config32(dev
, sriov_cap_offset
+ PCIE_EXT_CAP_SRIOV_SYSTEM_PAGE_SIZE
);
38 if ((system_page_size
& supported_page_size
) == 0) {
39 printk(BIOS_ERR
, "Unsupportted system page size 0x%08x for %s!\n",
40 system_page_size
, dev_path(dev
));
44 if (popcnt(system_page_size
) != 1) {
45 printk(BIOS_ERR
, "More than 1 bit is set in system page size for %s!\n",
50 num_vfs
= pci_read_config16(dev
, sriov_cap_offset
+ PCIE_EXT_CAP_SRIOV_TOTAL_VFS
);
53 * If bit `n` is set, the VFs are required to support a page size of 2 ^ (n + 12).
55 align
= __ffs(system_page_size
) + 12;
57 for (index
= PCIE_EXT_CAP_SRIOV_VF_BAR0
; index
<= PCIE_EXT_CAP_SRIOV_VF_BAR5
;
59 resource
= pci_get_resource(dev
, sriov_cap_offset
+ index
);
60 if (resource
->flags
== 0)
63 printk(BIOS_DEBUG
, "%s SRIOV BAR at offset 0x%x\n", dev_path(dev
),
64 sriov_cap_offset
+ index
);
67 * Section 9.3.3.13 of PCIe Base Specification 6.2.
69 resource
->align
= MAX(resource
->align
, align
);
70 resource
->gran
= MAX(resource
->gran
, align
);
71 resource
->size
= 1 << resource
->gran
;
73 resource
->size
*= num_vfs
;
76 * Allocate above 4G to avoid exhausting MMIO32 space.
78 if (resource
->size
>= 16 * MiB
)
79 resource
->flags
|= IORESOURCE_ABOVE_4G
;
81 printk(BIOS_DEBUG
, "%s SRIOV BAR size 0x%llx, flags 0x%lx\n", dev_path(dev
),
82 resource
->size
, resource
->flags
);
84 if (resource
->flags
& IORESOURCE_PCI64
)
89 void pciexp_pf_read_resources(struct device
*dev
)
92 struct resource
*resource
;
94 printk(BIOS_SPEW
, "Reading resource: %s idx %02x\n", dev_path(dev
), PCI_BASE_ADDRESS_0
);
96 for (index
= PCI_BASE_ADDRESS_0
; index
< PCI_BASE_ADDRESS_0
+ (6 << 2);) {
97 resource
= pci_get_resource(dev
, index
);
99 * Allocate above 4G to avoid exhausting MMIO32 space.
101 if (resource
->size
>= 16 * MiB
)
102 resource
->flags
|= IORESOURCE_ABOVE_4G
;
104 index
+= (resource
->flags
& IORESOURCE_PCI64
) ? 8 : 4;
107 pciexp_vf_read_resources(dev
);
109 compact_resources(dev
);