Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af86fa40 authored by Yinghai Lu's avatar Yinghai Lu Committed by Bjorn Helgaas
Browse files

sparc/PCI: Add mem64 resource parsing for root bus

David reported that a T5-8 sparc system failed to boot with:

  pci_sun4v f02dbcfc: PCI host bridge to bus 0000:00
  pci_bus 0000:00: root bus resource [io  0x804000000000-0x80400fffffff] (bus address [0x0000-0xfffffff])
  pci_bus 0000:00: root bus resource [mem 0x800000000000-0x80007effffff] (bus address [0x00000000-0x7effffff])
  pci 0000:00:01.0: can't claim BAR 15 [mem 0x100000000-0x4afffffff pref]: no compatible bridge window

Note that we don't know about a host bridge aperture that contains
BAR 15.  OF does report a MEM64 aperture, but before this patch,
pci_determine_mem_io_space() ignored it.

Add support for host bridge apertures with 64-bit PCI addresses.  Also
set IORESOURCE_MEM_64 for PCI device and bridge resources in PCI 64-bit
memory space.

Sparc doesn't actually print the device and bridge resources, but after
this patch, we should have the equivalent of this:

  pci_sun4v f02dbcfc: PCI host bridge to bus 0000:00
  pci_bus 0000:00: root bus resource [io  0x804000000000-0x80400fffffff] (bus address [0x0000-0xfffffff])
  pci_bus 0000:00: root bus resource [mem 0x800000000000-0x80007effffff] (bus address [0x00000000-0x7effffff])
  pci_bus 0000:00: root bus resource [mem 0x800100000000-0x8007ffffffff] (bus address [0x100000000-0x7ffffffff])
  pci 0000:00:01.0:   bridge window [mem 0x800100000000-0x8004afffffff 64bit pref]

[bhelgaas: changelog, URL to David's report]
Fixes: d63e2e1f ("sparc/PCI: Clip bridge windows to fit in upstream windows")
Link: http://lkml.kernel.org/r/5514391F.2030300@oracle.com


Reported-by: default avatarDavid Ahern <david.ahern@oracle.com>
Tested-by: default avatarDavid Ahern <david.ahern@oracle.com>
Tested-by: default avatarKhalid Aziz <khalid.aziz@oracle.com>
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 597becb4
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -185,8 +185,10 @@ static unsigned long pci_parse_of_flags(u32 addr0)

	if (addr0 & 0x02000000) {
		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
		if (addr0 & 0x01000000)
			flags |= IORESOURCE_MEM_64
				 | PCI_BASE_ADDRESS_MEM_TYPE_64;
		if (addr0 & 0x40000000)
			flags |= IORESOURCE_PREFETCH
				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
@@ -655,6 +657,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
				pbm->io_space.start);
	pci_add_resource_offset(&resources, &pbm->mem_space,
				pbm->mem_space.start);
	if (pbm->mem64_space.flags)
		pci_add_resource_offset(&resources, &pbm->mem64_space,
					pbm->mem_space.start);
	pbm->busn.start = pbm->pci_first_busno;
	pbm->busn.end	= pbm->pci_last_busno;
	pbm->busn.flags	= IORESOURCE_BUS;
+15 −2
Original line number Diff line number Diff line
@@ -406,6 +406,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
	}

	num_pbm_ranges = i / sizeof(*pbm_ranges);
	memset(&pbm->mem64_space, 0, sizeof(struct resource));

	for (i = 0; i < num_pbm_ranges; i++) {
		const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
@@ -451,7 +452,12 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
			break;

		case 3:
			/* XXX 64-bit MEM handling XXX */
			/* 64-bit MEM handling */
			pbm->mem64_space.start = a;
			pbm->mem64_space.end = a + size - 1UL;
			pbm->mem64_space.flags = IORESOURCE_MEM;
			saw_mem = 1;
			break;

		default:
			break;
@@ -465,15 +471,22 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
		prom_halt();
	}

	printk("%s: PCI IO[%llx] MEM[%llx]\n",
	printk("%s: PCI IO[%llx] MEM[%llx]",
	       pbm->name,
	       pbm->io_space.start,
	       pbm->mem_space.start);
	if (pbm->mem64_space.flags)
		printk(" MEM64[%llx]",
		       pbm->mem64_space.start);
	printk("\n");

	pbm->io_space.name = pbm->mem_space.name = pbm->name;
	pbm->mem64_space.name = pbm->name;

	request_resource(&ioport_resource, &pbm->io_space);
	request_resource(&iomem_resource, &pbm->mem_space);
	if (pbm->mem64_space.flags)
		request_resource(&iomem_resource, &pbm->mem64_space);

	pci_register_legacy_regions(&pbm->io_space,
				    &pbm->mem_space);
+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ struct pci_pbm_info {
	/* PBM I/O and Memory space resources. */
	struct resource			io_space;
	struct resource			mem_space;
	struct resource			mem64_space;
	struct resource			busn;

	/* Base of PCI Config space, can be per-PBM or shared. */