Module Name:    src
Committed By:   cliff
Date:           Sun Nov 15 23:11:06 UTC 2009

Modified Files:
        src/sys/arch/mips/rmi [matt-nb5-mips64]: rmixl_pcie.c rmixl_pcievar.h

Log Message:
- abandon XKPHYS mapping for access PCIe CFG and ECFG space, useless for N32
- rmixl_pcie_conf_read() and rmixl_pcie_conf_write() now use
rmixl_pcie_conf_setup() to establish bus space mappings for
access to PCIe CFG, ECFG space.  The mappings are "lazy"
to allow successive accesses to the same (bus) in CFG space,
or to the same (bus, device) in ECFG space, to reuse the mapping.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/arch/mips/rmi/rmixl_pcie.c
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/arch/mips/rmi/rmixl_pcievar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/rmi/rmixl_pcie.c
diff -u src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.2 src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.3
--- src/sys/arch/mips/rmi/rmixl_pcie.c:1.1.2.2	Fri Nov 13 05:22:19 2009
+++ src/sys/arch/mips/rmi/rmixl_pcie.c	Sun Nov 15 23:11:06 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: rmixl_pcie.c,v 1.1.2.2 2009/11/13 05:22:19 cliff Exp $	*/
+/*	$NetBSD: rmixl_pcie.c,v 1.1.2.3 2009/11/15 23:11:06 cliff Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.1.2.2 2009/11/13 05:22:19 cliff Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rmixl_pcie.c,v 1.1.2.3 2009/11/15 23:11:06 cliff Exp $");
 
 #include "opt_pci.h"
 #include "pci.h"
@@ -89,16 +89,6 @@
 
 
 /*
- * use XKPHYS in order to accomodate XLS 40 bit PCIe bus address
- * PCIe config space is all little endian for now
- */
-#define RMIXL_PCI_VADDR(ba)					\
-	(volatile uint32_t *)MIPS_PHYS_TO_XKPHYS_UNCACHED(ba)
-#define RMIXL_PCI_READ(o)     le32toh(*RMIXL_PCI_VADDR(o))
-#define RMIXL_PCI_WRITE(o,v)  *RMIXL_PCI_VADDR(o) = htole32(v)
-
-
-/*
  * XLS PCIe Extended Configuration Registers
  */
 #define RMIXL_PCIE_ECFG_UESR	0x104	/* Uncorrectable Error Status Reg */
@@ -149,9 +139,13 @@
 static void	rmixl_pcie_errata(struct rmixl_pcie_softc *);
 static void	rmixl_conf_interrupt(void *, int, int, int, int, int *);
 static int	rmixl_pcie_bus_maxdevs(void *, int);
+static pcitag_t	rmixl_tag_to_ecfg(pcitag_t);
 static pcitag_t	rmixl_pcie_make_tag(void *, int, int, int);
 static void	rmixl_pcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
 void		rmixl_pcie_tag_print(const char *restrict, void *, pcitag_t,				int, vaddr_t, u_long);
+static int	rmixl_pcie_conf_setup(struct rmixl_pcie_softc *,
+			pcitag_t, int *, bus_space_tag_t *,
+			bus_space_handle_t *);
 static pcireg_t	rmixl_pcie_conf_read(void *, pcitag_t, int);
 static void	rmixl_pcie_conf_write(void *, pcitag_t, int, pcireg_t);
 
@@ -306,7 +300,8 @@
 		u_long n = RMIXL_PCIE_CFG_SIZE / (1024 * 1024);
 		RMIXL_PCIE_BAR_INIT(CFG, bar, n, n);
 	}
-	sc->sc_pcie_cfg_pbase = RMIXL_PCIE_CFG_BAR_TO_BA(bar);
+	rcp->rc_pcie_cfg_pbase = (bus_addr_t)RMIXL_PCIE_CFG_BAR_TO_BA(bar);
+	rcp->rc_pcie_cfg_size  = (bus_size_t)RMIXL_PCIE_CFG_SIZE;
 
 	/*
 	 * get PCIE Extended config space base addr from SBC PCIe ECFG BAR
@@ -318,7 +313,8 @@
 		u_long n = RMIXL_PCIE_ECFG_SIZE / (1024 * 1024);
 		RMIXL_PCIE_BAR_INIT(ECFG, bar, n, n);
 	}
-	sc->sc_pcie_ecfg_pbase = RMIXL_PCIE_ECFG_BAR_TO_BA(bar);
+	rcp->rc_pcie_ecfg_pbase = (bus_addr_t)RMIXL_PCIE_ECFG_BAR_TO_BA(bar);
+	rcp->rc_pcie_ecfg_size  = (bus_size_t)RMIXL_PCIE_ECFG_SIZE;
 
 	/*
 	 * get PCI MEM space base [addr, size] from SBC PCIe MEM BAR
@@ -347,7 +343,16 @@
 	rcp->rc_pci_io_size  = (bus_size_t)RMIXL_PCIE_IO_BAR_TO_SIZE(bar);
 
 	/*
-	 * initialize the PCI bus spaces tag
+	 * initialize the PCI CFG, ECFG bus space tags
+	 */
+	rmixl_pcie_cfg_bus_mem_init(&rcp->rc_pcie_cfg_memt, rcp);
+	sc->sc_pcie_cfg_memt = &rcp->rc_pcie_cfg_memt;
+
+	rmixl_pcie_ecfg_bus_mem_init(&rcp->rc_pcie_ecfg_memt, rcp);
+	sc->sc_pcie_ecfg_memt = &rcp->rc_pcie_ecfg_memt;
+
+	/*
+	 * initialize the PCI MEM and IO bus space tags
 	 */
 	rmixl_pcie_bus_mem_init(&rcp->rc_pci_memt, rcp);
 	rmixl_pcie_bus_io_init(&rcp->rc_pci_iot, rcp);
@@ -769,18 +774,38 @@
 }
 
 /*
+ * rmixl_tag_to_ecfg - convert cfg address (generic tag) to ecfg address
+ *
+ *	39:29   (reserved)
+ *	28      Swap (0=little, 1=big endian)
+ *	27:20   Bus number
+ *	19:15   Device number
+ *	14:12   Function number
+ *	11:8    Extended Register number
+ *	7:0     Register number
+ */
+static pcitag_t
+rmixl_tag_to_ecfg(pcitag_t tag)
+{
+	KASSERT((tag & __BITS(7,0)) == 0);
+	return (tag << 4);
+}
+
+/*
  * XLS pci tag is a 40 bit address composed thusly:
  *	39:25   (reserved)
  *	24      Swap (0=little, 1=big endian)
  *	23:16   Bus number
  *	15:11   Device number
  *	10:8    Function number
- *	0:7     Register number
+ *	7:0     Register number
+ *
+ * Note: this is the "native" composition for addressing CFG space, but not for ECFG space.
  */
 pcitag_t
-rmixl_pcie_make_tag(void *v, int b, int d, int f)
+rmixl_pcie_make_tag(void *v, int bus, int dev, int fun)
 {
-	return ((b << 16) | (d << 11) | (f << 8));
+	return ((bus << 16) | (dev << 11) | (fun << 8));
 }
 
 void
@@ -801,50 +826,116 @@
 	int bus, dev, fun;
 
 	rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
-	printf("%s: %d/%d/%d/%d - %#lx:%#lx\n",
+	printf("%s: %d/%d/%d/%d - %#" PRIxVADDR ":%#lx\n",
 		s, bus, dev, fun, offset, va, r);
 }
 
+static int
+rmixl_pcie_conf_setup(struct rmixl_pcie_softc *sc,
+	pcitag_t tag, int *offp, bus_space_tag_t *bstp,
+	bus_space_handle_t *bshp)
+{
+	struct rmixl_config *rcp = &rmixl_configuration;
+	bus_space_tag_t bst;
+	bus_space_handle_t bsh;
+	bus_size_t size;
+	pcitag_t mask;
+	bus_addr_t ba;
+	int err;
+	static bus_space_handle_t cfg_bsh;
+	static pcitag_t cfg_oba = -1;
+	static bus_space_handle_t ecfg_bsh;
+	static pcitag_t ecfg_oba = -1;
+
+	/*
+	 * bus space depends on offset
+	 */
+	if ((*offp >= 0) && (*offp < 0x100)) {
+		mask = __BITS(15,0);
+		bst = sc->sc_pcie_cfg_memt;
+		ba = rcp->rc_pcie_cfg_pbase;
+		ba += (tag & ~mask);
+		*offp += (tag & mask);
+		if (ba != cfg_oba) {
+			size = (bus_size_t)(mask + 1);
+			if (cfg_oba != -1)
+				bus_space_unmap(bst, cfg_bsh, size);
+			err = bus_space_map(bst, ba, size, 0, &cfg_bsh);
+			if (err != 0) {
+#ifdef DEBUG
+				panic("%s: bus_space_map err %d, CFG space",
+					__func__, err);	/* XXX */
+#endif
+				return -1;
+			}
+			cfg_oba = ba;
+		}
+		bsh = cfg_bsh;
+	} else if ((*offp >= 0x100) && (*offp <= 0x700)) {
+		mask = __BITS(14,0);
+		tag = rmixl_tag_to_ecfg(tag);	/* convert to ECFG format */
+		bst = sc->sc_pcie_ecfg_memt;
+		ba = rcp->rc_pcie_ecfg_pbase;
+		ba += (tag & ~mask);
+		*offp += (tag & mask);
+		if (ba != ecfg_oba) {
+			size = (bus_size_t)(mask + 1);
+			if (ecfg_oba != -1)
+				bus_space_unmap(bst, ecfg_bsh, size);
+			err = bus_space_map(bst, ba, size, 0, &ecfg_bsh);
+			if (err != 0) {
+#ifdef DEBUH
+				panic("%s: bus_space_map err %d, ECFG space",
+					__func__, err);	/* XXX */
+#endif
+				return -1;
+			}
+			ecfg_oba = ba;
+		}
+		bsh = ecfg_bsh;
+	} else  {
+#ifdef DEBUG
+		panic("%s: offset %#x: unknown", __func__, *offp);
+#endif
+		return -1;
+	}
+
+	*bstp = bst;
+	*bshp = bsh;
+
+	return 0;
+}
+
 pcireg_t
 rmixl_pcie_conf_read(void *v, pcitag_t tag, int offset)
 {
 	struct rmixl_pcie_softc *sc = v;
-	bus_addr_t ba;
-	vaddr_t va;
+	static bus_space_handle_t bsh;
+	bus_space_tag_t bst;
 	pcireg_t rv;
 	uint64_t cfg0;
 	u_int s;
 
 	PCI_CONF_LOCK(s);
-	cfg0 = rmixl_cache_err_dis();
 
-	/*
-	 * base bus addr depends on offset
-	 */
-	if ((offset >= 0) && ( offset < 0x100)) {
-		ba = sc->sc_pcie_cfg_pbase;
-	} else if ((offset >= 0x100) && (offset <= 0x700)) {
-		ba = sc->sc_pcie_ecfg_pbase;
-		if (ba == -1)
-			return -1;
-	} else  {
-		panic("%s: offset %#x: unknown", __func__, offset);
-	}
-	ba += (tag + offset);
-	va = (vaddr_t)RMIXL_PCI_VADDR(ba);
-	rv = RMIXL_PCI_READ(va);
-	if (rmixl_cache_err_check() != 0) {
+	if (rmixl_pcie_conf_setup(sc, tag, &offset, &bst, &bsh) == 0) {
+		cfg0 = rmixl_cache_err_dis();
+		rv = bus_space_read_4(bst, bsh, (bus_size_t)offset);
+		if (rmixl_cache_err_check() != 0) {
 #ifdef DIAGNOSTIC
-		int bus, dev, fun;
+			int bus, dev, fun;
 
-		rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
-		printf("%s: %d/%d/%d, offset %#x: bad address\n",
-			__func__, bus, dev, fun, offset);
+			rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
+			printf("%s: %d/%d/%d, offset %#x: bad address\n",
+				__func__, bus, dev, fun, offset);
 #endif
-		rv = (pcireg_t) -1;
+			rv = (pcireg_t) -1;
+		}
+		rmixl_cache_err_restore(cfg0);
+	} else {
+		rv = -1;
 	}
 
-	rmixl_cache_err_restore(cfg0);
 	PCI_CONF_UNLOCK(s);
 	return rv;
 }
@@ -853,41 +944,28 @@
 rmixl_pcie_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
 {
 	struct rmixl_pcie_softc *sc = v;
-	bus_addr_t ba;
-	vaddr_t va;
+	static bus_space_handle_t bsh;
+	bus_space_tag_t bst;
 	uint64_t cfg0;
 	u_int s;
 
 	PCI_CONF_LOCK(s);
-	cfg0 = rmixl_cache_err_dis();
 
-	/*
-	 * base bus addr depends on offset
-	 */
-	if ((offset >= 0) && ( offset < 0x100)) {
-		ba = sc->sc_pcie_cfg_pbase;
-	} else if ((offset >= 0x100) && (offset <= 0x700)) {
-		ba = sc->sc_pcie_ecfg_pbase;
-		if (ba == -1)
-			panic("%s: offset %#x: PCIe ECFG space not connfigured",
-				__func__, offset);
-	} else  {
-		panic("%s: offset %#x: unknown", __func__, offset);
-	}
-	ba += (tag + offset);
-	va = (vaddr_t)RMIXL_PCI_VADDR(ba);
-	RMIXL_PCI_WRITE(ba, val);
+	if (rmixl_pcie_conf_setup(sc, tag, &offset, &bst, &bsh) == 0) {
+		cfg0 = rmixl_cache_err_dis();
+		bus_space_write_4(bst, bsh, (bus_size_t)offset, val);
+		if (rmixl_cache_err_check() != 0) {
 #ifdef DIAGNOSTIC
-	if (rmixl_cache_err_check() != 0) {
-		int bus, dev, fun;
+			int bus, dev, fun;
 
-		rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
-		printf("%s: %d/%d/%d, offset %#x: bad address\n",
-			__func__, bus, dev, fun, offset);
-	}
+			rmixl_pcie_decompose_tag(v, tag, &bus, &dev, &fun);
+			printf("%s: %d/%d/%d, offset %#x: bad address\n",
+				__func__, bus, dev, fun, offset);
 #endif
+		}
+		rmixl_cache_err_restore(cfg0);
+	}
 
-	rmixl_cache_err_restore(cfg0);
 	PCI_CONF_UNLOCK(s);
 }
 

Index: src/sys/arch/mips/rmi/rmixl_pcievar.h
diff -u src/sys/arch/mips/rmi/rmixl_pcievar.h:1.1.2.1 src/sys/arch/mips/rmi/rmixl_pcievar.h:1.1.2.2
--- src/sys/arch/mips/rmi/rmixl_pcievar.h:1.1.2.1	Mon Nov  9 10:17:06 2009
+++ src/sys/arch/mips/rmi/rmixl_pcievar.h	Sun Nov 15 23:11:06 2009
@@ -1,4 +1,4 @@
-/*      $NetBSD: rmixl_pcievar.h,v 1.1.2.1 2009/11/09 10:17:06 cliff Exp $	*/
+/*      $NetBSD: rmixl_pcievar.h,v 1.1.2.2 2009/11/15 23:11:06 cliff Exp $	*/
 
 #ifndef _MIPS_RMI_PCIE_VAR_H_
 #define _MIPS_RMI_PCIE_VAR_H_
@@ -25,8 +25,8 @@
 struct rmixl_pcie_softc {
 	device_t                	sc_dev;
 	struct mips_pci_chipset 	sc_pci_chipset;
-	bus_addr_t              	sc_pcie_cfg_pbase;
-	bus_addr_t              	sc_pcie_ecfg_pbase;
+	bus_space_tag_t              	sc_pcie_cfg_memt;
+	bus_space_tag_t              	sc_pcie_ecfg_memt;
 	bus_dma_tag_t			sc_29bit_dmat;
 	bus_dma_tag_t			sc_32bit_dmat;
 	bus_dma_tag_t			sc_64bit_dmat;

Reply via email to