Module Name:    src
Committed By:   dyoung
Date:           Wed Apr 28 21:27:14 UTC 2010

Modified Files:
        src/sys/arch/x86/include: pci_machdep_common.h
        src/sys/arch/x86/pci: pci_intr_machdep.c pci_machdep.c

Log Message:
Provide an x86 implementation of pci_chipset_tag_create(9) and
pci_chipset_tag_destroy(9).


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x86/include/pci_machdep_common.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/x86/pci/pci_intr_machdep.c
cvs rdiff -u -r1.42 -r1.43 src/sys/arch/x86/pci/pci_machdep.c

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/x86/include/pci_machdep_common.h
diff -u src/sys/arch/x86/include/pci_machdep_common.h:1.2 src/sys/arch/x86/include/pci_machdep_common.h:1.3
--- src/sys/arch/x86/include/pci_machdep_common.h:1.2	Sat Mar 20 00:02:59 2010
+++ src/sys/arch/x86/include/pci_machdep_common.h	Wed Apr 28 21:27:14 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_machdep_common.h,v 1.2 2010/03/20 00:02:59 dyoung Exp $	*/
+/*	$NetBSD: pci_machdep_common.h,v 1.3 2010/04/28 21:27:14 dyoung Exp $	*/
 
 /*
  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
@@ -74,31 +74,9 @@
 
 struct pci_chipset_tag {
 	pci_chipset_tag_t pc_super;
-	pcireg_t (*pc_conf_read)(pci_chipset_tag_t, pcitag_t, int);
-
-	void (*pc_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
-
-#if 0
-	int (*pc_find_rom)(struct pci_attach_args *, bus_space_tag_t,
-	    bus_space_handle_t, int, bus_space_handle_t *, bus_space_size_t *);
-#endif
-
-	int (*pc_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
-
-	const char *(*pc_intr_string)(pci_chipset_tag_t, pci_intr_handle_t);
-
-	const struct evcnt *(*pc_intr_evcnt)(pci_chipset_tag_t,
-	    pci_intr_handle_t);
-
-	void *(*pc_intr_establish)(pci_chipset_tag_t, pci_intr_handle_t, int,
-	    int (*)(void *), void *);
-
-	void (*pc_intr_disestablish)(pci_chipset_tag_t, void *);
-
-	pcitag_t (*pc_make_tag)(pci_chipset_tag_t, int, int, int);
-
-	void (*pc_decompose_tag)(pci_chipset_tag_t, pcitag_t,
-	    int *, int *, int *);
+	uint64_t pc_present;
+	const struct pci_overrides *pc_ov;
+	void *pc_ctx;
 };
 
 /*

Index: src/sys/arch/x86/pci/pci_intr_machdep.c
diff -u src/sys/arch/x86/pci/pci_intr_machdep.c:1.16 src/sys/arch/x86/pci/pci_intr_machdep.c:1.17
--- src/sys/arch/x86/pci/pci_intr_machdep.c:1.16	Sun Mar 14 20:19:06 2010
+++ src/sys/arch/x86/pci/pci_intr_machdep.c	Wed Apr 28 21:27:14 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_intr_machdep.c,v 1.16 2010/03/14 20:19:06 dyoung Exp $	*/
+/*	$NetBSD: pci_intr_machdep.c,v 1.17 2010/04/28 21:27:14 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2009 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.16 2010/03/14 20:19:06 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_intr_machdep.c,v 1.17 2010/04/28 21:27:14 dyoung Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -122,8 +122,8 @@
 #endif
 
 	if ((pc = pa->pa_pc) != NULL) {
-		if (pc->pc_intr_map != NULL)
-			return (*pc->pc_intr_map)(pa, ihp);
+		if ((pc->pc_present & PCI_OVERRIDE_INTR_MAP) != 0)
+			return (*pc->pc_ov->ov_intr_map)(pc->pc_ctx, pa, ihp);
 		if (pc->pc_super != NULL) {
 			struct pci_attach_args paclone = *pa;
 			paclone.pa_pc = pc->pc_super;
@@ -217,9 +217,10 @@
 const char *
 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
 {
+
 	if (pc != NULL) {
-		if (pc->pc_intr_string != NULL)
-			return (*pc->pc_intr_string)(pc, ih);
+		if ((pc->pc_present & PCI_OVERRIDE_INTR_STRING) != 0)
+			return (*pc->pc_ov->ov_intr_string)(pc->pc_ctx, pc, ih);
 		if (pc->pc_super != NULL)
 			return pci_intr_string(pc->pc_super, ih);
 	}
@@ -233,8 +234,8 @@
 {
 
 	if (pc != NULL) {
-		if (pc->pc_intr_evcnt != NULL)
-			return (*pc->pc_intr_evcnt)(pc, ih);
+		if ((pc->pc_present & PCI_OVERRIDE_INTR_EVCNT) != 0)
+			return (*pc->pc_ov->ov_intr_evcnt)(pc->pc_ctx, pc, ih);
 		if (pc->pc_super != NULL)
 			return pci_intr_evcnt(pc->pc_super, ih);
 	}
@@ -274,9 +275,9 @@
 	bool mpsafe;
 
 	if (pc != NULL) {
-		if (pc->pc_intr_establish != NULL) {
-			return (*pc->pc_intr_establish)(pc, ih, level, func,
-			    arg);
+		if ((pc->pc_present & PCI_OVERRIDE_INTR_ESTABLISH) != 0) {
+			return (*pc->pc_ov->ov_intr_establish)(pc->pc_ctx,
+			    pc, ih, level, func, arg);
 		}
 		if (pc->pc_super != NULL) {
 			return pci_intr_establish(pc->pc_super, ih, level, func,
@@ -313,8 +314,9 @@
 {
 
 	if (pc != NULL) {
-		if (pc->pc_intr_disestablish != NULL) {
-			(*pc->pc_intr_disestablish)(pc, cookie);
+		if ((pc->pc_present & PCI_OVERRIDE_INTR_ESTABLISH) != 0) {
+			(*pc->pc_ov->ov_intr_disestablish)(pc->pc_ctx,
+			    pc, cookie);
 			return;
 		}
 		if (pc->pc_super != NULL) {

Index: src/sys/arch/x86/pci/pci_machdep.c
diff -u src/sys/arch/x86/pci/pci_machdep.c:1.42 src/sys/arch/x86/pci/pci_machdep.c:1.43
--- src/sys/arch/x86/pci/pci_machdep.c:1.42	Tue Apr 27 23:33:14 2010
+++ src/sys/arch/x86/pci/pci_machdep.c	Wed Apr 28 21:27:14 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci_machdep.c,v 1.42 2010/04/27 23:33:14 dyoung Exp $	*/
+/*	$NetBSD: pci_machdep.c,v 1.43 2010/04/28 21:27:14 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.42 2010/04/27 23:33:14 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.43 2010/04/28 21:27:14 dyoung Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -83,6 +83,7 @@
 #include <sys/device.h>
 #include <sys/bus.h>
 #include <sys/cpu.h>
+#include <sys/kmem.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -95,6 +96,7 @@
 #include <dev/isa/isavar.h>
 #include <dev/pci/pcivar.h>
 #include <dev/pci/pcireg.h>
+#include <dev/pci/pccbbreg.h>
 #include <dev/pci/pcidevs.h>
 
 #include "acpica.h"
@@ -401,8 +403,10 @@
 	pcitag_t tag;
 
 	if (pc != NULL) {
-		if (pc->pc_make_tag != NULL)
-			return (*pc->pc_make_tag)(pc, bus, device, function);
+		if ((pc->pc_present & PCI_OVERRIDE_MAKE_TAG) != 0) {
+			return (*pc->pc_ov->ov_make_tag)(pc->pc_ctx,
+			    pc, bus, device, function);
+		}
 		if (pc->pc_super != NULL) {
 			return pci_make_tag(pc->pc_super, bus, device,
 			    function);
@@ -436,8 +440,9 @@
 {
 
 	if (pc != NULL) {
-		if (pc->pc_decompose_tag != NULL) {
-			(*pc->pc_decompose_tag)(pc, tag, bp, dp, fp);
+		if ((pc->pc_present & PCI_OVERRIDE_DECOMPOSE_TAG) != 0) {
+			(*pc->pc_ov->ov_decompose_tag)(pc->pc_ctx,
+			    pc, tag, bp, dp, fp);
 			return;
 		}
 		if (pc->pc_super != NULL) {
@@ -469,8 +474,7 @@
 }
 
 pcireg_t
-pci_conf_read( pci_chipset_tag_t pc, pcitag_t tag,
-    int reg)
+pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
 {
 	pcireg_t data;
 	struct pci_conf_lock ocl;
@@ -478,8 +482,10 @@
 	KASSERT((reg & 0x3) == 0);
 
 	if (pc != NULL) {
-		if (pc->pc_conf_read != NULL)
-			return (*pc->pc_conf_read)(pc, tag, reg);
+		if ((pc->pc_present & PCI_OVERRIDE_CONF_READ) != 0) {
+			return (*pc->pc_ov->ov_conf_read)(pc->pc_ctx,
+			    pc, tag, reg);
+		}
 		if (pc->pc_super != NULL)
 			return pci_conf_read(pc->pc_super, tag, reg);
 	}
@@ -500,16 +506,16 @@
 }
 
 void
-pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg,
-    pcireg_t data)
+pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
 {
 	struct pci_conf_lock ocl;
 
 	KASSERT((reg & 0x3) == 0);
 
 	if (pc != NULL) {
-		if (pc->pc_conf_write != NULL) {
-			(*pc->pc_conf_write)(pc, tag, reg, data);
+		if ((pc->pc_present & PCI_OVERRIDE_CONF_WRITE) != 0) {
+			(*pc->pc_ov->ov_conf_write)(pc->pc_ctx, pc, tag, reg,
+			    data);
 			return;
 		}
 		if (pc->pc_super != NULL) {
@@ -750,3 +756,75 @@
 		(*bridge_hook->func)(pc, tag, bridge_hook->arg);
 	}
 }
+
+static const void *
+bit_to_function_pointer(const struct pci_overrides *ov, uint64_t bit)
+{
+	switch (bit) {
+	case PCI_OVERRIDE_CONF_READ:
+		return ov->ov_conf_read;
+	case PCI_OVERRIDE_CONF_WRITE:
+		return ov->ov_conf_write;
+	case PCI_OVERRIDE_INTR_MAP:
+		return ov->ov_intr_map;
+	case PCI_OVERRIDE_INTR_STRING:
+		return ov->ov_intr_string;
+	case PCI_OVERRIDE_INTR_EVCNT:
+		return ov->ov_intr_evcnt;
+	case PCI_OVERRIDE_INTR_ESTABLISH:
+		return ov->ov_intr_establish;
+	case PCI_OVERRIDE_INTR_DISESTABLISH:
+		return ov->ov_intr_disestablish;
+	case PCI_OVERRIDE_MAKE_TAG:
+		return ov->ov_make_tag;
+	case PCI_OVERRIDE_DECOMPOSE_TAG:
+		return ov->ov_decompose_tag;
+	default:
+		return NULL;
+	}
+}
+
+void
+pci_chipset_tag_destroy(pci_chipset_tag_t pc)
+{
+	kmem_free(pc, sizeof(struct pci_chipset_tag));
+}
+
+int
+pci_chipset_tag_create(pci_chipset_tag_t opc, const uint64_t present,
+    const struct pci_overrides *ov, void *ctx, pci_chipset_tag_t *pcp)
+{
+	uint64_t bit, bits, nbits;
+	pci_chipset_tag_t pc;
+	const void *fp;
+
+	if (ov == NULL || present == 0)
+		return EINVAL;
+
+	pc = kmem_alloc(sizeof(struct pci_chipset_tag), KM_SLEEP);
+
+	if (pc == NULL)
+		return ENOMEM;
+
+	pc->pc_super = opc;
+
+	for (bits = present; bits != 0; bits = nbits) {
+		nbits = bits & (bits - 1);
+		bit = nbits ^ bits;
+		if ((fp = bit_to_function_pointer(ov, bit)) == NULL) {
+			printf("%s: missing bit %" PRIx64 "\n", __func__, bit);
+			goto einval;
+		}
+	}
+
+	pc->pc_ov = ov;
+	pc->pc_present = present;
+	pc->pc_ctx = ctx;
+
+	*pcp = pc;
+
+	return 0;
+einval:
+	kmem_free(pc, sizeof(struct pci_chipset_tag));
+	return EINVAL;
+}

Reply via email to