pci.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id: pci_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
00027 
00028 *****************************************************************************************/
00029 
00030 #include <pci/pci.h>
00031 #include <sys/io.h>
00032 #include <ubixos/types.h>
00033 #include <lib/kprintf.h>
00034 
00035 const struct {
00036   uInt8 baseClass;
00037   uInt8 subClass;
00038   uInt8 interface;
00039   const char* name;
00040   } pciClasses[] = {
00041     { 0x00, 0x00, 0x00, "Undefined" },
00042     { 0x00, 0x01, 0x00, "VGA" },
00043 
00044     { 0x01, 0x00, 0x00, "SCSI" },
00045     { 0x01, 0x01, 0x00, "IDE" },
00046     { 0x01, 0x01, 0x8A, "IDE" },
00047     { 0x01, 0x02, 0x00, "Floppy" },
00048     { 0x01, 0x03, 0x00, "IPI" },
00049     { 0x01, 0x04, 0x00, "RAID" },
00050     { 0x01, 0x80, 0x00, "Other" },
00051 
00052     { 0x02, 0x00, 0x00, "Ethernet" },
00053     { 0x02, 0x01, 0x00, "Token Ring" },
00054     { 0x02, 0x02, 0x00, "FDDI" },
00055     { 0x02, 0x03, 0x00, "ATM" },
00056     { 0x02, 0x04, 0x00, "ISDN" },
00057     { 0x02, 0x80, 0x00, "Other" },
00058 
00059     { 0x03, 0x00, 0x00, "VGA" },
00060     { 0x03, 0x00, 0x01, "VGA+8514" },
00061     { 0x03, 0x01, 0x00, "XGA" },
00062     { 0x03, 0x02, 0x00, "3D" },
00063     { 0x03, 0x80, 0x00, "VGA Other" },
00064 
00065     { 0x04, 0x00, 0x00, "Video" },
00066     { 0x04, 0x01, 0x00, "Audio" },
00067     { 0x04, 0x02, 0x00, "Telephony" },
00068     { 0x04, 0x80, 0x00, "Other" },
00069 
00070     { 0x05, 0x00, 0x00, "RAM" },
00071     { 0x05, 0x01, 0x00, "Flash" },
00072     { 0x05, 0x80, 0x00, "Other" },
00073         
00074     { 0x06, 0x00, 0x00, "PCI to HOST" },
00075     { 0x06, 0x01, 0x00, "PCI to ISA" },
00076     { 0x06, 0x02, 0x00, "PCI to EISA" },
00077     { 0x06, 0x03, 0x00, "PCI to MCA" },
00078     { 0x06, 0x04, 0x00, "PCI to PCI" },
00079     { 0x06, 0x04, 0x01, "PCI to PCI (Subtractive Decode)" },
00080     { 0x06, 0x05, 0x00, "PCI to PCMCIA" },
00081     { 0x06, 0x06, 0x00, "PCI to NuBUS" },
00082     { 0x06, 0x07, 0x00, "PCI to Cardbus" },
00083     { 0x06, 0x08, 0x00, "PCI to RACEway" },
00084     { 0x06, 0x09, 0x00, "PCI to PCI" },
00085     { 0x06, 0x0A, 0x00, "PCI to InfiBand" },
00086     { 0x06, 0x80, 0x00, "PCI to Other" },
00087 
00088     { 0x07, 0x00, 0x00, "Serial" },
00089     { 0x07, 0x00, 0x01, "Serial - 16450" },
00090     { 0x07, 0x00, 0x02, "Serial - 16550" },
00091     { 0x07, 0x00, 0x03, "Serial - 16650" },
00092     { 0x07, 0x00, 0x04, "Serial - 16750" },
00093     { 0x07, 0x00, 0x05, "Serial - 16850" },
00094     { 0x07, 0x00, 0x06, "Serial - 16950" },
00095     { 0x07, 0x01, 0x00, "Parallel" },
00096     { 0x07, 0x01, 0x01, "Parallel - BiDir" },
00097     { 0x07, 0x01, 0x02, "Parallel - ECP" },
00098     { 0x07, 0x01, 0x03, "Parallel - IEEE1284" },
00099     { 0x07, 0x01, 0xFE, "Parallel - IEEE1284 Target" },
00100     { 0x07, 0x02, 0x00, "Multiport Serial" },
00101     { 0x07, 0x03, 0x00, "Hayes Compatible Modem" },
00102     { 0x07, 0x03, 0x01, "Hayes Compatible Modem, 16450" },
00103     { 0x07, 0x03, 0x02, "Hayes Compatible Modem, 16550" },
00104     { 0x07, 0x03, 0x03, "Hayes Compatible Modem, 16650" },
00105     { 0x07, 0x03, 0x04, "Hayes Compatible Modem, 16750" },
00106     { 0x07, 0x80, 0x00, "Other" },
00107 
00108     { 0x08, 0x00, 0x00, "PIC" },
00109     { 0x08, 0x00, 0x01, "ISA PIC" },
00110     { 0x08, 0x00, 0x02, "EISA PIC" },
00111     { 0x08, 0x00, 0x10, "I/O APIC" },
00112     { 0x08, 0x00, 0x20, "I/O(x) APIC" },
00113     { 0x08, 0x01, 0x00, "DMA" },
00114     { 0x08, 0x01, 0x01, "ISA DMA" },
00115     { 0x08, 0x01, 0x02, "EISA DMA" },
00116     { 0x08, 0x02, 0x00, "Timer" },
00117     { 0x08, 0x02, 0x01, "ISA Timer" },
00118     { 0x08, 0x02, 0x02, "EISA Timer" },
00119     { 0x08, 0x03, 0x00, "RTC" },
00120     { 0x08, 0x03, 0x00, "ISA RTC" },
00121     { 0x08, 0x03, 0x00, "Hot-Plug" },
00122     { 0x08, 0x80, 0x00, "Other" },
00123 
00124     { 0x09, 0x00, 0x00, "Keyboard" },
00125     { 0x09, 0x01, 0x00, "Pen" },
00126     { 0x09, 0x02, 0x00, "Mouse" },
00127     { 0x09, 0x03, 0x00, "Scanner" },
00128     { 0x09, 0x04, 0x00, "Game Port" },
00129     { 0x09, 0x80, 0x00, "Other" },
00130 
00131     { 0x0a, 0x00, 0x00, "Generic" },
00132     { 0x0a, 0x80, 0x00, "Other" },
00133 
00134     { 0x0b, 0x00, 0x00, "386" },
00135     { 0x0b, 0x01, 0x00, "486" },
00136     { 0x0b, 0x02, 0x00, "Pentium" },
00137     { 0x0b, 0x03, 0x00, "PentiumPro" },
00138     { 0x0b, 0x10, 0x00, "DEC Alpha" },
00139     { 0x0b, 0x20, 0x00, "PowerPC" },
00140     { 0x0b, 0x30, 0x00, "MIPS" },
00141     { 0x0b, 0x40, 0x00, "Coprocessor" },
00142     { 0x0b, 0x80, 0x00, "Other" },
00143 
00144     { 0x0c, 0x00, 0x00, "FireWire" },
00145     { 0x0c, 0x00, 0x10, "OHCI FireWire" },
00146     { 0x0c, 0x01, 0x00, "Access.bus" },
00147     { 0x0c, 0x02, 0x00, "SSA" },
00148     { 0x0c, 0x03, 0x00, "USB (UHCI)" },
00149     { 0x0c, 0x03, 0x10, "USB (OHCI)" },
00150     { 0x0c, 0x03, 0x80, "USB" },
00151     { 0x0c, 0x03, 0xFE, "USB Device" },
00152     { 0x0c, 0x04, 0x00, "Fiber" },
00153     { 0x0c, 0x05, 0x00, "SMBus Controller" },
00154     { 0x0c, 0x06, 0x00, "InfiniBand" },
00155     { 0x0c, 0x80, 0x00, "Other" },
00156 
00157     { 0x0d, 0x00, 0x00, "iRDA" },
00158     { 0x0d, 0x01, 0x00, "Consumer IR" },
00159     { 0x0d, 0x10, 0x00, "RF" },
00160     { 0x0d, 0x80, 0x00, "Other" },
00161 
00162     { 0x0e, 0x00, 0x00, "I2O" },
00163     { 0x0e, 0x80, 0x00, "Other" },
00164 
00165     { 0x0f, 0x01, 0x00, "TV" },
00166     { 0x0f, 0x02, 0x00, "Audio" },
00167     { 0x0f, 0x03, 0x00, "Voice" },
00168     { 0x0f, 0x04, 0x00, "Data" },
00169     { 0x0f, 0x80, 0x00, "Other" },
00170 
00171     { 0x10, 0x00, 0x00, "Network" },
00172     { 0x10, 0x10, 0x00, "Entertainment" },
00173     { 0x10, 0x80, 0x00, "Other" },
00174 
00175     { 0x11, 0x00, 0x00, "DPIO Modules" },
00176     { 0x11, 0x01, 0x00, "Performance Counters" },
00177     { 0x11, 0x10, 0x00, "Comm Sync, Time+Frequency Measurement" },
00178     { 0x11, 0x80, 0x00, "Other" },       
00179     
00180   };
00181 
00182 uInt32 pciRead(int bus,int dev,int func,int reg,int bytes) {
00183   uInt16 base;
00184 
00185   union {
00186     struct confadd c;
00187     uInt32 n;
00188     } u;
00189 
00190   u.n = 0;
00191   u.c.enable = 1;
00192   u.c.rsvd = 0;
00193   u.c.bus = bus;
00194   u.c.dev = dev;
00195   u.c.func = func;
00196   u.c.reg = reg & 0xFC;
00197   
00198   outportDWord(0xCF8, u.n);
00199 
00200   base = 0xCFC + (reg & 0x03);
00201 
00202   switch(bytes){
00203     case 1: return(inportByte(base));
00204     case 2: return(inportWord(base));
00205     case 4: return(inportDWord(base));
00206     default: return 0;
00207     }
00208   }
00209 
00210 void pciWrite(int bus,int dev,int func,int reg,uInt32 v,int bytes) {
00211   uInt16 base;
00212 
00213   union {
00214     struct confadd c;
00215     uInt32 n;
00216     } u;
00217 
00218   u.n = 0;
00219   u.c.enable = 1;
00220   u.c.rsvd = 0;
00221   u.c.bus = bus;
00222   u.c.dev = dev;
00223   u.c.func = func;
00224   u.c.reg = reg & 0xFC;
00225 
00226   base = 0xCFC + (reg & 0x03);
00227   outportDWord(0xCF8, u.n);
00228   switch(bytes){
00229     case 1: outportByte(base, (uInt8) v); break;
00230     case 2: outportWord(base, (uInt16) v); break;
00231     case 4: outportDWord(base, v); break;
00232     }
00233   }
00234 
00235 
00236 bool pciProbe(int bus, int dev, int func,struct pciConfig *cfg) {
00237   uInt32 *word = (uInt32 *) cfg;
00238   uInt32 v;
00239   int i;
00240   for(i=0;i<4;i++) {
00241     word[i] = pciRead(bus,dev,func,4*i,4);
00242     }
00243   if(cfg->vendorId == 0xffff) return FALSE;
00244   if(cfg->vendorId == 0x0)    return FALSE; /* Quick Hack */
00245 
00246   cfg->bus = bus;
00247   cfg->dev = dev;
00248   cfg->func = func;
00249   cfg->subsysVendor = pciRead(bus, dev, func, 0x2c, 2);
00250   cfg->subsys = pciRead(bus, dev, func, 0x2e, 2);
00251   kprintf("Device Info: /bus/pci/%d/%d/%d\n",bus,dev,func);
00252   kprintf("  * Vendor: %X   Device: %X  Class/SubClass/Interface %X/%X/%X\n",cfg->vendorId,cfg->deviceId,cfg->baseClass,cfg->subClass,cfg->interface);
00253   kprintf("  * Status: %X  Command: %X  BIST/Type/Lat/CLS: %X/%X/%X/%X\n",cfg->status, cfg->command, cfg->bist, cfg->headerType,cfg->latencyTimer, cfg->cacheLineSize);
00254   switch(cfg->headerType & 0x7F){
00255     case 0: /* normal device */
00256       for(i=0;i<6;i++) {
00257       v = pciRead(bus,dev,func,i*4 + 0x10, 4);
00258       if(v) {
00259         int v2;
00260         pciWrite(bus,dev,func,i*4 + 0x10, 0xffffffff, 4);
00261         v2 = pciRead(bus,dev,func,i*4+0x10, 4) & 0xfffffff0;
00262         pciWrite(bus,dev,func,i*4 + 0x10, v, 4);
00263         v2 = 1 + ~v2;
00264         if(v & 1) {
00265           cfg->base[i] = v & 0xffff;
00266           cfg->size[i] = v2 & 0xffff;
00267           }
00268         else {
00269           cfg->base[i] = v;
00270           cfg->size[i] = v2;
00271           }
00272         }
00273       else {
00274         cfg->base[i] = 0;
00275         cfg->size[i] = 0;
00276         }
00277       }
00278       v = pciRead(bus,dev,func,0x3c,1);
00279       cfg->irq = (v == 0xff ? 0 : v);
00280       break;
00281     case 1:
00282       kprintf("  * PCI <-> PCI Bridge\n");
00283       break;
00284     default:
00285       kprintf("  * Unknown Header Type\n");
00286       break;
00287     }
00288 
00289   return(TRUE);
00290   }
00291 
00292 int pci_init() {
00293   uInt16 bus,dev,func;
00294   int i = 0x0;
00295   struct pciConfig pcfg;
00296   for (bus = 0x0; bus < 0x2; bus++) { /* 255 */
00297     for (dev = 0; dev < 32; dev++) {
00298       for (func = 0; func < 8; func++) {
00299         if (pciProbe(bus, dev, func, &pcfg) == TRUE) {
00300           /* kprintf("  * Vendor: %X   Device: %X  Class/SubClass/Interface %X/%X/%X\n",pcfg.vendorId,pcfg.deviceId,pcfg.baseClass,pcfg.subClass,pcfg.interface); */
00301           for (i=0x0;i<countof(pciClasses);i++) {
00302             if (pcfg.baseClass == pciClasses[i].baseClass && pcfg.subClass == pciClasses[i].subClass && pcfg.interface == pciClasses[i].interface) {
00303               kprintf("PCI Device: %s @ IRQ: 0x%X\n",pciClasses[i].name,pcfg.irq);
00304               break;
00305               }
00306             }
00307           }
00308         }
00309       }
00310     }
00311   return(0x0);
00312   }
00313 
00314 /***
00315  $Log: pci_8c-source.html,v $
00315  Revision 1.7  2006/12/15 17:47:06  reddawg
00315  Updates
00315 
00316  Revision 1.1.1.1  2006/06/01 12:46:16  reddawg
00317  ubix2
00318 
00319  Revision 1.2  2005/10/12 00:13:37  reddawg
00320  Removed
00321 
00322  Revision 1.1.1.1  2005/09/26 17:24:36  reddawg
00323  no message
00324 
00325  Revision 1.4  2004/08/20 17:49:13  reddawg
00326  Tiny fixens
00327 
00328  Revision 1.3  2004/08/20 16:49:11  reddawg
00329  PCI Updates - More to follow as PCI system gets revamped
00330 
00331  Revision 1.2  2004/07/09 11:58:19  reddawg
00332  Updating Driver Routines
00333 
00334  Revision 1.1.1.1  2004/04/15 12:07:16  reddawg
00335  UbixOS v1.0
00336 
00337  Revision 1.5  2004/04/13 16:36:33  reddawg
00338  Changed our copyright, it is all now under a BSD-Style license
00339 
00340  END
00341  ***/

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7