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