Changeset 6266abe in rtems for c/src/lib/libbsp/i386/shared/pci


Ignore:
Timestamp:
May 4, 2005, 7:24:41 PM (15 years ago)
Author:
Jennifer Averett <Jennifer.Averett@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
8b3b2ef
Parents:
7111268
Message:

2005-05-04 Jennifer Averett <jennifer.averett@…>

  • pci/pcibios.c, pci/pcibios.h: Corrected spacing Name modifications for a generic PCI interface Added wrapper routines for pci read/write configuration data
Location:
c/src/lib/libbsp/i386/shared/pci
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/shared/pci/pcibios.c

    r7111268 r6266abe  
    1212#include <pcibios.h>
    1313
    14 #include <string.h>     /* memcpy */
     14#include <string.h>  /* memcpy */
    1515
    1616/*
    1717 * This is simpliest possible PCI BIOS, it assumes that addressing
    18  * is flat and that stack is big enough 
    19  */ 
     18 * is flat and that stack is big enough
     19 */
    2020
    2121
     
    2424
    2525/*
    26  * Array to pass data between c and asm parts, at the time of 
    27  * writing I am not yet that familiar with extended asm feature 
    28  * of gcc. This code is not on performance path, so we can care 
    29  * relatively little about performance here 
     26 * Array to pass data between c and asm parts, at the time of
     27 * writing I am not yet that familiar with extended asm feature
     28 * of gcc. This code is not on performance path, so we can care
     29 * relatively little about performance here
    3030 */
    3131static volatile unsigned int pcibExchg[5];
     
    3434
    3535/*
    36  * Detects presense of PCI BIOS, returns 
     36 * Detects presense of PCI BIOS, returns
    3737 * error code
    3838 */
    39 int 
     39int
    4040pci_initialize(void)
    4141{
     
    4747
    4848  /* First, we have to look for BIOS-32 */
    49   for(ucp=(unsigned char *)0xE0000; ucp < (unsigned char *)0xFFFFF; ucp+=0x10)
    50     {
    51       if(memcmp(ucp, "_32_", 4) != 0)
    52         {
    53           continue;
    54         }
     49  for (ucp = (unsigned char *)0xE0000;
     50       ucp < (unsigned char *)0xFFFFF;
     51       ucp += 0x10) {
     52    if (memcmp(ucp, "_32_", 4) != 0) {
     53      continue;
     54    }
    5555
    5656      /* Got signature, check length  */
    57       if(*(ucp + 9) != 1)
    58         {
    59           continue;
    60         }
    61 
    62       /* Verify checksum */
    63       sum = 0;
    64       for(i=0; i<16; i++)
    65         {
    66           sum += *(ucp+i);
    67         }
    68 
    69       if(sum == 0)
    70         {
    71           /* found */
    72           break;
    73         }
     57    if (*(ucp + 9) != 1) {
     58      continue;
    7459    }
    7560
    76   if(ucp >= (unsigned char *)0xFFFFF)
    77     {
    78       /* BIOS-32 not found */
    79       return PCIB_ERR_NOTPRESENT;
     61    /* Verify checksum */
     62    sum = 0;
     63    for (i=0; i<16; i++) {
     64      sum += *(ucp+i);
    8065    }
     66
     67    if (sum == 0) {
     68      /* found */
     69      break;
     70    }
     71  }
     72
     73  if (ucp >= (unsigned char *)0xFFFFF) {
     74    /* BIOS-32 not found */
     75    return PCIB_ERR_NOTPRESENT;
     76  }
    8177
    8278  /* BIOS-32 found, let us find PCI BIOS */
     
    8581  pcibExchg[0] = *(unsigned int *)ucp;
    8682
    87   asm ("    pusha");                  /* Push all registers */ 
     83  asm ("    pusha");                  /* Push all registers */
    8884  asm ("    movl pcibExchg, %edi");   /* Move entry point to esi */
    8985  asm ("    movl $0x49435024, %eax"); /* Move signature to eax */
     
    9793  asm ("    popa");
    9894
    99   if((pcibExchg[0] & 0xff) != 0)
    100     {
    101       /* Not found */
    102       return PCIB_ERR_NOTPRESENT;
    103     }
     95  if ((pcibExchg[0] & 0xff) != 0) {
     96    /* Not found */
     97    return PCIB_ERR_NOTPRESENT;
     98  }
    10499
    105100  /* Found PCI entry point */
     
    108103  /* Let us check whether PCI bios is present */
    109104  pcibExchg[0] = pcibEntry;
    110  
     105
    111106  asm("    pusha");
    112107  asm("    movl pcibExchg, %edi");
    113108  asm("    movb $0xb1, %ah");
    114109  asm("    movb $0x01, %al");
    115   asm ("   pushl %cs");
     110  asm("    pushl %cs");
    116111  asm("    call *%edi");
    117112  asm("    movl %eax, pcibExchg");
     
    121116  asm("    popa");
    122117
    123   if((pcibExchg[0] & 0xff00) != 0)
    124     {
    125       /* Not found */
    126       return PCIB_ERR_NOTPRESENT;
    127     }
    128 
    129   if(pcibExchg[3] != 0x20494350)
    130     {
    131       /* Signature does not match */
    132       return PCIB_ERR_NOTPRESENT;
    133     }
     118  if ((pcibExchg[0] & 0xff00) != 0) {
     119    /* Not found */
     120    return PCIB_ERR_NOTPRESENT;
     121  }
     122
     123  if (pcibExchg[3] != 0x20494350) {
     124    /* Signature does not match */
     125    return PCIB_ERR_NOTPRESENT;
     126  }
    134127
    135128  /* Success */
    136  
     129
    137130  pcibInitialized = 1;
    138131  return PCIB_ERR_SUCCESS;
    139132}
    140133
    141 /* 
    142  * Find specified device and return its signature: combination 
     134/*
     135 * Find specified device and return its signature: combination
    143136 * of bus number, device number and function number
    144137 */
     
    146139pcib_find_by_devid(int vendorId, int devId, int idx, int *sig)
    147140{
    148   if(!pcibInitialized)
    149     {
    150       return PCIB_ERR_UNINITIALIZED;
    151     }
     141  if (!pcibInitialized) {
     142    return PCIB_ERR_UNINITIALIZED;
     143  }
    152144
    153145  pcibExchg[0] = pcibEntry;
     
    195187}
    196188
    197 /* 
    198  * Find specified class code return device signature: combination 
     189/*
     190 * Find specified class code return device signature: combination
    199191 * of bus number, device number and function number
    200192 */
     
    202194pcib_find_by_class(int classCode, int idx, int *sig)
    203195{
    204   if(!pcibInitialized)
    205     {
    206       return PCIB_ERR_UNINITIALIZED;
    207     }
     196  if (!pcibInitialized) {
     197    return PCIB_ERR_UNINITIALIZED;
     198  }
    208199
    209200  pcibExchg[0] = pcibEntry;
     
    223214  asm("    popa");
    224215
    225   if((pcibExchg[0] & 0xff00) != 0)
    226     {
    227       return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
     216  if ((pcibExchg[0] & 0xff00) != 0) {
     217    return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
     218  }
     219
     220  *sig = pcibExchg[1] & 0xffff;
     221
     222  return PCIB_ERR_SUCCESS;
     223}
     224
     225#define PCI_MULTI_FUNCTION      0x80
     226
     227static unsigned8 ucBusCount = 0xff;
     228
     229unsigned char
     230pci_bus_count()
     231{
     232  if ( ucBusCount == 0xff ) {
     233    unsigned char bus;
     234    unsigned char dev;
     235    unsigned char hd = 0;
     236    unsigned int d = 0;
     237    int sig;
     238
     239    ucBusCount = 0;
     240
     241    for (bus=0; bus< 0xff; bus++) {
     242      for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
     243        sig = PCIB_DEVSIG_MAKE(bus,dev,0);
     244        pcib_conf_read32(sig, PCI_VENDOR_ID, &d);
     245
     246        if ( d != -1 ) {
     247           pcib_conf_read32(sig, PCI_CLASS_REVISION, &d);
     248
     249           if ( (d >> 16) == PCI_CLASS_BRIDGE_PCI ) {
     250             pcib_conf_read8(sig, PCI_SUBORDINATE_BUS, &hd);
     251
     252             if ( hd > ucBusCount )
     253               ucBusCount = hd;
     254           }
     255        }
     256      }
    228257    }
    229258
    230   *sig = pcibExchg[1] & 0xffff;
    231 
    232   return PCIB_ERR_SUCCESS;
    233 }
    234  
    235 #define PCI_MULTI_FUNCTION      0x80
    236 
    237 static unsigned8 ucBusCount = 0xff;
    238 
    239 unsigned char
    240 BusCountPCI()
    241 {
    242    if( ucBusCount == 0xff )
    243    {
    244       unsigned char bus;
    245       unsigned char dev;
    246       unsigned char hd = 0;
    247       unsigned int d = 0;
    248       int sig;
    249 
    250       ucBusCount = 0;
    251 
    252       for (bus=0; bus< 0xff; bus++) { 
    253          for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
    254             sig = PCIB_DEVSIG_MAKE(bus,dev,0);
    255             pcib_conf_read32(sig, PCI_VENDOR_ID, &d);
    256 
    257             if( d != -1 ) {
    258                pcib_conf_read32(sig, PCI_CLASS_REVISION, &d);
    259                
    260                if( (d >> 16) == PCI_CLASS_BRIDGE_PCI ) {
    261                   pcib_conf_read8(sig, PCI_SUBORDINATE_BUS, &hd);
    262 
    263                   if( hd > ucBusCount )
    264                      ucBusCount = hd;
    265                }
    266             }
    267          }
    268          
    269       }
    270 
    271       if( ucBusCount == 0 ) {
    272          printk("BusCountPCI() found 0 busses, assuming 1\n");
    273          ucBusCount = 1;
    274       } else if( ucBusCount == 0xff ) {
    275          printk("BusCountPCI() found 0xff busses, assuming 1\n");
    276          ucBusCount = 1;
    277       }
    278    }                       
    279 
    280    return ucBusCount;
     259    if ( ucBusCount == 0 ) {
     260      printk("pci_bus_count() found 0 busses, assuming 1\n");
     261      ucBusCount = 1;
     262    } else if ( ucBusCount == 0xff ) {
     263      printk("pci_bus_count() found 0xff busses, assuming 1\n");
     264      ucBusCount = 1;
     265    }
     266  }
     267
     268  return ucBusCount;
    281269}
    282270
     
    286274                   int instance, int *pbus, int *pdev, int *pfun )
    287275{
    288    int sig;
    289    unsigned int d = 0;
    290    unsigned short s = 0;
    291    unsigned char bus;
    292    unsigned char dev;
    293    unsigned char fun;
    294    unsigned char hd = 0;
    295 
    296    for (bus=0; bus<BusCountPCI(); bus++)
    297    {
    298       for (dev=0; dev<PCI_MAX_DEVICES; dev++)
    299       {
    300          sig = PCIB_DEVSIG_MAKE(bus,dev,0);
    301 
    302          /* pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd); */
    303          pcib_conf_read8(sig, 0xe, &hd);
    304 
    305          hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
    306 
    307          for (fun=0; fun<hd; fun++) {
    308             /*
    309              * The last devfn id/slot is special; must skip it
    310              */
    311             if( PCI_MAX_DEVICES-1 == dev && PCI_MAX_FUNCTIONS-1 == fun )
    312                break;
    313 
    314             /*pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d); */
    315             pcib_conf_read32(sig, 0, &d);
    316             if( d == -1 )
    317                continue;
     276  int sig;
     277  unsigned int d = 0;
     278  unsigned short s = 0;
     279  unsigned char bus;
     280  unsigned char dev;
     281  unsigned char fun;
     282  unsigned char hd = 0;
     283
     284  for (bus=0; bus<pci_bus_count(); bus++) {
     285    for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
     286      sig = PCIB_DEVSIG_MAKE(bus,dev,0);
     287
     288      /* pci_read_config_byte(bus,dev,0, PCI_HEADER_TYPE, &hd); */
     289      pcib_conf_read8(sig, 0xe, &hd);
     290
     291      hd = (hd & PCI_MULTI_FUNCTION ? PCI_MAX_FUNCTIONS : 1);
     292
     293      for (fun=0; fun<hd; fun++) {
     294        /*
     295         * The last devfn id/slot is special; must skip it
     296         */
     297        if ( PCI_MAX_DEVICES-1 == dev && PCI_MAX_FUNCTIONS-1 == fun )
     298          break;
     299
     300        /*pci_read_config_dword(bus,dev,fun,PCI_VENDOR_ID,&d); */
     301        pcib_conf_read32(sig, 0, &d);
     302        if ( d == -1 )
     303          continue;
    318304#ifdef PCI_DEBUG
    319             printk("BSP_pciFindDevice: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
     305        printk("BSP_pciFindDevice: found 0x%08x at %d/%d/%d\n",d,bus,dev,fun);
    320306#endif
    321             /* pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s); */
    322             pcib_conf_read16(sig, 0, &s);
    323             if (vendorid != s)
    324                continue;
    325 
    326             /* pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s); */
    327             pcib_conf_read16(sig, 0x2, &s);
    328             if (deviceid == s) {
    329                if (instance--) continue;
    330                *pbus=bus;
    331                *pdev=dev;
    332                *pfun=fun;
    333                return 0;
    334             }
    335          }
     307        /* pci_read_config_word(bus,dev,fun,PCI_VENDOR_ID,&s); */
     308        pcib_conf_read16(sig, 0, &s);
     309        if (vendorid != s)
     310          continue;
     311
     312        /* pci_read_config_word(bus,dev,fun,PCI_DEVICE_ID,&s); */
     313        pcib_conf_read16(sig, 0x2, &s);
     314        if (deviceid == s) {
     315          if (instance--) continue;
     316          *pbus=bus;
     317          *pdev=dev;
     318          *pfun=fun;
     319          return 0;
     320        }
    336321      }
    337    }
    338    return -1;
    339 }
    340 
    341 
    342  
    343 
    344 /*
     322    }
     323  }
     324  return -1;
     325}
     326
     327/*
    345328 * Generate Special Cycle
    346329 */
     
    348331pcib_special_cycle(int busNo, int data)
    349332{
    350   if(!pcibInitialized)
    351     {
    352       return PCIB_ERR_UNINITIALIZED;
    353     }
     333  if (!pcibInitialized) {
     334    return PCIB_ERR_UNINITIALIZED;
     335  }
    354336
    355337  pcibExchg[0] = pcibEntry;
     
    371353  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    372354}
    373  
    374 
    375 /* 
     355
     356
     357/*
    376358 * Read byte from config space
    377359 */
     
    379361pcib_conf_read8(int sig, int off, unsigned char *data)
    380362{
    381   if(!pcibInitialized)
    382     {
    383       return PCIB_ERR_UNINITIALIZED;
    384     }
     363  if (!pcibInitialized) {
     364    return PCIB_ERR_UNINITIALIZED;
     365  }
    385366
    386367  pcibExchg[0] = pcibEntry;
     
    400381  asm("    popa");
    401382
    402   if((pcibExchg[0] & 0xff00) != 0)
    403     {
    404       return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    405     }
     383  if ((pcibExchg[0] & 0xff00) != 0) {
     384    return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
     385  }
    406386
    407387  *data = (unsigned char)pcibExchg[1] & 0xff;
     
    409389  return PCIB_ERR_SUCCESS;
    410390}
    411  
    412 
    413 /* 
     391
     392
     393/*
    414394 * Read word from config space
    415395 */
     
    417397pcib_conf_read16(int sig, int off, unsigned short *data)
    418398{
    419   if(!pcibInitialized)
    420     {
    421       return PCIB_ERR_UNINITIALIZED;
    422     }
     399  if (!pcibInitialized) {
     400    return PCIB_ERR_UNINITIALIZED;
     401  }
    423402
    424403  pcibExchg[0] = pcibEntry;
     
    438417  asm("    popa");
    439418
    440   if((pcibExchg[0] & 0xff00) != 0)
    441     {
    442       return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    443     }
     419  if ((pcibExchg[0] & 0xff00) != 0) {
     420    return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
     421  }
    444422
    445423  *data = (unsigned short)pcibExchg[1] & 0xffff;
     
    447425  return PCIB_ERR_SUCCESS;
    448426}
    449  
    450 
    451 /* 
     427
     428
     429/*
    452430 * Read dword from config space
    453431 */
     
    455433pcib_conf_read32(int sig, int off, unsigned int *data)
    456434{
    457   if(!pcibInitialized)
    458     {
    459       return PCIB_ERR_UNINITIALIZED;
    460     }
     435  if (!pcibInitialized) {
     436    return PCIB_ERR_UNINITIALIZED;
     437  }
    461438
    462439  pcibExchg[0] = pcibEntry;
     
    476453  asm("    popa");
    477454
    478   if((pcibExchg[0] & 0xff00) != 0)
    479     {
    480       return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    481     }
     455  if ((pcibExchg[0] & 0xff00) != 0) {
     456    return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
     457  }
    482458
    483459  *data = (unsigned int)pcibExchg[1];
     
    485461  return PCIB_ERR_SUCCESS;
    486462}
    487  
    488 
    489 /* 
     463
     464
     465/*
    490466 * Write byte into  config space
    491467 */
     
    493469pcib_conf_write8(int sig, int off, unsigned int data)
    494470{
    495   if(!pcibInitialized)
    496     {
    497       return PCIB_ERR_UNINITIALIZED;
    498     }
     471  if (!pcibInitialized) {
     472    return PCIB_ERR_UNINITIALIZED;
     473  }
    499474
    500475  pcibExchg[0] = pcibEntry;
     
    518493}
    519494
    520 /* 
     495/*
    521496 * Write word into config space
    522497 */
     
    524499pcib_conf_write16(int sig, int off, unsigned int data)
    525500{
    526   if(!pcibInitialized)
    527     {
    528       return PCIB_ERR_UNINITIALIZED;
    529     }
     501  if (!pcibInitialized) {
     502    return PCIB_ERR_UNINITIALIZED;
     503  }
    530504
    531505  pcibExchg[0] = pcibEntry;
     
    548522  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    549523}
    550  
    551 
    552 
    553 /* 
     524
     525
     526
     527/*
    554528 * Write dword into config space
    555529 */
     
    557531pcib_conf_write32(int sig, int off, unsigned int data)
    558532{
    559   if(!pcibInitialized)
    560     {
     533  if (!pcibInitialized){
    561534      return PCIB_ERR_UNINITIALIZED;
    562     }
     535  }
    563536
    564537  pcibExchg[0] = pcibEntry;
     
    581554  return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    582555}
    583  
     556
    584557
    585558static int
    586559pcib_convert_err(int err)
    587560{
    588   switch(err & 0xff)
    589     {
     561  switch(err & 0xff){
    590562    case 0:
    591563      return PCIB_ERR_SUCCESS;
     
    600572    default:
    601573      break;
    602     }
     574  }
    603575  return PCIB_ERR_NOFUNC;
    604576}
    605        
    606      
    607 
    608 
    609  
    610      
    611  
    612 
    613 
    614 
     577
     578static int
     579indirect_pci_read_config_byte(
     580  unsigned char bus,
     581  unsigned char slot,
     582  unsigned char fun,
     583  unsigned char offset,
     584  unsigned char *val
     585)
     586{
     587  int sig;
     588
     589  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     590  pcib_conf_read8(sig, offset, val);
     591  return PCIBIOS_SUCCESSFUL;
     592}
     593
     594static int
     595indirect_pci_read_config_word(
     596  unsigned char bus,
     597  unsigned char slot,
     598  unsigned char fun,
     599  unsigned char offset,
     600  unsigned short *val
     601)
     602{
     603  int sig;
     604
     605  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     606  pcib_conf_read16(sig, offset, val);
     607  return PCIBIOS_SUCCESSFUL;
     608}
     609
     610static int
     611indirect_pci_read_config_dword(
     612  unsigned char bus,
     613  unsigned char slot,
     614  unsigned char fun,
     615  unsigned char offset,
     616  unsigned int *val
     617)
     618{
     619  int sig;
     620
     621  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     622  pcib_conf_read32(sig, offset, val);
     623  return PCIBIOS_SUCCESSFUL;
     624}
     625
     626static int
     627indirect_pci_write_config_byte(
     628  unsigned char bus,
     629  unsigned char slot,
     630  unsigned char fun,
     631  unsigned char offset,
     632  unsigned char val
     633)
     634{
     635  int sig;
     636
     637  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     638  pcib_conf_write8(sig, offset, val);
     639  return PCIBIOS_SUCCESSFUL;
     640}
     641
     642static int
     643indirect_pci_write_config_word(
     644  unsigned char bus,
     645  unsigned char slot,
     646  unsigned char fun,
     647  unsigned char offset,
     648  unsigned short val
     649)
     650{
     651  int sig;
     652
     653  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     654  pcib_conf_write16(sig, offset, val);
     655  return PCIBIOS_SUCCESSFUL;
     656}
     657
     658static int
     659indirect_pci_write_config_dword(
     660  unsigned char bus,
     661  unsigned char slot,
     662  unsigned char fun,
     663  unsigned char offset,
     664  unsigned int val
     665)
     666{
     667  int sig;
     668
     669  sig = PCIB_DEVSIG_MAKE(bus,slot,fun);
     670  pcib_conf_write32(sig, offset, val);
     671  return PCIBIOS_SUCCESSFUL;
     672}
     673
     674const pci_config_access_functions pci_indirect_functions = {
     675  indirect_pci_read_config_byte,
     676  indirect_pci_read_config_word,
     677  indirect_pci_read_config_dword,
     678  indirect_pci_write_config_byte,
     679  indirect_pci_write_config_word,
     680  indirect_pci_write_config_dword
     681};
     682
     683pci_config BSP_pci_configuration = {
     684  (volatile unsigned char*)0,
     685  (volatile unsigned char*)0,
     686  &pci_indirect_functions
     687};
  • c/src/lib/libbsp/i386/shared/pci/pcibios.h

    r7111268 r6266abe  
    3838
    3939int
    40 BSP_pciFindDevice( unsigned short vendorid, unsigned short deviceid,
     40pci_find_device( unsigned short vendorid, unsigned short deviceid,
    4141                   int instance, int *pbus, int *pdev, int *pfun );
    4242
Note: See TracChangeset for help on using the changeset viewer.