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.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.