Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Feb 2010 02:59:50 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r203796 - in head/sys: conf mips/conf mips/mips mips/sibyte
Message-ID:  <201002120259.o1C2xoPr069696@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Fri Feb 12 02:59:49 2010
New Revision: 203796
URL: http://svn.freebsd.org/changeset/base/203796

Log:
  Remove the PCI_IOSPACE_SIZE and PCI_IOSPACE_ADDR hack from nexus.c. Implement
  this in the Sibyte PCI hostbridge driver instead.
  
  The nexus driver sees resource allocation requests for memory and irq
  resources only. These are legitimate resources on all MIPS platforms.
  
  Suggested by: imp

Modified:
  head/sys/conf/options.mips
  head/sys/mips/conf/SWARM
  head/sys/mips/mips/nexus.c
  head/sys/mips/sibyte/sb_zbpci.c

Modified: head/sys/conf/options.mips
==============================================================================
--- head/sys/conf/options.mips	Fri Feb 12 02:26:12 2010	(r203795)
+++ head/sys/conf/options.mips	Fri Feb 12 02:59:49 2010	(r203796)
@@ -61,14 +61,6 @@ TICK_USE_YAMON_FREQ	opt_global.h
 TICK_USE_MALTA_RTC	opt_global.h
 
 #
-# The MIPS architecture does not have separate memory and i/o address space
-# like x86. However some MIPS processors provide a memory-mapped window that
-# maps onto the PCI I/O space.
-#
-PCI_IOSPACE_SIZE        opt_global.h
-PCI_IOSPACE_ADDR        opt_global.h
-
-#
 # The highest memory address that can be used by the kernel in units of KB.
 #
 MAXMEM			opt_global.h

Modified: head/sys/mips/conf/SWARM
==============================================================================
--- head/sys/mips/conf/SWARM	Fri Feb 12 02:26:12 2010	(r203795)
+++ head/sys/mips/conf/SWARM	Fri Feb 12 02:59:49 2010	(r203796)
@@ -8,9 +8,6 @@ options		CPU_SB1
 files		"../sibyte/files.sibyte"
 hints		"SWARM.hints"
 
-options		PCI_IOSPACE_ADDR=0xFC000000
-options		PCI_IOSPACE_SIZE=0x02000000
-
 #
 # 32-bit kernel cannot deal with physical memory beyond 4GB
 # XXX pmap assumes that all the memory can be mapped using KSEG0

Modified: head/sys/mips/mips/nexus.c
==============================================================================
--- head/sys/mips/mips/nexus.c	Fri Feb 12 02:26:12 2010	(r203795)
+++ head/sys/mips/mips/nexus.c	Fri Feb 12 02:59:49 2010	(r203796)
@@ -77,7 +77,6 @@ struct nexus_device {
 
 static struct rman irq_rman;
 static struct rman mem_rman;
-static struct rman port_rman;
 
 static struct resource *
 		nexus_alloc_resource(device_t, device_t, int, int *, u_long,
@@ -161,21 +160,6 @@ nexus_probe(device_t dev)
 		panic("%s: mem_rman", __func__);
 	}
 
-	/*
-	 * MIPS has no concept of the x86 I/O address space but some cpus
-	 * provide a memory mapped window to access the PCI I/O BARs.
-	 */
-	port_rman.rm_start = 0;
-#ifdef PCI_IOSPACE_SIZE
-	port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
-#endif
-	port_rman.rm_type = RMAN_ARRAY;
-	port_rman.rm_descr = "I/O ports";
-	if (rman_init(&port_rman) != 0 ||
-	    rman_manage_region(&port_rman, 0, port_rman.rm_end) != 0)
-		panic("%s: port_rman", __func__);
-
-
 	return (0);
 }
 
@@ -241,7 +225,6 @@ nexus_print_all_resources(device_t dev)
 
 	retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
 	retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
-	retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
 
 	return (retval);
 }
@@ -368,9 +351,6 @@ nexus_alloc_resource(device_t bus, devic
 	case SYS_RES_MEMORY:
 		rm = &mem_rman;
 		break;
-	case SYS_RES_IOPORT:
-		rm = &port_rman;
-		break;
 	default:
 		printf("%s: unknown resource type %d\n", __func__, type);
 		return (0);
@@ -400,21 +380,17 @@ static int
 nexus_activate_resource(device_t bus, device_t child, int type, int rid,
     struct resource *r)
 {
+	void *vaddr;
+	u_int32_t paddr, psize;
+	
 	/*
 	 * If this is a memory resource, track the direct mapping
 	 * in the uncached MIPS KSEG1 segment.
 	 */
-	/* XXX we shouldn't be supporting sys_res_ioport here */
-	if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
-		caddr_t vaddr = 0;
-		u_int32_t paddr;
-		u_int32_t psize;
-		u_int32_t poffs;
-		
+	if (type == SYS_RES_MEMORY) {
 		paddr = rman_get_start(r);
 		psize = rman_get_size(r);
-		poffs = paddr - trunc_page(paddr);
-		vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
+		vaddr = pmap_mapdev(paddr, psize);
 
 		rman_set_virtual(r, vaddr);
 		rman_set_bustag(r, mips_bus_space_generic);
@@ -501,7 +477,7 @@ nexus_deactivate_resource(device_t bus, 
 {
 	vm_offset_t va;
 	
-	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+	if (type == SYS_RES_MEMORY) {
 		va = (vm_offset_t)rman_get_virtual(r);
 		pmap_unmapdev(va, rman_get_size(r));
 	}

Modified: head/sys/mips/sibyte/sb_zbpci.c
==============================================================================
--- head/sys/mips/sibyte/sb_zbpci.c	Fri Feb 12 02:26:12 2010	(r203795)
+++ head/sys/mips/sibyte/sb_zbpci.c	Fri Feb 12 02:59:49 2010	(r203796)
@@ -30,6 +30,7 @@
 #include <sys/systm.h>
 #include <sys/module.h>
 #include <sys/bus.h>
+#include <sys/rman.h>
 #include <sys/pcpu.h>
 #include <sys/smp.h>
 
@@ -45,6 +46,7 @@
 
 #include <machine/pmap.h>
 #include <machine/resource.h>
+#include <machine/bus.h>
 
 #include "pcib_if.h"
 
@@ -58,7 +60,11 @@ static struct {
 } zbpci_config_space[MAXCPU];
 
 static const vm_paddr_t CFG_PADDR_BASE = 0xFE000000;
-	
+static const u_long PCI_IOSPACE_ADDR = 0xFC000000;
+static const u_long PCI_IOSPACE_SIZE = 0x02000000;
+
+static struct rman port_rman;
+
 static int
 zbpci_probe(device_t dev)
 {
@@ -73,13 +79,32 @@ zbpci_attach(device_t dev)
 	int n, rid, size;
 	vm_offset_t va;
 	struct resource *res;
+	
+	/*
+	 * Reserve the physical memory window used to map PCI I/O space.
+	 */
+	rid = 0;
+	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+				 PCI_IOSPACE_ADDR,
+				 PCI_IOSPACE_ADDR + PCI_IOSPACE_SIZE - 1,
+				 PCI_IOSPACE_SIZE, 0);
+	if (res == NULL)
+		panic("Cannot allocate resource for PCI I/O space mapping.");
+
+	port_rman.rm_start = 0;
+	port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
+	port_rman.rm_type = RMAN_ARRAY;
+	port_rman.rm_descr = "PCI I/O ports";
+	if (rman_init(&port_rman) != 0 ||
+	    rman_manage_region(&port_rman, 0, PCI_IOSPACE_SIZE - 1) != 0)
+		panic("%s: port_rman", __func__);
 
 	/*
 	 * Reserve the the physical memory that is used to read/write to the
 	 * pci config space but don't activate it. We are using a page worth
 	 * of KVA as a window over this region.
 	 */
-	rid = 0;
+	rid = 1;
 	size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256;
 	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE,
 				 CFG_PADDR_BASE + size - 1, size, 0);
@@ -115,6 +140,101 @@ zbpci_attach(device_t dev)
 	return (bus_generic_attach(dev));
 }
 
+static struct resource *
+zbpci_alloc_resource(device_t bus, device_t child, int type, int *rid,
+		     u_long start, u_long end, u_long count, u_int flags)
+{
+	struct resource *res;
+
+	/*
+	 * Handle PCI I/O port resources here and pass everything else to nexus.
+	 */
+	if (type != SYS_RES_IOPORT) {
+		res = bus_generic_alloc_resource(bus, child, type, rid,
+						 start, end, count, flags);
+		return (res);
+	}
+
+	res = rman_reserve_resource(&port_rman, start, end, count,
+				    flags, child);
+	if (res == NULL)
+		return (NULL);
+
+	rman_set_rid(res, *rid);
+
+	/* Activate the resource is requested */
+	if (flags & RF_ACTIVE) {
+		if (bus_activate_resource(child, type, *rid, res) != 0) {
+			rman_release_resource(res);
+			return (NULL);
+		}
+	}
+
+	return (res);
+}
+
+static int
+zbpci_activate_resource(device_t bus, device_t child, int type, int rid,
+			struct resource *res)
+{
+	void *vaddr;
+	u_long paddr, psize;
+
+	if (type != SYS_RES_IOPORT) {
+		return (bus_generic_activate_resource(bus, child, type,
+						      rid, res));
+	}
+
+	/*
+	 * Map the I/O space resource through the memory window starting
+	 * at PCI_IOSPACE_ADDR.
+	 */
+	paddr = rman_get_start(res) + PCI_IOSPACE_ADDR;
+	psize = rman_get_size(res);
+	vaddr = pmap_mapdev(paddr, psize);
+
+	rman_set_virtual(res, vaddr);
+	rman_set_bustag(res, mips_bus_space_generic);
+	rman_set_bushandle(res, (bus_space_handle_t)vaddr);
+
+	return (rman_activate_resource(res));
+}
+
+static int
+zbpci_release_resource(device_t bus, device_t child, int type, int rid,
+		       struct resource *r)
+{
+	int error;
+
+	if (type != SYS_RES_IOPORT)
+		return (bus_generic_release_resource(bus, child, type, rid, r));
+
+	if (rman_get_flags(r) & RF_ACTIVE) {
+		error = bus_deactivate_resource(child, type, rid, r);
+		if (error)
+			return (error);
+	}
+
+	return (rman_release_resource(r));
+}
+
+static int
+zbpci_deactivate_resource(device_t bus, device_t child, int type, int rid,
+			  struct resource *r)
+{
+	vm_offset_t va;
+
+	if (type != SYS_RES_IOPORT) {
+		return (bus_generic_deactivate_resource(bus, child, type,
+							rid, r));
+	}
+	
+	va = (vm_offset_t)rman_get_virtual(r);
+	pmap_unmapdev(va, rman_get_size(r));
+
+	return (rman_deactivate_resource(r));
+}
+
 static int
 zbpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
 {
@@ -248,10 +368,10 @@ static device_method_t zbpci_methods[] =
 	/* Bus interface */
 	DEVMETHOD(bus_read_ivar,	zbpci_read_ivar),
 	DEVMETHOD(bus_write_ivar,	bus_generic_write_ivar),
-	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
-	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
-	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
-	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_alloc_resource,	zbpci_alloc_resource),
+	DEVMETHOD(bus_activate_resource, zbpci_activate_resource),
+	DEVMETHOD(bus_deactivate_resource, zbpci_deactivate_resource),
+	DEVMETHOD(bus_release_resource,	zbpci_release_resource),
 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
 	DEVMETHOD(bus_add_child,	bus_generic_add_child),



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