PERFORCE change 191481 for review
John Baldwin
jhb at FreeBSD.org
Thu Apr 14 13:51:20 UTC 2011
http://p4web.freebsd.org/@@191481?ac=10
Change 191481 by jhb at jhb_fiver on 2011/04/14 13:51:11
Various hacking on two fronts:
- Support for PCI bus renumbering via PCI_RES_BUS resources.
- Support for managing PCI resource windows in Host to PCI bridge
drivers.
Affected files ...
.. //depot/projects/pci/sys/amd64/include/resource.h#2 edit
.. //depot/projects/pci/sys/conf/files#3 edit
.. //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#4 edit
.. //depot/projects/pci/sys/dev/pci/pci_domain.c#1 add
.. //depot/projects/pci/sys/dev/pci/pcib_private.h#8 edit
.. //depot/projects/pci/sys/x86/x86/nexus.c#4 edit
Differences ...
==== //depot/projects/pci/sys/amd64/include/resource.h#2 (text+ko) ====
@@ -40,5 +40,8 @@
#define SYS_RES_DRQ 2 /* isa dma lines */
#define SYS_RES_MEMORY 3 /* i/o memory */
#define SYS_RES_IOPORT 4 /* i/o ports */
+#ifdef NEW_PCIB
+#define PCI_RES_BUS 5 /* PCI bus numbers */
+#endif
#endif /* !_MACHINE_RESOURCE_H_ */
==== //depot/projects/pci/sys/conf/files#3 (text+ko) ====
@@ -1472,6 +1472,7 @@
dev/pci/ignore_pci.c optional pci
dev/pci/isa_pci.c optional pci isa
dev/pci/pci.c optional pci
+dev/pci/pci_domain.c optional pci new_pcib
dev/pci/pci_if.m standard
dev/pci/pci_pci.c optional pci
dev/pci/pci_user.c optional pci
==== //depot/projects/pci/sys/dev/acpica/acpi_pcib_acpi.c#4 (text+ko) ====
@@ -62,6 +62,10 @@
int ap_bus; /* bios-assigned bus number */
ACPI_BUFFER ap_prt; /* interrupt routing table */
+#ifdef NEW_PCIB
+ struct pcib_host_resources ap_host_res;
+ struct resource *ap_bus_res; /* resource for 'ap_bus' */
+#endif
};
static int acpi_pcib_acpi_probe(device_t bus);
@@ -101,8 +105,13 @@
DEVMETHOD(bus_read_ivar, acpi_pcib_read_ivar),
DEVMETHOD(bus_write_ivar, acpi_pcib_write_ivar),
DEVMETHOD(bus_alloc_resource, acpi_pcib_acpi_alloc_resource),
+#ifdef NEW_PCIB
+ DEVMETHOD(bus_adjust_resource, acpi_pcib_acpi_adjust_resource),
+ DEVMETHOD(bus_release_resource, acpi_pcib_acpi_release_resource),
+#else
DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+#endif
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
@@ -149,6 +158,20 @@
return (0);
}
+#ifdef NEW_PCIB
+static void
+acpi_pcib_add_producers(struct acpi_hpcib_softc *sc)
+{
+
+ if (pcib_host_res_init(sc->ap_dev, &sc->ap_host_res) != 0)
+ panic("failed to init hostb resources");
+ /*
+ * XXX: Next use AcpiWalkResources() on _CRS calling
+ * pcib_host_res_manage() on each producer range.
+ */
+}
+#endif
+
static int
acpi_pcib_acpi_attach(device_t dev)
{
@@ -241,7 +264,16 @@
}
}
+#ifdef NEW_PCIB
/*
+ * If we have a valid bus number, allocate it from our domain. If
+ * we do not have a valid bus number, hope that ACPI at least lays
+ * out the Host-PCI bridges in order and that as a result the next
+ * free bus number is our bus number.
+ */
+#else
+#endif
+ /*
* If nothing else worked, hope that ACPI at least lays out the
* host-PCI bridges in order and that as a result our unit number
* is actually our bus number. There are several reasons this
@@ -269,7 +301,7 @@
switch (which) {
case PCIB_IVAR_DOMAIN:
- *result = 0;
+ *result = sc->ap_segment;
return (0);
case PCIB_IVAR_BUS:
*result = sc->ap_bus;
@@ -364,6 +396,17 @@
acpi_pcib_acpi_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
+#ifdef NEW_PCIB
+ struct acpi_hpcib_softc *sc;
+ struct resource *r;
+ int error;
+
+ sc = device_get_softc(dev);
+ error = pcib_host_res_alloc(&sc->ap_host_res, child, type, rid, start, end,
+ count, flags, &r);
+ if (error == 0)
+ return (r);
+#endif
/*
* If no memory preference is given, use upper 32MB slot most
* bioses use for their memory window. Typically other bridges
@@ -371,7 +414,7 @@
* Hardcoding like this sucks, so a more MD/MI way needs to be
* found to do it. This is typically only used on older laptops
* that don't have pci busses behind pci bridge, so assuming > 32MB
- * is liekly OK.
+ * is likely OK.
*/
if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
start = acpi_host_mem_start;
==== //depot/projects/pci/sys/dev/pci/pcib_private.h#8 (text+ko) ====
@@ -33,6 +33,19 @@
#ifndef __PCIB_PRIVATE_H__
#define __PCIB_PRIVATE_H__
+#ifdef NEW_PCIB
+/*
+ * Data structure and routines that Host to PCI bridge drivers can use
+ * to suballocate resources to PCI devices.
+ */
+struct pcib_host_resources {
+ device_t hr_pcib;
+ struct resource_list hr_rl; /* allocated resources from parent */
+ struct rman hr_bus_rman;
+ struct rman hr_io_rman;
+ struct rman hr_mem_rman;
+};
+
/*
* Export portions of generic PCI:PCI bridge support so that it can be
* used by subclasses.
@@ -45,15 +58,15 @@
#define WIN_PMEM 0x4
struct pcib_window {
- pci_addr_t base; /* base address */
- pci_addr_t limit; /* topmost address */
- struct rman rman;
- struct resource *res;
- int reg; /* resource id from parent */
- int valid;
- int mask; /* WIN_* bitmask of this window */
- int step; /* log_2 of window granularity */
- const char *name;
+ pci_addr_t base; /* base address */
+ pci_addr_t limit; /* topmost address */
+ struct rman rman;
+ struct resource *res;
+ int reg; /* resource id from parent */
+ int valid;
+ int mask; /* WIN_* bitmask of this window */
+ int step; /* log_2 of window granularity */
+ const char *name;
};
#endif
@@ -90,6 +103,28 @@
typedef uint32_t pci_read_config_fn(int b, int s, int f, int reg, int width);
+#ifdef NEW_PCIB
+int pcib_host_res_init(device_t pcib,
+ struct pcib_host_resources *hr);
+int pcib_host_res_free(device_t pcib,
+ struct pcib_host_resources *hr);
+int pcib_host_res_manage(struct pcib_host_resources *hr, int type,
+ u_long start, u_long end);
+int pcib_host_res_alloc(struct pcib_host_resources *hr,
+ device_t dev, int type, int *rid, u_long start, u_long end,
+ u_long count, u_int flags, struct resource **rp);
+int pcib_host_res_adjust(struct pcib_host_resources *hr,
+ device_t dev, int type, struct resource *r, u_long start,
+ u_long end);
+int pcib_host_res_release(struct pcib_host_resources *hr,
+ device_t dev, int type, int rid, struct resource *r);
+struct resource *pci_domain_alloc_bus(int domain, device_t dev, int *rid, u_long start,
+ u_long end, u_long count, u_int flags);
+int pci_domain_adjust_bus(int domain, device_t dev, struct resource *r,
+ u_long start, u_long end);
+int pci_domain_release_bus(int domain, device_t dev, int rid,
+ struct resource *r);
+#endif
int host_pcib_get_busno(pci_read_config_fn read_config, int bus,
int slot, int func, uint8_t *busnum);
int pcib_attach(device_t dev);
==== //depot/projects/pci/sys/x86/x86/nexus.c#4 (text+ko) ====
@@ -70,6 +70,8 @@
#include <machine/resource.h>
#include <machine/pc/bios.h>
+#include <dev/pci/pcib_private.h>
+
#ifdef DEV_APIC
#include "pcib_if.h"
#endif
@@ -383,6 +385,23 @@
count = rle->count;
}
+#ifdef NEW_PCIB
+ if (type == PCI_RES_BUS) {
+ /*
+ * PCI bus number resources are allocated from a
+ * specific PCI domain. The child device must be a
+ * 'pcib' device which implements the pcib ivars. We
+ * depend on that to determine which PCI domain to
+ * allocate from.
+ */
+ rv = pci_domain_alloc_bus(pcib_get_domain(child), child, rid,
+ start, end, count, flags);
+ if (rv == NULL)
+ return (NULL);
+ rman_set_rid(rv, *rid);
+ return (rv);
+ }
+#endif
flags &= ~RF_ACTIVE;
rm = nexus_rman(type);
if (rm == NULL)
@@ -409,6 +428,11 @@
{
struct rman *rm;
+#ifdef NEW_PCIB
+ if (type == PCI_RES_BUS)
+ return (pci_domain_adjust_bus(pcib_get_domain(child), child, r,
+ start, end));
+#endif
rm = nexus_rman(type);
if (rm == NULL)
return (ENXIO);
@@ -492,6 +516,12 @@
nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+
+#ifdef NEW_PCIB
+ if (type == PCI_RES_BUS) {
+ return (pci_domain_release_bus(pcib_get_domain(child), child,
+ rid, r));
+#endif
if (rman_get_flags(r) & RF_ACTIVE) {
int error = bus_deactivate_resource(child, type, rid, r);
if (error)
More information about the p4-projects
mailing list