Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Apr 2011 13:51:20 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 191481 for review
Message-ID:  <201104141351.p3EDpKcN076703@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@191481?ac=10

Change 191481 by jhb@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)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104141351.p3EDpKcN076703>