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