Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86 Provide an x86 implementation of pci_chipset_ta...



details:   https://anonhg.NetBSD.org/src/rev/ff9bb5798e04
branches:  trunk
changeset: 754362:ff9bb5798e04
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Wed Apr 28 21:27:14 2010 +0000

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

diffstat:

 sys/arch/x86/include/pci_machdep_common.h |   30 +-------
 sys/arch/x86/pci/pci_intr_machdep.c       |   28 ++++---
 sys/arch/x86/pci/pci_machdep.c            |  106 ++++++++++++++++++++++++++---
 3 files changed, 111 insertions(+), 53 deletions(-)

diffs (truncated from 301 to 300 lines):

diff -r af3c9103c138 -r ff9bb5798e04 sys/arch/x86/include/pci_machdep_common.h
--- a/sys/arch/x86/include/pci_machdep_common.h Wed Apr 28 21:15:47 2010 +0000
+++ b/sys/arch/x86/include/pci_machdep_common.h Wed Apr 28 21:27:14 2010 +0000
@@ -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;
 };
 
 /*
diff -r af3c9103c138 -r ff9bb5798e04 sys/arch/x86/pci/pci_intr_machdep.c
--- a/sys/arch/x86/pci/pci_intr_machdep.c       Wed Apr 28 21:15:47 2010 +0000
+++ b/sys/arch/x86/pci/pci_intr_machdep.c       Wed Apr 28 21:27:14 2010 +0000
@@ -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) {
diff -r af3c9103c138 -r ff9bb5798e04 sys/arch/x86/pci/pci_machdep.c
--- a/sys/arch/x86/pci/pci_machdep.c    Wed Apr 28 21:15:47 2010 +0000
+++ b/sys/arch/x86/pci/pci_machdep.c    Wed Apr 28 21:27:14 2010 +0000
@@ -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;



Home | Main Index | Thread Index | Old Index