Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:50

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  This file was based on the powerpc.
0007  */
0008 
0009 /*
0010  *  COPYRIGHT (c) 1989-2012.
0011  *  On-Line Applications Research Corporation (OAR).
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #include <rtems.h>
0036 #include <bsp.h>
0037 
0038 #include <bsp/pci.h>
0039 #include <bsp/irq.h>
0040 #include <rtems/bspIo.h>
0041 #include <rtems/endian.h>
0042 
0043 /*
0044  * DEFINES
0045  */
0046 
0047 #undef SHOW_PCI_SETTING
0048 
0049 // #define DEBUG_PCI 1
0050 
0051 /* allow for overriding these definitions */
0052 #ifndef PCI_CONFIG_ADDR
0053 #define PCI_CONFIG_ADDR      0xcf8
0054 #endif
0055 #ifndef PCI_CONFIG_DATA
0056 #define PCI_CONFIG_DATA      0xcfc
0057 #endif
0058 
0059 /* define a shortcut */
0060 #define pci  BSP_pci_configuration
0061 
0062 #ifndef  PCI_CONFIG_ADDR_VAL
0063 #define  PCI_CONFIG_ADDR_VAL(bus, slot, funcion, offset) \
0064      (0x80000000|((bus)<<16)|(PCI_DEVFN((slot),(function))<<8)|(((offset)&~3)))
0065 #endif
0066 
0067 #ifdef DEBUG_PCI
0068   #define JPRINTK(fmt, ...) printk("%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
0069 #else
0070   #define JPRINTK(fmt, ...)
0071 #endif
0072 
0073 #ifndef  PCI_CONFIG_WR_ADDR
0074 #define  PCI_CONFIG_WR_ADDR( addr, val ) out_le32((uint32_t)(addr), (val))
0075 #endif
0076 
0077 /* Bit encode for PCI_CONFIG_HEADER_TYPE register */
0078 #define PCI_CONFIG_SET_ADDR(addr, bus, slot,function,offset) \
0079   PCI_CONFIG_WR_ADDR( \
0080     (addr), \
0081     PCI_CONFIG_ADDR_VAL((bus), (slot), (function), (offset))\
0082   )
0083 
0084 #define PRINT_MSG() \
0085   printk("pci : Device %d:0x%02x:%d routed to interrupt_line %d\n", \
0086     pbus, pslot, pfun, int_name )
0087 
0088 /*
0089  * STRUCTURES
0090  */
0091 
0092 /*
0093  * PROTOTYPES
0094  */
0095 void print_bars(
0096   unsigned char slot,
0097   unsigned char func
0098 );
0099 int direct_pci_read_config_byte(
0100   unsigned char bus,
0101   unsigned char slot,
0102   unsigned char function,
0103   unsigned char offset,
0104   uint8_t      *val
0105 );
0106 int direct_pci_read_config_word(
0107   unsigned char bus,
0108   unsigned char slot,
0109   unsigned char function,
0110   unsigned char offset,
0111   uint16_t     *val
0112 );
0113 int direct_pci_read_config_dword(
0114   unsigned char bus,
0115   unsigned char slot,
0116   unsigned char function,
0117   unsigned char offset,
0118   uint32_t     *val
0119 );
0120 int direct_pci_write_config_byte(
0121   unsigned char bus,
0122   unsigned char slot,
0123   unsigned char function,
0124   unsigned char offset,
0125   uint8_t       val
0126 );
0127 int direct_pci_write_config_word(
0128   unsigned char bus,
0129   unsigned char slot,
0130   unsigned char function,
0131   unsigned char offset,
0132   uint16_t      val
0133 );
0134 int direct_pci_write_config_dword(
0135   unsigned char bus,
0136   unsigned char slot,
0137   unsigned char function,
0138   unsigned char offset,
0139   uint32_t      val
0140 );
0141 int test_intname(
0142   const struct _int_map *row,
0143   int pbus,
0144   int pslot,
0145   int pfun,
0146   int int_pin,
0147   int int_name
0148 );
0149 void pci_memory_enable(
0150   unsigned char bus,
0151   unsigned char slot,
0152   unsigned char function
0153 );
0154 void pci_io_enable(
0155   unsigned char bus,
0156   unsigned char slot,
0157   unsigned char function
0158 );
0159 void pci_busmaster_enable(
0160   unsigned char bus,
0161   unsigned char slot,
0162   unsigned char function
0163 );
0164 
0165 /*
0166  * GLOBALS
0167  */
0168 unsigned char ucMaxPCIBus;
0169 const pci_config_access_functions pci_indirect_functions = {
0170   indirect_pci_read_config_byte,
0171   indirect_pci_read_config_word,
0172   indirect_pci_read_config_dword,
0173   indirect_pci_write_config_byte,
0174   indirect_pci_write_config_word,
0175   indirect_pci_write_config_dword
0176 };
0177 
0178 rtems_pci_config_t BSP_pci_configuration = {
0179   (volatile unsigned char*)PCI_CONFIG_ADDR,
0180   (volatile unsigned char*)PCI_CONFIG_DATA,
0181   &pci_indirect_functions
0182 };
0183 
0184 const pci_config_access_functions pci_direct_functions = {
0185   direct_pci_read_config_byte,
0186   direct_pci_read_config_word,
0187   direct_pci_read_config_dword,
0188   direct_pci_write_config_byte,
0189   direct_pci_write_config_word,
0190   direct_pci_write_config_dword
0191 };
0192 
0193 /*
0194  * PCI specific accesses.  Note these are made on 32 bit
0195  * boundries.
0196  */
0197 void pci_out_32(uint32_t base, uint32_t addr, uint32_t val)
0198 {
0199   volatile uint32_t *ptr;
0200 
0201   ptr = (volatile uint32_t *) (base + addr);
0202   *ptr = val;
0203 
0204   JPRINTK( "%p data: 0x%x\n", ptr, val);
0205 }
0206 
0207 void pci_out_le32(uint32_t base, uint32_t addr, uint32_t val)
0208 {
0209   volatile uint32_t *ptr;
0210   uint32_t           data = 0;
0211 
0212   ptr = (volatile uint32_t *) (base + addr);
0213   rtems_uint32_to_little_endian( val, (uint8_t *) &data);
0214   *ptr = data;
0215 
0216   JPRINTK( "%p data: 0x%x\n", ptr, data);
0217 }
0218 
0219 uint8_t pci_in_8( uint32_t base, uint32_t addr ) {
0220   volatile uint32_t *ptr;
0221   uint8_t            val;
0222   uint32_t           data;
0223 
0224   data = addr/4;
0225   ptr = (volatile uint32_t *) (base + (data*4));
0226   data = *ptr;
0227 
0228   switch ( addr%4 ) {
0229     case 0: val = (data & 0x000000ff) >>  0; break;
0230     case 1: val = (data & 0x0000ff00) >>  8; break;
0231     case 2: val = (data & 0x00ff0000) >> 16; break;
0232     case 3: val = (data & 0xff000000) >> 24; break;
0233    }
0234 
0235    JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
0236 
0237   return val;
0238 }
0239 
0240 int16_t pci_in_le16( uint32_t base, uint32_t addr ) {
0241   volatile uint32_t *ptr;
0242   uint16_t           val;
0243   uint16_t           rval;
0244   uint32_t           data;
0245 
0246   data = addr/4;
0247   ptr = (volatile uint32_t *) (base + (data*4));
0248   data = *ptr;
0249   if ( addr%4 == 0 )
0250     val = data & 0xffff;
0251   else
0252     val = (data>>16) & 0xffff;
0253 
0254   rval = rtems_uint16_from_little_endian( (uint8_t *) &val);
0255   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, data);
0256   return rval;
0257 }
0258 
0259 int16_t pci_in_16( uint32_t base, uint32_t addr ) {
0260   volatile uint32_t *ptr;
0261   uint16_t           val;
0262   uint32_t           data;
0263 
0264   data = addr/4;
0265   ptr = (volatile uint32_t *) (base + (data*4));
0266   data = *ptr;
0267   if ( addr%4 == 0 )
0268     val = data & 0xffff;
0269   else
0270     val = (data>>16) & 0xffff;
0271 
0272   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, data);
0273   return val;
0274 }
0275 
0276 uint32_t pci_in_32( uint32_t base, uint32_t addr ) {
0277   volatile uint32_t *ptr;
0278   uint32_t           val;
0279 
0280   ptr = (volatile uint32_t *) (base + addr);
0281   val = *ptr;
0282 
0283   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, val, val);
0284   return val;
0285 }
0286 uint32_t pci_in_le32( uint32_t base, uint32_t addr ) {
0287   volatile uint32_t *ptr;
0288   uint32_t           val;
0289   uint32_t           rval;
0290 
0291   ptr = (volatile uint32_t *) (base + addr);
0292   val = *ptr;
0293   rval = rtems_uint32_from_little_endian( (uint8_t *) &val);
0294 
0295   JPRINTK( "0x%x data: 0x%x raw: 0x%x\n", ptr, rval, val);
0296   return rval;
0297 }
0298 
0299 void pci_out_8( uint32_t base, uint32_t addr, uint8_t val ) {
0300   volatile uint32_t *ptr;
0301 
0302   ptr = (volatile uint32_t *) (base + addr);
0303   JPRINTK("Address: %p\n", ptr);
0304   *ptr = val;
0305   JPRINTK( "%p data: 0x%x\n", ptr, val);
0306 }
0307 
0308 void pci_out_le16( uint32_t base, uint32_t addr, uint16_t val ) {
0309   volatile uint32_t *ptr;
0310   uint32_t           out_data;
0311   uint32_t           data;
0312 
0313   ptr = (volatile uint32_t *) (base + (addr & ~0x3));
0314   data = *ptr;
0315   if ( addr%4 == 0 )
0316     out_data = (data & 0xffff0000) | val;
0317   else
0318     out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
0319   rtems_uint32_to_little_endian( out_data, (uint8_t *) &data);
0320   *ptr = data;
0321 
0322   JPRINTK( "0x%x data: 0x%x\n", ptr, data);
0323 }
0324 
0325 void pci_out_16( uint32_t base, uint32_t addr, uint16_t val ) {
0326   volatile uint32_t *ptr;
0327   uint32_t           out_data;
0328   uint32_t           data;
0329 
0330   ptr = (volatile uint32_t *) (base + (addr & ~0x3));
0331   data = *ptr;
0332   if ( addr%4 == 0 )
0333     out_data = (data & 0xffff0000) | val;
0334   else
0335     out_data = ((val << 16)&0xffff0000) | (data & 0xffff);
0336   *ptr = out_data;
0337 
0338   JPRINTK( "0x%x data: 0x%x\n", ptr, out_data);
0339 }
0340 
0341 /*
0342  * INDIRECT PCI CONFIGURATION ACCESSES
0343  */
0344 int indirect_pci_read_config_byte(
0345   unsigned char bus,
0346   unsigned char slot,
0347   unsigned char function,
0348   unsigned char offset,
0349   uint8_t       *val
0350 ) {
0351 
0352   JPRINTK("==>\n");
0353   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0354   *val = in_8((uint32_t) (pci.pci_config_data +  (offset&3)) );
0355   JPRINTK("\n\n");
0356 
0357   return PCIBIOS_SUCCESSFUL;
0358 }
0359 
0360 int indirect_pci_read_config_word(
0361   unsigned char bus,
0362   unsigned char slot,
0363   unsigned char function,
0364   unsigned char offset,
0365   uint16_t      *val
0366 ) {
0367 
0368   JPRINTK("==>\n");
0369 
0370   *val = 0xffff;
0371   if (offset&1)
0372     return PCIBIOS_BAD_REGISTER_NUMBER;
0373 
0374   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0375   *val = in_16((uint32_t)(pci.pci_config_data + (offset&3)));
0376 
0377   JPRINTK("\n\n");
0378 
0379   return PCIBIOS_SUCCESSFUL;
0380 }
0381 
0382 int indirect_pci_read_config_dword(
0383   unsigned char bus,
0384   unsigned char slot,
0385   unsigned char function,
0386   unsigned char offset,
0387   uint32_t *val
0388 ) {
0389   uint32_t v;
0390   JPRINTK("==>\n");
0391 
0392   *val = 0xffffffff;
0393   if (offset&3)
0394     return PCIBIOS_BAD_REGISTER_NUMBER;
0395   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0396   v = in_32( (uint32_t) pci.pci_config_data );
0397   *val = v;
0398    if ( offset == 0x0b )
0399      JPRINTK( "%x:%x %x ==> 0x%08x, 0x%08x\n", bus, slot, function, v, *val );
0400 
0401   JPRINTK("\n\n");
0402 
0403   return PCIBIOS_SUCCESSFUL;
0404 }
0405 
0406 int indirect_pci_write_config_byte(
0407   unsigned char bus,
0408   unsigned char slot,
0409   unsigned char function,
0410   unsigned char offset,
0411   uint8_t       val
0412 ) {
0413 
0414   JPRINTK("==>\n");
0415 
0416   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0417   out_8( (uint32_t) (pci.pci_config_data + (offset&3)), val);
0418 
0419   JPRINTK("\n\n");
0420 
0421   return PCIBIOS_SUCCESSFUL;
0422 }
0423 
0424 int indirect_pci_write_config_word(
0425   unsigned char bus,
0426   unsigned char slot,
0427   unsigned char function,
0428   unsigned char offset,
0429   uint16_t      val
0430 ) {
0431 
0432   JPRINTK("==>\n");
0433 
0434   if (offset&1)
0435     return PCIBIOS_BAD_REGISTER_NUMBER;
0436 
0437   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0438   out_16((uint32_t)(pci.pci_config_data + (offset&3)), val);
0439 
0440   JPRINTK("\n\n");
0441 
0442   return PCIBIOS_SUCCESSFUL;
0443 }
0444 
0445 int indirect_pci_write_config_dword(
0446   unsigned char bus,
0447   unsigned char slot,
0448   unsigned char function,
0449   unsigned char offset,
0450   uint32_t      val
0451 ) {
0452 
0453   if (offset&3)
0454     return PCIBIOS_BAD_REGISTER_NUMBER;
0455 
0456   JPRINTK("==>\n");
0457 
0458   /*
0459    * The Base Address Registers get accessed big endian while the
0460    * other registers are little endian.
0461    */
0462   PCI_CONFIG_SET_ADDR(pci.pci_config_addr, bus, slot, function, offset);
0463   if ( bus == 0 && slot == 0x0b &&
0464        (offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) ) {
0465     out_32((uint32_t)pci.pci_config_data, val);
0466   } else {
0467     out_le32((uint32_t)pci.pci_config_data, val);
0468   }
0469 
0470   JPRINTK("\n\n");
0471 
0472   return PCIBIOS_SUCCESSFUL;
0473 }
0474 
0475 /*
0476  * DIRECT CONFIGUREATION ACCESSES.
0477  */
0478 int direct_pci_read_config_byte(
0479   unsigned char bus,
0480   unsigned char slot,
0481   unsigned char function,
0482   unsigned char offset,
0483   uint8_t      *val
0484 ) {
0485   if (bus != 0 || (1<<slot & 0xff8007fe)) {
0486     *val=0xff;
0487      return PCIBIOS_DEVICE_NOT_FOUND;
0488   }
0489 
0490   JPRINTK("==>\n");
0491 
0492   *val=in_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1)
0493    + (function<<8) + offset));
0494 
0495   JPRINTK("\n\n");
0496 
0497   return PCIBIOS_SUCCESSFUL;
0498 }
0499 
0500 int direct_pci_read_config_word(
0501   unsigned char bus,
0502   unsigned char slot,
0503   unsigned char function,
0504   unsigned char offset,
0505   uint16_t     *val
0506 ) {
0507   *val = 0xffff;
0508   if (offset&1)
0509     return PCIBIOS_BAD_REGISTER_NUMBER;
0510   if (bus != 0 || (1<<slot & 0xff8007fe))
0511      return PCIBIOS_DEVICE_NOT_FOUND;
0512 
0513   JPRINTK("==>\n");
0514 
0515   *val=in_le16((uint32_t)
0516       (pci.pci_config_data + ((1<<slot)&~1)
0517        + (function<<8) + offset));
0518 
0519   JPRINTK("\n\n");
0520 
0521   return PCIBIOS_SUCCESSFUL;
0522 }
0523 
0524 int direct_pci_read_config_dword(
0525   unsigned char bus,
0526   unsigned char slot,
0527   unsigned char function,
0528   unsigned char offset,
0529   uint32_t     *val
0530 ) {
0531   *val = 0xffffffff;
0532   if (offset&3)
0533     return PCIBIOS_BAD_REGISTER_NUMBER;
0534   if (bus != 0 || (1<<slot & 0xff8007fe))
0535      return PCIBIOS_DEVICE_NOT_FOUND;
0536 
0537   JPRINTK("==>\n");
0538 
0539   *val=in_le32((uint32_t)(pci.pci_config_data +
0540     ((1<<slot)&~1)+(function<<8) + offset));
0541 
0542   JPRINTK("\n\n");
0543 
0544   return PCIBIOS_SUCCESSFUL;
0545 }
0546 
0547 int direct_pci_write_config_byte(
0548   unsigned char bus,
0549   unsigned char slot,
0550   unsigned char function,
0551   unsigned char offset,
0552   uint8_t       val
0553 ) {
0554   if (bus != 0 || (1<<slot & 0xff8007fe))
0555      return PCIBIOS_DEVICE_NOT_FOUND;
0556 
0557   JPRINTK("==>\n");
0558 
0559   out_8((uint32_t) (pci.pci_config_data + ((1<<slot)&~1) +
0560     (function<<8) + offset),
0561      val);
0562 
0563   JPRINTK("\n\n");
0564 
0565   return PCIBIOS_SUCCESSFUL;
0566 }
0567 
0568 int direct_pci_write_config_word(
0569   unsigned char bus,
0570   unsigned char slot,
0571   unsigned char function,
0572   unsigned char offset,
0573   uint16_t      val
0574 ) {
0575   if (offset&1)
0576     return PCIBIOS_BAD_REGISTER_NUMBER;
0577   if (bus != 0 || (1<<slot & 0xff8007fe))
0578      return PCIBIOS_DEVICE_NOT_FOUND;
0579 
0580   JPRINTK("==>\n");
0581 
0582   out_le16((uint32_t)(pci.pci_config_data + ((1<<slot)&~1) +
0583     (function<<8) + offset),
0584     val);
0585 
0586   JPRINTK("\n\n");
0587 
0588   return PCIBIOS_SUCCESSFUL;
0589 }
0590 
0591 int direct_pci_write_config_dword(
0592   unsigned char bus,
0593   unsigned char slot,
0594   unsigned char function,
0595   unsigned char offset,
0596   uint32_t      val
0597 ) {
0598   if (offset&3)
0599     return PCIBIOS_BAD_REGISTER_NUMBER;
0600   if (bus != 0 || (1<<slot & 0xff8007fe))
0601      return PCIBIOS_DEVICE_NOT_FOUND;
0602 
0603   JPRINTK("direct_pci_write_config_dword==>\n");
0604 
0605   out_le32((uint32_t)
0606      (pci.pci_config_data + ((1<<slot)&~1)
0607    + (function<<8) + offset),
0608      val);
0609 
0610   JPRINTK("\n\n");
0611 
0612   return PCIBIOS_SUCCESSFUL;
0613 }
0614 
0615 /*
0616  * Validate a test interrupt name and print a warning if its not one of
0617  * the names defined in the routing record.
0618  */
0619 int test_intname(
0620   const struct _int_map *row,
0621   int pbus,
0622   int pslot,
0623   int pfun,
0624   int int_pin,
0625   int int_name
0626 ) {
0627   int j, k;
0628   int _nopin= -1, _noname= -1;
0629 
0630   for (j=0; row->pin_route[j].pin > -1; j++) {
0631     if ( row->pin_route[j].pin == int_pin ) {
0632    _nopin = 0;
0633 
0634    for (k=0; k<4 && row->pin_route[j].int_name[k] > -1; k++ ) {
0635      if ( row->pin_route[j].int_name[k] == int_name ) {
0636        _noname=0; break;
0637      }
0638    }
0639    break;
0640     }
0641   }
0642 
0643    if( _nopin  )
0644    {
0645       printk(
0646         "pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n",
0647         pbus,
0648         pslot,
0649         pfun,
0650         int_pin
0651       );
0652       return -1;
0653    }
0654    else
0655    {
0656      if( _noname ) {
0657        unsigned char v = row->pin_route[j].int_name[0];
0658        printk(
0659          "pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ",
0660          pbus,
0661          pslot,
0662          pfun,
0663          int_name
0664        );
0665        if ((row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 !=
0666            (v = row->pin_route[j].int_name[0])
0667           ) {
0668          printk("OVERRIDING with %d from fixup table\n", v);
0669          pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v);
0670        } else {
0671         printk("using it anyway\n");
0672        }
0673      }
0674    }
0675    return 0;
0676 }
0677 
0678 int FindPCIbridge( int mybus, struct pcibridge *pb )
0679 {
0680   int          pbus, pslot;
0681   uint8_t      bussec, buspri;
0682   uint16_t     devid, vendorid, dclass;
0683 
0684   for(pbus=0; pbus< pci_bus_count(); pbus++) {
0685     for(pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
0686       pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
0687       if ( devid == 0xffff ) continue;
0688 
0689       pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &vendorid);
0690       if ( vendorid == 0xffff ) continue;
0691 
0692       pci_read_config_word(pbus, pslot, 0, PCI_CLASS_DEVICE, &dclass);
0693 
0694       if ( dclass == PCI_CLASS_BRIDGE_PCI ) {
0695         pci_read_config_byte(pbus, pslot, 0, PCI_PRIMARY_BUS,    &buspri);
0696         pci_read_config_byte(pbus, pslot, 0, PCI_SECONDARY_BUS,  &bussec);
0697 
0698         #ifdef SHOW_PCI_SETTING
0699           JPRINTK(
0700             "pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ",
0701             pbus,
0702             pslot,
0703             mybus,
0704             buspri,
0705             bussec
0706           );
0707         #endif
0708         if ( bussec == mybus ) {
0709           #ifdef SHOW_PCI_SETTING
0710             JPRINTK("match\n");
0711           #endif
0712           /* found our nearest bridge going towards the root */
0713           pb->bus = pbus;
0714           pb->slot = pslot;
0715           return 0;
0716         }
0717         #ifdef SHOW_PCI_SETTING
0718           JPRINTK("no match\n");
0719         #endif
0720       }
0721 
0722      }
0723    }
0724    return -1;
0725 }
0726 
0727 void FixupPCI( const struct _int_map *bspmap, int (*swizzler)(int,int) )
0728 {
0729   unsigned char cvalue;
0730   uint16_t      devid;
0731   int           ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns;
0732 
0733   /*
0734    * If the device has a non-zero INTERRUPT_PIN, assign a bsp-specific
0735    * INTERRUPT_NAME if one isn't already in place.  Then, drivers can
0736    * trivially use INTERRUPT_NAME to hook up with devices.
0737    */
0738 
0739   for (pbus=0; pbus< pci_bus_count(); pbus++) {
0740     for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
0741       pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
0742       if ( devid == 0xffff ) continue;
0743 
0744       /* got a device */
0745       pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue);
0746       nfuns = cvalue & PCI_HEADER_TYPE_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1;
0747       for (pfun=0; pfun< nfuns; pfun++) {
0748 
0749         pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid);
0750         if( devid == 0xffff ) continue;
0751 
0752         pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue);
0753         int_pin = cvalue;
0754 
0755         pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue);
0756         int_name = cvalue;
0757 
0758         #ifdef SHOW_PCI_SETTING
0759         {
0760           unsigned short cmd,stat;
0761           unsigned char  lat, seclat, csize;
0762 
0763           pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd );
0764           pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat );
0765           pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat );
0766           pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat);
0767           pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize );
0768 
0769           JPRINTK(
0770             "pci : device %d:0x%02x:%d  cmd %04X, stat %04X, latency %d, "
0771             " sec_latency %d, clsize %d\n",
0772             pbus,
0773             pslot,
0774             pfun,
0775             cmd,
0776             stat,
0777             lat,
0778             seclat,
0779             csize
0780           );
0781         }
0782         #endif
0783 
0784         if ( int_pin > 0 ) {
0785           ismatch = 0;
0786 
0787           /*
0788            * first run thru the bspmap table and see if we have an
0789            * explicit configuration
0790            */
0791           for (i=0; bspmap[i].bus > -1; i++) {
0792             if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
0793               ismatch = -1;
0794 
0795               /* we have a record in the table that gives specific
0796                * pins and interrupts for devices in this slot
0797                */
0798               if ( int_name == 255 ) {
0799 
0800                 /* find the vector associated with whatever pin the
0801                  * device gives us
0802                  */
0803                 for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ){
0804                   if ( bspmap[i].pin_route[j].pin == int_pin ) {
0805                     int_name = bspmap[i].pin_route[j].int_name[0];
0806                     break;
0807                   }
0808                 }
0809 
0810                 if ( int_name == -1 ) {
0811                   printk(
0812                     "pci : Unable to resolve device %d:0x%02x:%d w/ "
0813                     "swizzled int pin %i to an interrupt_line.\n",
0814                     pbus,
0815                     pslot,
0816                     pfun,
0817                     int_pin
0818                   );
0819                 } else {
0820                   PRINT_MSG();
0821                   pci_write_config_byte(
0822                     pbus,
0823                     pslot,
0824                     pfun,
0825                     PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue)
0826                   );
0827                 }
0828               } else {
0829                 test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name);
0830               }
0831               break;
0832             }
0833           }
0834 
0835           if ( !ismatch ) {
0836             /*
0837              * no match, which means we're on a bus someplace.  Work
0838              * backwards from it to one of our defined busses,
0839              * swizzling thru each bridge on the way.
0840              */
0841 
0842             /* keep pbus, pslot pointed to the device being
0843              * configured while we track down the bridges using
0844              * tbus,tslot.  We keep searching the routing table because
0845              * we may end up finding our bridge in it
0846              */
0847 
0848             int tbus= pbus, tslot= pslot;
0849             for (;;) {
0850               for (i=0; bspmap[i].bus > -1; i++) {
0851                 if ( bspmap[i].bus == tbus &&
0852                     (bspmap[i].slot == tslot || bspmap[i].slot == -1))
0853                 {
0854                   ismatch = -1;
0855 
0856                   /* found a record for this bus, so swizzle the
0857                    * int_pin which we then use to find the
0858                    * interrupt_name.
0859                    */
0860                   if ( int_name == 255 ) {
0861                     /*
0862                      * FIXME.  I can't believe this little hack
0863                      * is right.  It does not yield an error in
0864                      * convienently simple situations.
0865                      */
0866                     if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
0867 
0868                     /*
0869                      * int_pin points to the interrupt channel
0870                      * this card ends up delivering interrupts
0871                      * on.  Find the int_name servicing it.
0872                      */
0873                     for (int_name=-1, j=0;
0874                          bspmap[i].pin_route[j].pin > -1;
0875                          j++)
0876                     {
0877                       if ( bspmap[i].pin_route[j].pin == int_pin ) {
0878                         int_name = bspmap[i].pin_route[j].int_name[0];
0879                         break;
0880                       }
0881                     }
0882 
0883                     if ( int_name == -1 ) {
0884                       printk(
0885                         "pci : Unable to resolve device %d:0x%02x:%d w/ "
0886                         "swizzled int pin %i to an interrupt_line.\n",
0887                         pbus,
0888                         pslot,
0889                         pfun,
0890                         int_pin
0891                       );
0892                     } else {
0893                       PRINT_MSG();
0894                       pci_write_config_byte(pbus,pslot,pfun,
0895                       PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
0896                     }
0897                   } else {
0898                     test_intname(
0899                       &bspmap[i],
0900                       pbus,
0901                       pslot,
0902                       pfun,
0903                       int_pin,
0904                       int_name
0905                     );
0906                   }
0907                   goto donesearch;
0908                 }
0909               }
0910               if ( !ismatch ) {
0911                 struct pcibridge   pb;
0912 
0913                 /*
0914                  * Haven't found our bus in the int map, so work
0915                  * upwards thru the bridges till we find it.
0916                  */
0917                 if ( FindPCIbridge( tbus, &pb )== 0 ) {
0918                   int_pin = (*swizzler)(tslot,int_pin);
0919 
0920                   /* our next bridge up is on pb.bus, pb.slot- now
0921                    * instead of pointing to the device we're
0922                    * trying to configure, we move from bridge to
0923                    * bridge.
0924                    */
0925                   tbus = pb.bus;
0926                   tslot = pb.slot;
0927                 } else {
0928                   printk(
0929                     "pci : No bridge from bus %i towards root found\n",
0930                     tbus
0931                   );
0932                   goto donesearch;
0933                 }
0934               }
0935             }
0936           }
0937 
0938           donesearch:
0939           if ( !ismatch && int_pin != 0 && int_name == 255 ) {
0940             printk(
0941               "pci : Unable to match device %d:0x%02x:%d with an int "
0942               "routing table entry\n",
0943               pbus,
0944               pslot,
0945               pfun
0946             );
0947           }
0948         }
0949       }
0950     }
0951   }
0952 }
0953 
0954 void print_bars(
0955   unsigned char slot,
0956   unsigned char func
0957 )
0958 {
0959   uint32_t addr;
0960 
0961   printk( "*** BARs for slot=%d func=%d\n", slot, func );
0962   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_0, &addr);
0963   printk("***    PCI DEVICE BAR0: 0x%lx\n", addr);
0964   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_1, &addr);
0965   printk("***    PCI DEVICE BAR1: 0x%lx\n", addr);
0966   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_2, &addr);
0967   printk("***    PCI DEVICE BAR2: 0x%lx\n", addr);
0968   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_3, &addr);
0969   printk("***    PCI DEVICE BAR3: 0x%lx\n", addr);
0970   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_4, &addr);
0971   printk("***    PCI DEVICE BAR4: 0x%lx\n", addr);
0972   pci_read_config_dword (0, slot, func, PCI_BASE_ADDRESS_5, &addr);
0973   printk("***    PCI DEVICE BAR5: 0x%lx\n", addr);
0974 }
0975 
0976 void pci_memory_enable(
0977   unsigned char bus,
0978   unsigned char slot,
0979   unsigned char function
0980 )
0981 {
0982   uint16_t data;
0983 
0984   pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
0985   data |= PCI_COMMAND_MEMORY;
0986   pci_write_config_word(0, slot, function, PCI_COMMAND, data );
0987   pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
0988 }
0989 
0990 void pci_io_enable(
0991   unsigned char bus,
0992   unsigned char slot,
0993   unsigned char function
0994 )
0995 {
0996   uint16_t data;
0997 
0998   pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
0999   data |= PCI_COMMAND_IO;
1000   pci_write_config_word(0, slot, function, PCI_COMMAND, data );
1001 }
1002 
1003 void pci_busmaster_enable(
1004   unsigned char bus,
1005   unsigned char slot,
1006   unsigned char function
1007 )
1008 {
1009   uint16_t data;
1010 
1011   pci_read_config_word(0, slot, function, PCI_COMMAND, &data);
1012   data |= PCI_COMMAND_MASTER;
1013   pci_write_config_word(0, slot, function, PCI_COMMAND, data );
1014 }
1015 
1016 /*
1017  * This routine determines the maximum bus number in the system
1018  */
1019 int pci_initialize(void)
1020 {
1021   unsigned char slot, func, ucNumFuncs;
1022   unsigned char ucHeader;
1023   uint32_t class;
1024   uint32_t device;
1025   uint32_t vendor;
1026 
1027   /*
1028    * Initialize GT_PCI0IOREMAP
1029    */
1030   pci_out_32( BSP_PCI_BASE_ADDRESS, 0xf0, 0 );
1031 
1032   /*
1033    *  According to Linux and BSD sources, this is needed to cover up a bug
1034    *  in some versions of the hardware.
1035    */
1036   out_le32( PCI_CONFIG_ADDR, 0x80000020 );
1037   out_le32( PCI_CONFIG_DATA, 0x1be00000 );
1038 
1039   /*
1040    * Scan PCI bus 0 looking for the known Network devices and
1041    * initializing the PCI for them.
1042    */
1043   for (slot=0;slot<PCI_MAX_DEVICES;slot++) {
1044     pci_read_config_dword(0, slot, 0, PCI_VENDOR_ID, &device);
1045     if (device == PCI_INVALID_VENDORDEVICEID) {
1046       /* This slot is empty */
1047       continue;
1048     }
1049 
1050     pci_read_config_byte(0, slot, 0, PCI_HEADER_TYPE, &ucHeader);
1051     if (ucHeader & PCI_HEADER_TYPE_MULTI_FUNCTION)  {
1052       ucNumFuncs = PCI_MAX_FUNCTIONS;
1053     } else {
1054       ucNumFuncs=1;
1055     }
1056     for (func=0;func<ucNumFuncs;func++) {
1057       pci_read_config_dword(0, slot, func, PCI_VENDOR_ID, &device);
1058        if (device==PCI_INVALID_VENDORDEVICEID) {
1059         /* This slot/function is empty */
1060         continue;
1061       }
1062       vendor = device & 0xffff;
1063       device = device >> 16;
1064 
1065       /* This slot/function has a device fitted. */
1066       pci_read_config_dword(0, slot, func, PCI_CLASS_REVISION, &class);
1067       class >>= 16;
1068 
1069       // printk( "FOUND DEVICE 0x%04x/0x%04x class 0x%x\n",
1070       //          vendor, device, class );
1071       if (class == PCI_CLASS_NETWORK_ETHERNET) {
1072         JPRINTK("FOUND ETHERNET\n");
1073 
1074         pci_write_config_byte(
1075             0, slot, func, PCI_INTERRUPT_LINE, MALTA_IRQ_ETHERNET );
1076 
1077         /*
1078          * Rewrite BAR1 for RTL8139
1079          */
1080         if ( vendor == PCI_VENDOR_ID_REALTEK &&
1081              device == PCI_DEVICE_ID_REALTEK_8139 ) {
1082 
1083           pci_memory_enable(0, slot, func);
1084           pci_io_enable(0, slot, func);
1085           pci_busmaster_enable(0, slot, func);
1086 
1087           // BAR0: IO at 0x0000_1001
1088           pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001001);
1089 
1090           // BAR1: Memory at 0x1203_1000
1091           pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12031000);
1092 
1093           // print_bars( slot, func );
1094        } else if ( vendor == PCI_VENDOR_ID_AMD &&
1095                    device == PCI_DEVICE_ID_AMD_LANCE ) {
1096          print_bars( slot, func );
1097          pci_memory_enable(0, slot, func);
1098          pci_io_enable(0, slot, func);
1099          pci_busmaster_enable(0, slot, func);
1100 
1101          // BAR0: IO at 0x0000_1041
1102          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_0, 0x00001041);
1103 
1104          // BAR1: Memory at 0x1201_1020
1105          pci_write_config_dword(0, slot, func, PCI_BASE_ADDRESS_1, 0x12011020);
1106          print_bars( slot, func );
1107        }
1108 
1109       }
1110     }
1111   }
1112   return PCIB_ERR_SUCCESS;
1113 }
1114 
1115 /*
1116  * Return the number of PCI busses in the system
1117  */
1118 unsigned char pci_bus_count(void)
1119 {
1120   return (ucMaxPCIBus+1);
1121 }