Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/pci PCI Configuration Mechanisms #1 and #2 are ...
details: https://anonhg.NetBSD.org/src/rev/a321c2e990f9
branches: trunk
changeset: 752137:a321c2e990f9
user: dyoung <dyoung%NetBSD.org@localhost>
date: Tue Feb 16 19:29:40 2010 +0000
description:
PCI Configuration Mechanisms #1 and #2 are controlled by two to
three registers. Let us think of the kernel operating the registers
in two steps:
1) Select: enable configuration cycles and select a range of
configuration-space addresses.
2) Access: read or write a word in PCI configuration space.
To make the steps more explicit, extract some helper subroutines
from pci_conf_read(9) and pci_conf_write(9):
pci_conf_selector(tag, reg): from a pcitag_t and a register offset,
create a word that enables configuration cycles and selects a
configuration address range.
pci_conf_select(w): for `w' a word created by pci_conf_selector(),
enable configuration cycles and select the address range indicated
by `w'.
pci_conf_select(0): disable configuration cycles.
pci_conf_port(tag, reg): map a pcitag_t and a register offset to an I/O
port where the configuration access should occur.
While I'm in here, change the panic(9) calls to panic("%s: ...",
__func__) instead of hard-coding a subroutine name.
diffstat:
sys/arch/x86/pci/pci_machdep.c | 115 ++++++++++++++++++++++++----------------
1 files changed, 70 insertions(+), 45 deletions(-)
diffs (183 lines):
diff -r c5bd9271cb86 -r a321c2e990f9 sys/arch/x86/pci/pci_machdep.c
--- a/sys/arch/x86/pci/pci_machdep.c Tue Feb 16 19:21:30 2010 +0000
+++ b/sys/arch/x86/pci/pci_machdep.c Tue Feb 16 19:29:40 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.c,v 1.38 2010/02/16 00:03:47 dyoung Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.39 2010/02/16 19:29:40 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.38 2010/02/16 00:03:47 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.39 2010/02/16 19:29:40 dyoung Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -135,7 +135,6 @@
void *arg;
};
-
__cpu_simple_lock_t pci_conf_lock = __SIMPLELOCK_UNLOCKED;
#define PCI_CONF_LOCK(s) \
@@ -244,6 +243,59 @@
};
#endif
+static uint32_t
+pci_conf_selector(pcitag_t tag, int reg)
+{
+ static const pcitag_t mode2_mask = {
+ .mode2 = {
+ .enable = 0xff
+ , .forward = 0xff
+ }
+ };
+
+ switch (pci_mode) {
+ case 1:
+ return tag.mode1 | reg;
+ case 2:
+ return tag.mode1 & mode2_mask.mode1;
+ default:
+ panic("%s: mode not configured", __func__);
+ }
+}
+
+static unsigned int
+pci_conf_port(pcitag_t tag, int reg)
+{
+ switch (pci_mode) {
+ case 1:
+ return PCI_MODE1_DATA_REG;
+ case 2:
+ return tag.mode2.port | reg;
+ default:
+ panic("%s: mode not configured", __func__);
+ }
+}
+
+static void
+pci_conf_select(uint32_t addr)
+{
+ pcitag_t tag;
+
+ switch (pci_mode) {
+ case 1:
+ outl(PCI_MODE1_ADDRESS_REG, addr);
+ return;
+ case 2:
+ tag.mode1 = addr;
+ outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
+ if (tag.mode2.enable != 0)
+ outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
+ return;
+ default:
+ panic("%s: mode not configured", __func__);
+ }
+}
+
void
pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
{
@@ -295,21 +347,21 @@
switch (pci_mode) {
case 1:
if (bus >= 256 || device >= 32 || function >= 8)
- panic("pci_make_tag: bad request");
+ panic("%s: bad request", __func__);
tag.mode1 = PCI_MODE1_ENABLE |
(bus << 16) | (device << 11) | (function << 8);
return tag;
case 2:
if (bus >= 256 || device >= 16 || function >= 8)
- panic("pci_make_tag: bad request");
+ panic("%s: bad request", __func__);
tag.mode2.port = 0xc000 | (device << 8);
tag.mode2.enable = 0xf0 | (function << 1);
tag.mode2.forward = bus;
return tag;
default:
- panic("pci_make_tag: mode not configured");
+ panic("%s: mode not configured", __func__);
}
}
@@ -336,7 +388,7 @@
*fp = (tag.mode2.enable >> 1) & 0x7;
return;
default:
- panic("pci_decompose_tag: mode not configured");
+ panic("%s: mode not configured", __func__);
}
}
@@ -357,25 +409,12 @@
}
#endif
- switch (pci_mode) {
- case 1:
- PCI_CONF_LOCK(s);
- outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
- data = inl(PCI_MODE1_DATA_REG);
- outl(PCI_MODE1_ADDRESS_REG, 0);
- PCI_CONF_UNLOCK(s);
- return data;
- case 2:
- PCI_CONF_LOCK(s);
- outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
- outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
- data = inl(tag.mode2.port | reg);
- outb(PCI_MODE2_ENABLE_REG, 0);
- PCI_CONF_UNLOCK(s);
- return data;
- default:
- panic("pci_conf_read: mode not configured");
- }
+ PCI_CONF_LOCK(s);
+ pci_conf_select(pci_conf_selector(tag, reg));
+ data = inl(pci_conf_port(tag, reg));
+ pci_conf_select(0);
+ PCI_CONF_UNLOCK(s);
+ return data;
}
void
@@ -394,25 +433,11 @@
}
#endif
- switch (pci_mode) {
- case 1:
- PCI_CONF_LOCK(s);
- outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
- outl(PCI_MODE1_DATA_REG, data);
- outl(PCI_MODE1_ADDRESS_REG, 0);
- PCI_CONF_UNLOCK(s);
- return;
- case 2:
- PCI_CONF_LOCK(s);
- outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
- outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
- outl(tag.mode2.port | reg, data);
- outb(PCI_MODE2_ENABLE_REG, 0);
- PCI_CONF_UNLOCK(s);
- return;
- default:
- panic("pci_conf_write: mode not configured");
- }
+ PCI_CONF_LOCK(s);
+ pci_conf_select(pci_conf_selector(tag, reg));
+ outl(pci_conf_port(tag, reg), data);
+ pci_conf_select(0);
+ PCI_CONF_UNLOCK(s);
}
void
Home |
Main Index |
Thread Index |
Old Index