]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pci] Record prefetchable memory window for PCI bridges
authorMichael Brown <mcb30@ipxe.org>
Tue, 14 Oct 2025 17:37:39 +0000 (18:37 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 14 Oct 2025 17:38:08 +0000 (18:38 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/bus/pcibridge.c
src/include/ipxe/pci.h
src/include/ipxe/pcibridge.h

index d2763faf9ce83e3109ba49789f7a9c10fc71a0e2..67c97589ff61b3f614ea9f2e20e27b4c3b9abca8 100644 (file)
@@ -68,6 +68,8 @@ static int pcibridge_probe ( struct pci_device *pci ) {
        struct pci_bridge *bridge;
        uint16_t base;
        uint16_t limit;
+       uint32_t base_hi;
+       uint32_t limit_hi;
        int rc;
 
        /* Allocate and initialise structure */
@@ -78,17 +80,33 @@ static int pcibridge_probe ( struct pci_device *pci ) {
        }
        bridge->pci = pci;
 
-       /* Read configuration */
+       /* Read bus configuration */
        pci_read_config_dword ( pci, PCI_PRIMARY, &bridge->buses );
        cpu_to_le32s ( &buses );
+
+       /* Read memory base and limit */
        pci_read_config_word ( pci, PCI_MEM_BASE, &base );
        bridge->membase = ( ( base & ~PCI_MEM_MASK ) << 16 );
        pci_read_config_word ( pci, PCI_MEM_LIMIT, &limit );
        bridge->memlimit = ( ( ( ( limit | PCI_MEM_MASK ) + 1 ) << 16 ) - 1 );
-       DBGC ( bridge, "BRIDGE " PCI_FMT " bus %02x to [%02x,%02x) mem "
-              "[%08x,%08x)\n", PCI_ARGS ( pci ), bridge->primary,
-              bridge->secondary, bridge->subordinate, bridge->membase,
-              bridge->memlimit );
+
+       /* Read prefetchable memory base and limit */
+       pci_read_config_word ( pci, PCI_PREFMEM_BASE, &base );
+       pci_read_config_dword ( pci, PCI_PREFMEM_BASE_HI, &base_hi );
+       bridge->prefmembase = ( ( ( base & ~PCI_MEM_MASK ) << 16 ) |
+                               ( ( ( uint64_t ) base_hi ) << 32 ) );
+       pci_read_config_word ( pci, PCI_PREFMEM_LIMIT, &limit );
+       pci_read_config_dword ( pci, PCI_PREFMEM_LIMIT_HI, &limit_hi );
+       bridge->prefmemlimit = ( ( ( ( ( limit | PCI_MEM_MASK ) + 1 ) << 16 ) |
+                                  ( ( ( uint64_t ) limit_hi ) << 32 ) ) - 1 );
+
+       DBGC ( bridge, "BRIDGE " PCI_FMT " bus %02x to [%02x,%02x)\n",
+              PCI_ARGS ( pci ), bridge->primary, bridge->secondary,
+              bridge->subordinate );
+       DBGC ( bridge, "BRIDGE " PCI_FMT " mem [%08x,%08x) prefmem "
+              "[%08llx,%08llx)\n", PCI_ARGS ( pci ), bridge->membase,
+              bridge->memlimit, ( ( unsigned long long ) bridge->prefmembase ),
+              ( ( unsigned long long ) bridge->prefmemlimit ) );
 
        /* Add to list of PCI bridges */
        list_add ( &bridge->list, &pcibridges );
index 6eeabef3067e5ca20701d62c56a80263ed5713d7..2728cbd45e76a48eb4dd59c567a4e8aadade72ca 100644 (file)
@@ -151,7 +151,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Memory base and limit */
 #define PCI_MEM_BASE           0x20
 #define PCI_MEM_LIMIT          0x22
-#define PCI_MEM_MASK                   0x000f
+#define PCI_MEM_MASK                   0x000fUL
+#define PCI_PREFMEM_BASE       0x24
+#define PCI_PREFMEM_LIMIT      0x26
+#define PCI_PREFMEM_BASE_HI    0x28
+#define PCI_PREFMEM_LIMIT_HI   0x2c
 
 /** Construct PCI class
  *
index c57a81067f85c48e1425f0414ff1be13ecc326f5..3a278a0ca6bd1f13fc7901b51ad6812fffb73fa6 100644 (file)
@@ -34,6 +34,10 @@ struct pci_bridge {
        uint32_t membase;
        /** Memory limit */
        uint32_t memlimit;
+       /** Prefetchable memory base */
+       uint64_t prefmembase;
+       /** Prefetchable memory limit */
+       uint64_t prefmemlimit;
        /** List of bridges */
        struct list_head list;
 };