Changeset 98afe31 in rtems


Ignore:
Timestamp:
Nov 4, 2005, 3:34:08 AM (14 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
758ee5c
Parents:
cca22863
Message:

2005-11-03 Till Straumann <strauman@…>

  • shared/motorola/motorola.c, shared/pci/detect_raven_bridge.c, shared/pci/pci.c, shared/pci/pci.h, shared/pci/pcifinddevice.c: Several PCI enhancements and fixes: all BSP flavors now use the generic clear_hostbridge_errors() routine (this means that only polling memory probing is possible [see detect_raven_bridge.c for details]). Interrupt fixup routine now supports multi-function devices. Interrupt fixup routine now honours a flag/option so that wrong firmware values can be overridden. Fixed irq routing table for mvme2100 [PMC]. Added irq routing table for mvme2300. Added a BSP_pciScan() routine that executes a user callback on each non-empty slot/fun. Added BSP_pciConfigDump() to display basic config headers.
Location:
c/src/lib/libbsp/powerpc/shared
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/shared/motorola/motorola.c

    rcca22863 r98afe31  
    111111   NULL_INTMAP };
    112112
     113static struct _int_map mvme23xx_intmap[] = {
     114/* Raven Hostbridge; has int_pin == 0
     115   {0,  0, 0, {{0, {-1,-1,-1,-1}},
     116               NULL_PINMAP}},
     117*/
     118
     119/* Winbond PCI/ISA 83c553; has int_pin == 0
     120   {0, 11, 0, {{0, {-1,-1,-1,-1}},
     121               NULL_PINMAP}},
     122*/
     123
     124#if 0 /* Leave as ISA interrupts for now */
     125   {0, 13, PCI_FIXUP_OPT_OVERRIDE_NAME,
     126                        {{1, {11,21,-1,-1,-1}},  /* Universe  ISA/PCI */
     127                        /* strictly speaking, a non-multi function device
     128                         * must only use pin A
     129                         */
     130                         {2, {22,-1,-1,-1,-1}},  /* Universe          */
     131                         {3, {23,-1,-1,-1,-1}},  /* Universe          */
     132                         {4, {24,-1,-1,-1,-1}},  /* Universe          */
     133             NULL_PINMAP}},
     134
     135   {0, 14, PCI_FIXUP_OPT_OVERRIDE_NAME,
     136                        {{1, {10,18,-1,-1}},  /* DEC Tulip enet (ISA/PCI)  */
     137             NULL_PINMAP}},
     138#endif
     139
     140   {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
     141                        {{1, {25,-1,-1,-1}},  /* pci/pmc slot 1   */
     142             {2, {26,-1,-1,-1}},
     143             {3, {27,-1,-1,-1}},
     144             {4, {28,-1,-1,-1}},
     145             NULL_PINMAP}},
     146
     147   {0, 17, PCI_FIXUP_OPT_OVERRIDE_NAME,
     148                        {{1, {28,-1,-1,-1}},  /* pci/pmc slot 2   */ /* orig: 0xf */
     149             {2, {25,-1,-1,-1}},
     150             {3, {26,-1,-1,-1}},
     151             {4, {27,-1,-1,-1}},
     152             NULL_PINMAP}},
     153
     154   NULL_INTMAP };
     155
    113156static struct _int_map mvme2100_intmap[] = {
    114    {0, 0, 0, {{1, {16,-1,-1,-1}}, /* something shows up in slot 0 and OpenPIC */
    115                                   /* 0 is unused.  This hushes the init code. */
    116                NULL_PINMAP}},
    117 
    118    {0, 13, 0, {{1, {23,24,25,26}},  /* PCI INT[A-D]/Universe Lint[0-3] */
     157   {0, 0, 0, {{1, {16,-1,-1,-1}}, /* something shows up in slot 0 and OpenPIC  */
     158                                  /* 0 is unused.  This hushes the init code.  */
     159               NULL_PINMAP}},
     160
     161   {0, 13, 0, {{1, {23,-1,-1,-1}},  /* Universe Lint[0-3]; not quite legal     */
     162               {2, {24,-1,-1,-1}},  /* since the universe is a single-function */
     163               {3, {25,-1,-1,-1}},  /* device. We leave it for info purposes   */
     164               {4, {26,-1,-1,-1}},
    119165               NULL_PINMAP}},
    120166
    121167   {0, 14, 0, {{1, {17,-1,-1,-1}},  /* onboard ethernet */
     168               NULL_PINMAP}},
     169
     170   {0, 16, PCI_FIXUP_OPT_OVERRIDE_NAME,
     171              {{1, {18,-1,-1,-1}},  /* PMC slot; all pins are routed to 18     */
     172               {2, {18,-1,-1,-1}},  /* I give the OVERRIDE option since I had  */
     173               {3, {18,-1,-1,-1}},  /* problems with devices behind a bridge   */
     174               {4, {18,-1,-1,-1}},  /* on a PMC card reading irq line 0...     */
     175               NULL_PINMAP}},
     176
     177   /* FIXME: I don't know how MIP works or what it is; these probably won't work */
     178
     179   {0, -1, PCI_FIXUP_OPT_OVERRIDE_NAME,
     180              {{1, {23,-1,-1,-1}},  /* PCI INT[A-D] expansion */
     181               {2, {24,-1,-1,-1}},
     182               {3, {25,-1,-1,-1}},
     183               {4, {26,-1,-1,-1}},
    122184               NULL_PINMAP}},
    123185
     
    170232  {0x1E0, 0xF7, "MTX w/o Parallel Port", mtx603_intmap, prep_pci_swizzle},
    171233  {0x1E0, 0xF8, "MTX w/ Parallel Port", mtx603_intmap, prep_pci_swizzle},
    172   {0x1E0, 0xF9, "MVME 2300", NULL, NULL},
    173   {0x1E0, 0xFA, "MVME 2300SC/2600", NULL, NULL},
     234  {0x1E0, 0xF9, "MVME 2300", mvme23xx_intmap, prep_pci_swizzle},
     235  {0x1E0, 0xFA, "MVME 2300SC/2600", mvme23xx_intmap, prep_pci_swizzle},
    174236  {0x1E0, 0xFB, "MVME 2600 with MVME712M", NULL, NULL},
    175237  {0x1E0, 0xFC, "MVME 2600/2700 with MVME761", NULL, NULL},
     
    189251  /* figure out what kind of prep workstation we are */
    190252  if ( res->ResidualLength != 0 ) {
    191     if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
     253    if ( !strncmp((char*)res->VitalProductData.PrintableModel,"IBM",3) )
    192254      PREP_type = PREP_IBM;
    193     else if (!strncmp(res->VitalProductData.PrintableModel,
     255    else if (!strncmp((char*)res->VitalProductData.PrintableModel,
    194256                      "Radstone",8)){
    195257      PREP_type = PREP_Radstone;
  • c/src/lib/libbsp/powerpc/shared/pci/detect_raven_bridge.c

    rcca22863 r98afe31  
    2424#define RAVEN_MPIC_MEREN    ((volatile unsigned *)0xfeff0020)
    2525#define RAVEN_MPIC_MERST    ((volatile unsigned *)0xfeff0024)
    26 /* enable machine check on all conditions */
    2726#define MEREN_VAL           0x2f00
    2827
    2928#define pci BSP_pci_configuration
    30 extern unsigned int EUMBBAR;
    3129
    3230extern const pci_config_access_functions pci_direct_functions;
    3331extern const pci_config_access_functions pci_indirect_functions;
     32
    3433
    3534#define PCI_ERR_BITS        0xf900
     
    7978}
    8079
     80#if (defined(mpc8240) || defined(mpc8245))
     81/* FIXME - this should really be in a separate file - the 2100 doesn't
     82 *         have a raven chip so there is no point having 2100 code here
     83 */
     84
     85extern unsigned int EUMBBAR;
     86
    8187void detect_host_bridge()
    8288{
    83 #if (defined(mpc8240) || defined(mpc8245))
    8489  /*
    8590   * If the processor is an 8240 or an 8245 then the PIC is built
     
    9398  pci.pci_config_addr = (volatile unsigned char *) 0xfec00000;
    9499  pci.pci_config_data = (volatile unsigned char *) 0xfee00000;
     100}
    95101
    96102#else
     103
     104#if 0
     105/* Unfortunately, PCI config space access to empty slots generates
     106 * a 'signalled master abort' condition --> we can't really use
     107 * the machine check interrupt for memory probing unless
     108 * we use probing for PCI scanning also (which would make
     109 * all that code either BSP dependent or requiring yet another
     110 * API, sigh...).
     111 * So for the moment, we just don't use MCP on all mvme2xxx
     112 * boards (using the generic, hostbridge-independent 'clear'
     113 * implementation above).
     114 */
     115/*
     116 * enableMCP: whether to enable MCP checkstop / machine check interrupts
     117 *            on the hostbridge and in HID0.
     118 *
     119 *            NOTE: HID0 and MEREN are left alone if this flag is 0
     120 *
     121 * quiet    : be silent
     122 *
     123 * RETURNS  : raven MERST register contents (lowermost 16 bits), 0 if
     124 *            there were no errors
     125 */
     126unsigned long
     127_BSP_clear_hostbridge_errors(int enableMCP, int quiet)
     128{
     129unsigned merst;
     130
     131    merst = in_be32(RAVEN_MPIC_MERST);
     132    /* write back value to clear status */
     133    out_be32(RAVEN_MPIC_MERST, merst);
     134
     135    if (enableMCP) {
     136      if (!quiet)
     137        printk("Enabling MCP generation on hostbridge errors\n");
     138      out_be32(RAVEN_MPIC_MEREN, MEREN_VAL);
     139    } else {
     140      out_be32(RAVEN_MPIC_MEREN, 0);
     141      if ( !quiet && enableMCP ) {
     142        printk("leaving MCP interrupt disabled\n");
     143      }
     144    }
     145    return (merst & 0xffff);
     146}
     147#endif
     148
     149void detect_host_bridge()
     150{
    97151  PPC_DEVICE *hostbridge;
    98152  unsigned int id0;
     
    174228    }
    175229  }
    176 #endif
    177230  if (OpenPIC == (volatile struct OpenPIC *)0) {
    178231    BSP_panic("OpenPic Not found\n");
     
    180233
    181234}
     235
     236#endif
  • c/src/lib/libbsp/powerpc/shared/pci/pci.c

    rcca22863 r98afe31  
    2020 */
    2121
     22#include <rtems.h>
     23#include <bsp.h>
     24
    2225#include <libcpu/io.h>
    2326#include <bsp/pci.h>
     
    279282
    280283#define PRINT_MSG() \
    281   printk("pci : Device %d:%02x routed to interrupt_line %d\n", \
    282     pbus, pslot, int_name )
     284  printk("pci : Device %d:0x%02x:%d routed to interrupt_line %d\n", \
     285    pbus, pslot, pfun, int_name )
    283286
    284287/*
     
    290293  int pbus,
    291294  int pslot,
     295  int pfun,
    292296  int int_pin,
    293297  int int_name
     
    309313  }
    310314
    311   if ( _nopin  ) {
    312     printk("pci : Device %d:%02x supplied a bogus interrupt_pin %d\n",
    313    pbus, pslot, int_pin );
    314     return -1;
    315   } else {
    316     if ( _noname )
    317    printk("pci : Device %d:%02x supplied a suspicious interrupt_line %d,"
    318           " using it anyway\n", pbus, pslot, int_name );
    319   }
    320   return 0;
     315   if( _nopin  )
     316   {
     317      printk("pci : Device %d:0x%02x:%d supplied a bogus interrupt_pin %d\n", pbus, pslot, pfun, int_pin );
     318      return -1;
     319   }
     320   else
     321   {
     322      if( _noname ) {
     323                unsigned char v = row->pin_route[j].int_name[0];
     324                printk("pci : Device %d:0x%02x:%d supplied a suspicious interrupt_line %d, ", pbus, pslot, pfun, int_name );
     325                if ( (row->opts & PCI_FIXUP_OPT_OVERRIDE_NAME) && 255 != (v = row->pin_route[j].int_name[0]) ) {
     326                        printk("OVERRIDING with %d from fixup table\n", v);
     327            pci_write_config_byte(pbus,pslot,pfun,PCI_INTERRUPT_LINE,v);
     328                } else {
     329                printk("using it anyway\n");
     330                }
     331          }
     332   }
     333   return 0;
    321334}
    322335
     
    348361
    349362#if 0
    350          printk("pci : Found bridge at %d:%d, mybus %d, pribus %d, secbus %d ",
     363         printk("pci : Found bridge at %d:0x%02x, mybus %d, pribus %d, secbus %d ",
    351364                 pbus, pslot, mybus, buspri, bussec );
    352365#endif
     
    375388  unsigned char        cvalue;
    376389  uint16_t             devid;
    377   int                  ismatch, i, j, pbus, pslot, int_pin, int_name;
     390  int                  ismatch, i, j, pbus, pslot, pfun, int_pin, int_name, nfuns;
    378391
    379392  /*
     
    384397
    385398  for (pbus=0; pbus< pci_bus_count(); pbus++) {
    386     for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
    387       pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
    388       if ( devid == 0xffff ) continue;
    389 
    390       /* got a device */
    391 
    392       pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_PIN, &cvalue);
    393       int_pin = cvalue;
    394 
    395       pci_read_config_byte( pbus, pslot, 0, PCI_INTERRUPT_LINE, &cvalue);
    396       int_name = cvalue;
    397 
    398       /* printk("pci : device %d:%02x devid %04x, intpin %d, intline  %d\n",
    399          pbus, pslot, devid, int_pin, int_name ); */
     399        for (pslot=0; pslot< PCI_MAX_DEVICES; pslot++) {
     400          pci_read_config_word(pbus, pslot, 0, PCI_DEVICE_ID, &devid);
     401          if ( devid == 0xffff ) continue;
     402
     403          /* got a device */
     404          pci_read_config_byte(pbus, pslot, 0, PCI_HEADER_TYPE, &cvalue);
     405          nfuns = cvalue & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1;
     406
     407          for (pfun=0; pfun< nfuns; pfun++) {
     408                pci_read_config_word(pbus, pslot, pfun, PCI_DEVICE_ID, &devid);
     409                if( devid == 0xffff ) continue;
     410
     411                pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_PIN, &cvalue);
     412                int_pin = cvalue;
     413
     414                pci_read_config_byte( pbus, pslot, pfun, PCI_INTERRUPT_LINE, &cvalue);
     415                int_name = cvalue;
     416
     417                /* printk("pci : device %d:0x%02x:%i devid %04x, intpin %d, intline  %d\n",
     418                   pbus, pslot, pfun, devid, int_pin, int_name ); */
    400419
    401420#if 0
    402       {
    403          unsigned short cmd,stat;
    404          unsigned char  lat, seclat, csize;
    405 
    406          pci_read_config_word(pbus,pslot,0,PCI_COMMAND, &cmd );
    407          pci_read_config_word(pbus,pslot,0,PCI_STATUS, &stat );
    408          pci_read_config_byte(pbus,pslot,0,PCI_LATENCY_TIMER, &lat );
    409          pci_read_config_byte(pbus,pslot,0,PCI_SEC_LATENCY_TIMER, &seclat );
    410          pci_read_config_byte(pbus,pslot,0,PCI_CACHE_LINE_SIZE, &csize );
    411          
    412 
    413          printk("pci : device %d:%02x  cmd %04X, stat %04X, latency %d, "
    414                 " sec_latency %d, clsize %d\n", pbus, pslot, cmd, stat,
    415                 lat, seclat, csize);
    416       }
     421                {
     422                  unsigned short cmd,stat;
     423                  unsigned char  lat, seclat, csize;
     424
     425                  pci_read_config_word(pbus,pslot,pfun,PCI_COMMAND, &cmd );
     426                  pci_read_config_word(pbus,pslot,pfun,PCI_STATUS, &stat );
     427                  pci_read_config_byte(pbus,pslot,pfun,PCI_LATENCY_TIMER, &lat );
     428                  pci_read_config_byte(pbus,pslot,pfun,PCI_SEC_LATENCY_TIMER, &seclat );
     429                  pci_read_config_byte(pbus,pslot,pfun,PCI_CACHE_LINE_SIZE, &csize );
     430
     431
     432                  printk("pci : device %d:0x%02x:%d  cmd %04X, stat %04X, latency %d, "
     433                          " sec_latency %d, clsize %d\n", pbus, pslot, pfun, cmd, stat,
     434                          lat, seclat, csize);
     435                }
    417436#endif
    418437
    419       if ( int_pin > 0 ) {
    420         ismatch = 0;
    421 
    422         /*
    423          * first run thru the bspmap table and see if we have an
    424          * explicit configuration
    425          */
    426         for (i=0; bspmap[i].bus > -1; i++) {
    427           if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
    428             ismatch = -1;
    429             /* we have a record in the table that gives specific
    430              * pins and interrupts for devices in this slot */
    431             if ( int_name == 255 ) {
    432               /* find the vector associated with whatever pin the
    433                * device gives us
    434                */
    435               for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ) {
    436                 if ( bspmap[i].pin_route[j].pin == int_pin ) {
    437                   int_name = bspmap[i].pin_route[j].int_name[0];
    438                   break;
    439                 }
    440               }
    441               if ( int_name == -1 ) {
    442                 printk("pci : Unable to resolve device %d:%d w/ swizzled int "
    443                        "pin %i to an interrupt_line.\n", pbus, pslot, int_pin );
    444               } else {
    445                 PRINT_MSG();
    446                 pci_write_config_byte( pbus,pslot,0,
    447                     PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
    448               }
    449             } else {
    450               test_intname( &bspmap[i],pbus,pslot,int_pin,int_name);
    451             }
    452             break;
    453           }
    454         }
    455 
    456         if ( !ismatch ) {
    457           /*
    458            * no match, which means we're on a bus someplace.  Work
    459            * backwards from it to one of our defined busses,
    460            * swizzling thru each bridge on the way.
    461            */
    462 
    463           /* keep pbus, pslot pointed to the device being
    464            * configured while we track down the bridges using
    465            * tbus,tslot.  We keep searching the routing table because
    466            * we may end up finding our bridge in it
    467            */
    468 
    469           int tbus= pbus, tslot= pslot;
    470 
    471           for (;;) {
    472             for (i=0; bspmap[i].bus > -1; i++) {
    473               if ( bspmap[i].bus == tbus &&
    474                    (bspmap[i].slot == tslot || bspmap[i].slot == -1) ) {
    475                 ismatch = -1;
    476                 /* found a record for this bus, so swizzle the
    477                  * int_pin which we then use to find the
    478                  * interrupt_name.
    479                  */
    480 
    481                 if ( int_name == 255 ) {
    482                   /*
    483                    * FIXME.  I can't believe this little hack
    484                    * is right.  It does not yield an error in
    485                    * convienently simple situations.
    486                    */
    487                   if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
    488 
    489                   /*
    490                    * int_pin points to the interrupt channel
    491                    * this card ends up delivering interrupts
    492                    * on.  Find the int_name servicing it.
    493                    */
    494                   for (int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++){
    495                     if ( bspmap[i].pin_route[j].pin == int_pin ) {
    496                       int_name = bspmap[i].pin_route[j].int_name[0];
    497                       break;
    498                     }
    499                   }
    500 
    501                   if ( int_name == -1 ) {
    502                     printk("pci : Unable to resolve device %d:%d w/ swizzled "
    503                            "int pin %i to an interrupt_line.\n",
    504                            pbus, pslot, int_pin );
    505                   } else {
    506                     PRINT_MSG();
    507                     pci_write_config_byte(pbus,pslot,0,
    508                       PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
    509                   }
    510                 } else {
    511                   test_intname(&bspmap[i],pbus,pslot,int_pin,int_name);
    512                 }
    513                 goto donesearch;
    514               }
    515             }
    516 
    517             if ( !ismatch ) {
    518               struct pcibridge   pb;
    519 
    520               /*
    521                * Haven't found our bus in the int map, so work
    522                * upwards thru the bridges till we find it.
    523                */
    524 
    525               if ( FindPCIbridge( tbus, &pb )== 0 ) {
    526                 int_pin = (*swizzler)(tslot,int_pin);
    527 
    528                 /* our next bridge up is on pb.bus, pb.slot- now
    529                  * instead of pointing to the device we're
    530                  * trying to configure, we move from bridge to
    531                  * bridge.
    532                  */
    533 
    534                 tbus = pb.bus;
    535                 tslot = pb.slot;
    536               } else {
    537                 printk("pci : No bridge from bus %i towards root found\n",
    538                        tbus );
    539                 goto donesearch;
    540               }
    541             }
    542           }
    543         }
    544         donesearch:
    545 
    546         if ( !ismatch && int_pin != 0 && int_name == 255 ) {
    547             printk("pci : Unable to match device %d:%d with an int "
    548                    "routing table entry\n", pbus, pslot  );
    549         }
    550       }
    551      }
    552    }
     438                if ( int_pin > 0 ) {
     439                  ismatch = 0;
     440
     441                  /*
     442                   * first run thru the bspmap table and see if we have an
     443                   * explicit configuration
     444                   */
     445                  for (i=0; bspmap[i].bus > -1; i++) {
     446                        if ( bspmap[i].bus == pbus && bspmap[i].slot == pslot ) {
     447                          ismatch = -1;
     448                          /* we have a record in the table that gives specific
     449                           * pins and interrupts for devices in this slot */
     450                          if ( int_name == 255 ) {
     451                                /* find the vector associated with whatever pin the
     452                                 * device gives us
     453                                 */
     454                                for ( int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++ ) {
     455                                  if ( bspmap[i].pin_route[j].pin == int_pin ) {
     456                                        int_name = bspmap[i].pin_route[j].int_name[0];
     457                                        break;
     458                                  }
     459                                }
     460                                if ( int_name == -1 ) {
     461                                  printk("pci : Unable to resolve device %d:0x%02x:%d w/ swizzled int "
     462                                          "pin %i to an interrupt_line.\n", pbus, pslot, pfun, int_pin );
     463                                } else {
     464                                  PRINT_MSG();
     465                                  pci_write_config_byte( pbus,pslot,pfun,
     466                                          PCI_INTERRUPT_LINE,(cvalue= int_name, cvalue));
     467                                }
     468                          } else {
     469                                test_intname( &bspmap[i],pbus,pslot,pfun,int_pin,int_name);
     470                          }
     471                          break;
     472                        }
     473                  }
     474
     475                  if ( !ismatch ) {
     476                        /*
     477                         * no match, which means we're on a bus someplace.  Work
     478                         * backwards from it to one of our defined busses,
     479                         * swizzling thru each bridge on the way.
     480                         */
     481
     482                        /* keep pbus, pslot pointed to the device being
     483                         * configured while we track down the bridges using
     484                         * tbus,tslot.  We keep searching the routing table because
     485                         * we may end up finding our bridge in it
     486                         */
     487
     488                        int tbus= pbus, tslot= pslot;
     489
     490                        for (;;) {
     491                          for (i=0; bspmap[i].bus > -1; i++) {
     492                                if ( bspmap[i].bus == tbus &&
     493                                        (bspmap[i].slot == tslot || bspmap[i].slot == -1) ) {
     494                                  ismatch = -1;
     495                                  /* found a record for this bus, so swizzle the
     496                                   * int_pin which we then use to find the
     497                                   * interrupt_name.
     498                                   */
     499
     500                                  if ( int_name == 255 ) {
     501                                        /*
     502                                         * FIXME.  I can't believe this little hack
     503                                         * is right.  It does not yield an error in
     504                                         * convienently simple situations.
     505                                         */
     506                                        if ( tbus ) int_pin = (*swizzler)(tslot,int_pin);
     507
     508                                        /*
     509                                         * int_pin points to the interrupt channel
     510                                         * this card ends up delivering interrupts
     511                                         * on.  Find the int_name servicing it.
     512                                         */
     513                                        for (int_name=-1, j=0; bspmap[i].pin_route[j].pin > -1; j++){
     514                                          if ( bspmap[i].pin_route[j].pin == int_pin ) {
     515                                                int_name = bspmap[i].pin_route[j].int_name[0];
     516                                                break;
     517                                          }
     518                                        }
     519
     520                                        if ( int_name == -1 ) {
     521                                          printk("pci : Unable to resolve device %d:0x%02x:%d w/ swizzled "
     522                                                  "int pin %i to an interrupt_line.\n",
     523                                                  pbus, pslot, pfun, int_pin );
     524                                        } else {
     525                                          PRINT_MSG();
     526                                          pci_write_config_byte(pbus,pslot,pfun,
     527                                                  PCI_INTERRUPT_LINE,(cvalue=int_name, cvalue));
     528                                        }
     529                                  } else {
     530                                        test_intname(&bspmap[i],pbus,pslot,pfun,int_pin,int_name);
     531                                  }
     532                                  goto donesearch;
     533                                }
     534                          }
     535
     536                          if ( !ismatch ) {
     537                                struct pcibridge   pb;
     538
     539                                /*
     540                                 * Haven't found our bus in the int map, so work
     541                                 * upwards thru the bridges till we find it.
     542                                 */
     543
     544                                if ( FindPCIbridge( tbus, &pb )== 0 ) {
     545                                  int_pin = (*swizzler)(tslot,int_pin);
     546
     547                                  /* our next bridge up is on pb.bus, pb.slot- now
     548                                   * instead of pointing to the device we're
     549                                   * trying to configure, we move from bridge to
     550                                   * bridge.
     551                                   */
     552
     553                                  tbus = pb.bus;
     554                                  tslot = pb.slot;
     555                                } else {
     556                                  printk("pci : No bridge from bus %i towards root found\n",
     557                                          tbus );
     558                                  goto donesearch;
     559                                }
     560                          }
     561                        }
     562                  }
     563donesearch:
     564
     565                  if ( !ismatch && int_pin != 0 && int_name == 255 ) {
     566                        printk("pci : Unable to match device %d:0x%02x:%d with an int "
     567                                "routing table entry\n", pbus, pslot, pfun  );
     568                  }
     569                }
     570          }
     571        }
     572  }
    553573}
    554574
  • c/src/lib/libbsp/powerpc/shared/pci/pci.h

    rcca22863 r98afe31  
    2020
    2121#include <rtems/pci.h>
     22#include <stdio.h>
    2223
    2324struct _pin_routes
     
    3132};
    3233
     34/* If there's a conflict between a name in the routing table and
     35 * what's already set on the device, reprogram the device setting
     36 * to reflect int_name[0] for the routing table entry
     37 */
     38#define PCI_FIXUP_OPT_OVERRIDE_NAME     (1<<0)
     39
    3340void FixupPCI( const struct _int_map *, int (*swizzler)(int,int) );
    3441
     
    3643extern unsigned char pci_bus_count();
    3744
     45/* FIXME: This also is generic and could go into rtems/pci.h */
     46
     47/* Scan pci config space and run a user callback on each
     48 * device present; the user callback may return 0 to
     49 * continue the scan or a value > 0 to abort the scan.
     50 * Return values < 0 are reserved and must not be used.
     51 *
     52 * RETURNS: a (opaque) handle pointing to the bus/slot/fn-triple
     53 *          just after where the scan was aborted by a callback
     54 *          returning 1 (see above) or NULL if all devices were
     55 *          scanned.
     56 *          The handle may be passed to this routine to resume the
     57 *          scan continuing with the device after the one causing the
     58 *          abort.
     59 *          Pass a NULL 'handle' argument to start scanning from
     60 *          the beginning (bus/slot/fn = 0/0/0).
     61 */
     62typedef void *BSP_PciScanHandle;
     63typedef int (*BSP_PciScannerCb)(int bus, int slot, int fun, void *uarg);
     64
     65BSP_PciScanHandle
     66BSP_pciScan(BSP_PciScanHandle handle, BSP_PciScannerCb cb, void *uarg);
     67
     68/* Dump basic config. space info to a file. The argument may
     69 * be NULL in which case 'stdout' is used.
     70 * NOTE: the C-library must be functional before you can use
     71 *       this routine.
     72 */
     73void
     74BSP_pciConfigDump(FILE *fp);
     75
    3876#endif /* BSP_POWERPC_PCI_H */
  • c/src/lib/libbsp/powerpc/shared/pci/pcifinddevice.c

    rcca22863 r98afe31  
    1313#include <bsp/pci.h>
    1414#include <rtems/bspIo.h>
     15#include <stdio.h>
     16
     17/* Stolen from i386... */
     18
     19/*
     20 * Make device signature from bus number, device number and function
     21 * number
     22 */
     23#define PCIB_DEVSIG_MAKE(b,d,f) ((b<<8)|(d<<3)|(f))
     24
     25/*
     26 * Extract various parts from device signature
     27 */
     28#define PCIB_DEVSIG_BUS(x) (((x)>>8) &0xff)
     29#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
     30#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
     31
     32typedef struct {
     33        unsigned short  vid,did;
     34        int                             inst;
     35} fd_arg;
     36
     37static int
     38find_dev_cb(
     39   int bus,
     40   int dev,
     41   int fun,
     42   void *uarg
     43) {
     44fd_arg         *a = uarg;
     45unsigned short  s;
     46
     47  pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
     48  if (a->vid == s) {
     49    pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
     50        if (a->did == s && 0 == a->inst-- ) {
     51          a->inst = PCIB_DEVSIG_MAKE( bus, dev, fun );
     52          return 1;
     53        }
     54  }
     55  return 0;
     56}
    1557
    1658int
     
    2365  int *pfun
    2466) {
     67fd_arg a;
     68void   *h;
     69        a.vid  = vendorid;
     70        a.did  = deviceid;
     71        a.inst = instance;
     72
     73        if ( (h = BSP_pciScan(0, find_dev_cb, (void*)&a)) ) {
     74      *pbus = PCIB_DEVSIG_BUS(  a.inst );
     75      *pdev = PCIB_DEVSIG_DEV(  a.inst );
     76      *pfun = PCIB_DEVSIG_FUNC( a.inst );
     77          return 0;
     78        }
     79        return -1;
     80}
     81
     82static int
     83dump_dev_cb(
     84   int bus,
     85   int dev,
     86   int fun,
     87   void *uarg
     88) {
     89unsigned short vi,di;
     90unsigned short cd,st;
     91unsigned int   b1,b2;
     92unsigned char  il,ip;
     93FILE           *f = uarg;
     94
     95        pci_read_config_word (bus, dev, fun, PCI_VENDOR_ID,      &vi);
     96        pci_read_config_word (bus, dev, fun, PCI_DEVICE_ID,      &di);
     97        pci_read_config_word (bus, dev, fun, PCI_COMMAND,        &cd);
     98        pci_read_config_word (bus, dev, fun, PCI_STATUS,         &st);
     99        pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_0, &b1);
     100        pci_read_config_dword(bus, dev, fun, PCI_BASE_ADDRESS_1, &b2);
     101        pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_LINE, &il);
     102        pci_read_config_byte (bus, dev, fun, PCI_INTERRUPT_PIN,  &ip);
     103
     104        fprintf(f,"%3d:0x%02x:%d    0x%04x-0x%04x:  0x%04x 0x%04x 0x%08x 0x%08x       %d -> %3d (=0x%02x)\n",
     105                bus, dev, fun, vi, di, cd, st, b1, b2, ip, il, il);
     106        return 0;
     107}
     108
     109void
     110BSP_pciConfigDump(FILE *f)
     111{
     112        if ( !f )
     113                f = stdout;
     114        fprintf(f,"BUS:SLOT:FUN  VENDOR-DEV_ID: COMMAND STATUS BASE_ADDR0 BASE_ADDR1 IRQ_PIN -> IRQ_LINE\n");
     115        BSP_pciScan(0, dump_dev_cb, f);
     116}
     117
     118BSP_PciScanHandle
     119BSP_pciScan(
     120  BSP_PciScanHandle handle,
     121  BSP_PciScannerCb cb,
     122  void *uarg
     123) {
     124
    25125   unsigned int d;
    26    unsigned short s;
    27126   unsigned char bus,dev,fun,hd;
    28127
    29    for (bus=0; bus<pci_bus_count(); bus++) {
    30      for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
     128   bus = PCIB_DEVSIG_BUS(  (unsigned long)handle );
     129   dev = PCIB_DEVSIG_DEV(  (unsigned long)handle );
     130   fun = PCIB_DEVSIG_FUNC( (unsigned long)handle );
    31131
    32        pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
    33        hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
     132   hd = fun > 0 ? PCI_MAX_FUNCTIONS : 1;
    34133
    35        for (fun=0; fun<hd; fun++) {
     134   for (; bus<pci_bus_count(); bus++, dev=0) {
     135     for (; dev<PCI_MAX_DEVICES; dev++, fun=0) {
     136       for (; fun<hd; fun++) {
    36137         /*
    37138          * The last devfn id/slot is special; must skip it
    38139          */
    39         if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
    40           break;
     140         if (PCI_MAX_DEVICES-1==dev && PCI_MAX_FUNCTIONS-1 == fun)
     141           break;
     142
     143         (void)pci_read_config_dword(bus,dev,0,PCI_VENDOR_ID,&d);
     144         if (PCI_INVALID_VENDORDEVICEID == d)
     145           continue;
     146
     147         if ( 0 == fun ) {
     148           pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd);
     149           hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
     150                 }
     151
    41152        (void)pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d);
    42153        if (PCI_INVALID_VENDORDEVICEID == d)
    43154          continue;
    44155#ifdef PCI_DEBUG
    45         printk("pci_find_by_devid: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
     156        printk("BSP_pciScan: found 0x%08x at %d/x%02x/%d\n",d,bus,dev,fun);
    46157#endif
    47         (void) pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s);
    48         if (vendorid != s)
    49           continue;
    50         (void) pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s);
    51         if (deviceid == s) {
    52           if (instance--) continue;
    53           *pbus=bus; *pdev=dev; *pfun=fun;
    54           return 0;
    55         }
     158                if ( cb(bus,dev,fun,uarg) > 0 ) {
     159                        if ( ++fun >= hd ) {
     160                                fun = 0;
     161                                if ( ++dev >= PCI_MAX_DEVICES ) {
     162                                        dev = 0;
     163                                        bus++;
     164                                }
     165                        }
     166                        return (void*) PCIB_DEVSIG_MAKE(bus,dev,fun);
     167                }
    56168      }
    57169    }
    58170  }
    59   return -1;
     171  return 0;
    60172}
Note: See TracChangeset for help on using the changeset viewer.