mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <ahmad@a3f.at>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <ahmad@a3f.at>
Subject: [PATCH 2/4] PCI: support PCI BIOS preassigned buses
Date: Fri, 16 Apr 2021 08:24:34 +0200	[thread overview]
Message-ID: <20210416062436.332665-3-ahmad@a3f.at> (raw)
In-Reply-To: <20210416062436.332665-1-ahmad@a3f.at>

When running under UEFI, barebox should no redo PCI enumeration,
because the UEFI implementation will likely already have drivers
that won't cope with e.g. BAR addresses changing.

The user-visible effect of this is that likely the framebuffer will
stop working because the UEFI driver won't be able to access it
any longer.

Support this configuration by changing the PCI code to consult the
new pcibios_assign_all_busses().

When it's true, there is no change to previous behavior.
When it's false, reconfiguration is omitted and instead current
configuration is read back from the bus.

Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
---
 arch/arm/include/asm/pci.h  |   7 +++
 arch/mips/include/asm/pci.h |   7 +++
 drivers/pci/pci.c           | 106 +++++++++++++++++++++++-------------
 include/linux/pci.h         |   3 +
 4 files changed, 86 insertions(+), 37 deletions(-)
 create mode 100644 arch/arm/include/asm/pci.h
 create mode 100644 arch/mips/include/asm/pci.h

diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
new file mode 100644
index 000000000000..d7419cabe7ef
--- /dev/null
+++ b/arch/arm/include/asm/pci.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+
+#define pcibios_assign_all_busses()	1
+
+#endif
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
new file mode 100644
index 000000000000..d7419cabe7ef
--- /dev/null
+++ b/arch/mips/include/asm/pci.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+
+#define pcibios_assign_all_busses()	1
+
+#endif
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 945a983387ed..950c5094476c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -51,25 +51,27 @@ void register_pci_controller(struct pci_controller *hose)
 	bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
 	bus->resource[PCI_BUS_RESOURCE_MEM_PREF] = hose->mem_pref_resource;
 	bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
-	bus->number = bus_index++;
 
-	if (hose->set_busno)
-		hose->set_busno(hose, bus->number);
-
-	if (bus->resource[PCI_BUS_RESOURCE_MEM])
-		last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
-	else
-		last_mem = 0;
-
-	if (bus->resource[PCI_BUS_RESOURCE_MEM_PREF])
-		last_mem_pref = bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->start;
-	else
-		last_mem_pref = 0;
-
-	if (bus->resource[PCI_BUS_RESOURCE_IO])
-		last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
-	else
-		last_io = 0;
+	if (pcibios_assign_all_busses()) {
+		bus->number = bus_index++;
+		if (hose->set_busno)
+			hose->set_busno(hose, bus->number);
+
+		if (bus->resource[PCI_BUS_RESOURCE_MEM])
+			last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+		else
+			last_mem = 0;
+
+		if (bus->resource[PCI_BUS_RESOURCE_MEM_PREF])
+			last_mem_pref = bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->start;
+		else
+			last_mem_pref = 0;
+
+		if (bus->resource[PCI_BUS_RESOURCE_IO])
+			last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+		else
+			last_io = 0;
+	}
 
 	pci_scan_bus(bus);
 	pci_bus_register_devices(bus);
@@ -156,13 +158,16 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 	u8 cmd;
 
 	pci_read_config_byte(dev, PCI_COMMAND, &cmd);
-	pci_write_config_byte(dev, PCI_COMMAND,
-			      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
+	if (pcibios_assign_all_busses())
+		pci_write_config_byte(dev, PCI_COMMAND,
+				      cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
 
 	for (bar = 0; bar < max_bar; bar++) {
 		const int pci_base_address_0 = PCI_BASE_ADDRESS_0 + bar * 4;
 		const int pci_base_address_1 = PCI_BASE_ADDRESS_1 + bar * 4;
-		resource_size_t *last_addr;
+		resource_size_t *last_addr, start;
 		u32 orig, mask, size;
 		unsigned long flags;
 		const char *kind;
@@ -207,32 +212,47 @@ static void setup_device(struct pci_dev *dev, int max_bar)
 		pr_debug("pbar%d: mask=%08x %s %d bytes\n", bar, mask, kind,
 			 size);
 
-		if (ALIGN(*last_addr, size) + size >
-		    dev->bus->resource[busres]->end) {
-			pr_debug("BAR does not fit within bus %s res\n", kind);
-			return;
+		if (pcibios_assign_all_busses()) {
+			if (ALIGN(*last_addr, size) + size >
+			    dev->bus->resource[busres]->end) {
+				pr_debug("BAR does not fit within bus %s res\n", kind);
+				return;
+			}
+
+			*last_addr = ALIGN(*last_addr, size);
+			pci_write_config_dword(dev, pci_base_address_0, *last_addr);
+			if (mask & PCI_BASE_ADDRESS_MEM_TYPE_64)
+				pci_write_config_dword(dev, pci_base_address_1, 0);
+			start = *last_addr;
+			*last_addr += size;
+		} else {
+			u32 tmp;
+			pci_read_config_dword(dev, pci_base_address_0, &tmp);
+			tmp &= mask & PCI_BASE_ADDRESS_SPACE_IO ? PCI_BASE_ADDRESS_IO_MASK
+				                                : PCI_BASE_ADDRESS_MEM_MASK;
+			start = tmp;
+
+			if (mask & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+				pci_read_config_dword(dev, pci_base_address_1, &tmp);
+				start |= (u64)tmp << 32;
+			}
 		}
 
-		*last_addr = ALIGN(*last_addr, size);
-		pci_write_config_dword(dev, pci_base_address_0, *last_addr);
 		dev->resource[bar].flags = flags;
-		dev->resource[bar].start = *last_addr;
-		dev->resource[bar].end = dev->resource[bar].start + size - 1;
-
-		pr_debug("pbar%d: allocated at %pa\n", bar, last_addr);
-
-		*last_addr += size;
+		dev->resource[bar].start = start;
+		dev->resource[bar].end = start + size - 1;
 
 		if (mask & PCI_BASE_ADDRESS_MEM_TYPE_64) {
 			dev->resource[bar].flags |= IORESOURCE_MEM_64;
-			pci_write_config_dword(dev, pci_base_address_1, 0);
 			bar++;
 		}
 	}
 
 	pci_fixup_device(pci_fixup_header, dev);
 
-	pci_write_config_byte(dev, PCI_COMMAND, cmd);
+	if (pcibios_assign_all_busses())
+		pci_write_config_byte(dev, PCI_COMMAND, cmd);
+
 	list_add_tail(&dev->bus_list, &dev->bus->devices);
 }
 
@@ -240,6 +260,12 @@ static void prescan_setup_bridge(struct pci_dev *dev)
 {
 	u16 cmdstat;
 
+	if (!pcibios_assign_all_busses()) {
+		pci_read_config_byte(dev, PCI_PRIMARY_BUS, &dev->bus->number);
+		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &dev->subordinate->number);
+		return;
+	}
+
 	pci_read_config_word(dev, PCI_COMMAND, &cmdstat);
 
 	/* Configure bus number registers */
@@ -283,6 +309,9 @@ static void prescan_setup_bridge(struct pci_dev *dev)
 
 static void postscan_setup_bridge(struct pci_dev *dev)
 {
+	if (!pcibios_assign_all_busses())
+		return;
+
 	/* limit subordinate to last used bus number */
 	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, bus_index - 1);
 
@@ -416,8 +445,11 @@ static unsigned int pci_scan_bus(struct pci_bus *bus)
 				bus->resource[PCI_BUS_RESOURCE_IO];
 
 			child_bus->parent = &dev->dev;
-			child_bus->number = bus_index++;
-			child_bus->primary = bus->number;
+
+			if (pcibios_assign_all_busses()) {
+				child_bus->number = bus_index++;
+				child_bus->primary = bus->number;
+			}
 			list_add_tail(&child_bus->node, &bus->children);
 			dev->subordinate = child_bus;
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0c8fed7c8e0d..486d4251d42a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -29,6 +29,9 @@
 
 #include <linux/pci_ids.h>
 
+/* Include architecture-dependent settings and functions */
+
+#include <asm/pci.h>
 #define PCI_ANY_ID (~0)
 
 #define PCI_FIND_CAP_TTL	48
-- 
2.31.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


  parent reply	other threads:[~2021-04-16  6:27 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-16  6:24 [PATCH 0/4] x86: add EFI PCI host and iTCO watchdog support Ahmad Fatoum
2021-04-16  6:24 ` [PATCH 1/4] x86: add DMA support Ahmad Fatoum
2021-04-16  6:24 ` Ahmad Fatoum [this message]
2021-04-16  6:24 ` [PATCH 3/4] pci: add EFI PCI root bridge IO protocol driver Ahmad Fatoum
2021-04-16  6:24 ` [PATCH 4/4] watchdog: add support for Intel TCO watchdog timer Ahmad Fatoum
2021-05-03 12:07 ` [PATCH 0/4] x86: add EFI PCI host and iTCO watchdog support Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210416062436.332665-3-ahmad@a3f.at \
    --to=ahmad@a3f.at \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox