Changeset f770fcb in rtems


Ignore:
Timestamp:
Mar 3, 2016, 4:36:24 PM (4 years ago)
Author:
Joel Sherrill <joel@…>
Branches:
master
Children:
c3c57b1
Parents:
36717645
git-author:
Joel Sherrill <joel@…> (03/03/16 16:36:24)
git-committer:
Joel Sherrill <joel@…> (03/10/16 16:30:25)
Message:

Add shared PCI support and enhance pc386 to support non-legacy PCI configuration space

This patch fundamentally results from enhancements to the pc386 BSP
to support systems which do NOT have the legacy PCI BIOS. The
patch adds support for detecting when legacy PCI BIOS is not
present and then using IO space to access to PCI Configuration Space.
This resulted in dynamically selected between two implementations
of PCI and refactoring out the shared methods.

This patch adds shared implementations of pci_bus_count() and
pci_find_device(). Subsequent patches will remove implementations
of these methods in other BSPs where possible.

Location:
c/src/lib/libbsp
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/Makefile.am

    r36717645 rf770fcb  
    3030EXTRA_DIST += shared/include/bootcard.h
    3131
     32EXTRA_DIST += shared/pci/pci_bus_count.c
     33EXTRA_DIST += shared/pci/pci_find_device.c
     34
    3235include_bspdir = $(includedir)/bsp
    3336
  • c/src/lib/libbsp/i386/Makefile.am

    r36717645 rf770fcb  
    2323# shared/pci
    2424EXTRA_DIST += shared/pci/pcibios.c
     25EXTRA_DIST += shared/pci/pci_io.c
    2526
    2627include $(top_srcdir)/../../../automake/subdirs.am
  • c/src/lib/libbsp/i386/pc386/Makefile.am

    r36717645 rf770fcb  
    142142# pci
    143143libbsp_a_SOURCES += ../../i386/shared/pci/pcibios.c
     144libbsp_a_SOURCES += ../../i386/shared/pci/pci_io.c
     145libbsp_a_SOURCES += ../../shared/pci/pci_bus_count.c
     146libbsp_a_SOURCES += ../../shared/pci/pci_find_device.c
    144147
    145148include_HEADERS += ../../i386/shared/comm/uart.h
  • c/src/lib/libbsp/i386/pc386/include/bsp.h

    r36717645 rf770fcb  
    6060#include <rtems/score/cpu.h>
    6161#include <rtems/bspIo.h>
     62#include <rtems/pci.h>
    6263
    6364#ifdef __cplusplus
     
    276277void C_dispatch_isr(int vector);
    277278
     279/*
     280 * PCI Support Methods
     281 */
     282const pci_config_access_functions *pci_bios_initialize(void);
     283const pci_config_access_functions *pci_io_initialize(void);
     284
    278285#ifdef __cplusplus
    279286}
  • c/src/lib/libbsp/i386/pc386/startup/bspstart.c

    r36717645 rf770fcb  
    3535
    3636/*
     37 * PCI Bus Configuration
     38 */
     39rtems_pci_config_t BSP_pci_configuration = {
     40  (volatile unsigned char*)0,
     41  (volatile unsigned char*)0,
     42  NULL
     43};
     44
     45/*
    3746 * Helper to initialize the PCI Bus
    3847 */
     
    4049{
    4150#if (BSP_IS_EDISON == 0)
    42   int pci_init_retval;
     51  const pci_config_access_functions *pci_accessors;
    4352
    44   pci_init_retval = pci_initialize();
    45   if (pci_init_retval != PCIB_ERR_SUCCESS) {
    46       printk("PCI bus: could not initialize PCI BIOS interface\n");
     53  pci_accessors = pci_bios_initialize();
     54  if (pci_accessors != NULL) {
     55    printk("PCI bus: using PCI BIOS interface\n");
     56    BSP_pci_configuration.pci_functions = pci_accessors;
     57    return;
    4758  }
     59
     60  pci_accessors = pci_io_initialize();
     61  if (pci_accessors != NULL) {
     62    printk("PCI bus: using PCI I/O interface\n");
     63    BSP_pci_configuration.pci_functions = pci_accessors;
     64    return;
     65  }
     66
     67  printk("PCI bus: could not initialize PCI BIOS interface\n");
    4868#endif
    4969}
     
    6585  *edison_wd = 0x11f8;
    6686#endif
    67 
    6887
    6988  /*
  • c/src/lib/libbsp/i386/shared/pci/pcibios.c

    r36717645 rf770fcb  
    4141#define PCIB_DEVSIG_DEV(x) (((x)>>3) & 0x1f)
    4242#define PCIB_DEVSIG_FUNC(x) ((x) & 0x7)
    43 /*
    44  * Detects presense of PCI BIOS, returns
    45  * error code
    46  */
    47 int
    48 pci_initialize(void)
     43
     44/*
     45 * Forward reference. Initialized at bottom.
     46 */
     47static const pci_config_access_functions pci_bios_indirect_functions;
     48
     49/* prototype before defining */
     50const pci_config_access_functions *pci_bios_initialize(void);
     51
     52/*
     53 * Detects presense of PCI BIOS, returns pointer to accessor methods.
     54 */
     55const pci_config_access_functions *pci_bios_initialize(void)
    4956{
    5057  unsigned char *ucp;
    51   unsigned char sum;
    52   int      i;
     58  unsigned char  sum;
     59  int            i;
    5360
    5461  pcibInitialized = 0;
     
    8188  if (ucp >= (unsigned char *)0xFFFFF) {
    8289    /* BIOS-32 not found */
    83     return PCIB_ERR_NOTPRESENT;
     90    return NULL;
    8491  }
    8592
     
    103110  if ((pcibExchg[0] & 0xff) != 0) {
    104111    /* Not found */
    105     return PCIB_ERR_NOTPRESENT;
     112    return NULL;
    106113  }
    107114
     
    126133  if ((pcibExchg[0] & 0xff00) != 0) {
    127134    /* Not found */
    128     return PCIB_ERR_NOTPRESENT;
     135    return NULL;
    129136  }
    130137
    131138  if (pcibExchg[3] != 0x20494350) {
    132139    /* Signature does not match */
    133     return PCIB_ERR_NOTPRESENT;
     140    return NULL;
    134141  }
    135142
    136143  /* Success */
    137 
    138144  pcibInitialized = 1;
    139   return PCIB_ERR_SUCCESS;
    140 }
    141 
    142 /*
    143  * Find specified device and return its signature: combination
    144  * of bus number, device number and function number
    145  */
    146 static int
    147 pcib_find_by_devid(int vendorId, int devId, int idx, int *sig)
    148 {
    149   if (!pcibInitialized) {
    150     return PCIB_ERR_UNINITIALIZED;
    151   }
    152 
    153   pcibExchg[0] = pcibEntry;
    154   pcibExchg[1] = vendorId;
    155   pcibExchg[2] = devId;
    156   pcibExchg[3] = idx;
    157 
    158   __asm__ ("    pusha");
    159   __asm__ ("    movl pcibExchg, %edi");
    160   __asm__ ("    movb $0xb1, %ah");
    161   __asm__ ("    movb $0x02, %al");
    162   __asm__ ("    movl pcibExchg+4, %edx");
    163   __asm__ ("    movl pcibExchg+8, %ecx");
    164   __asm__ ("    movl pcibExchg+12, %esi");
    165   __asm__ ("    pushl %cs");
    166   __asm__ ("    call *%edi");
    167   __asm__ ("    movl %eax, pcibExchg");
    168   __asm__ ("    movl %ebx, pcibExchg+4");
    169   __asm__ ("    popa");
    170 
    171   *sig = pcibExchg[1] & 0xffff;
    172 
    173   return pcib_convert_err((pcibExchg[0] >> 8) & 0xff);
    174 }
    175 
    176 int
    177 pci_find_device(
    178   unsigned short vendorid,
    179   unsigned short deviceid,
    180   int instance,
    181   int *pbus,
    182   int *pdev,
    183   int *pfun
    184 )
    185 {
    186   int status;
    187   int sig = 0;
    188 
    189   status = pcib_find_by_devid( vendorid, deviceid, instance, &sig );
    190 
    191   *pbus = PCIB_DEVSIG_BUS(sig);
    192   *pdev = PCIB_DEVSIG_DEV(sig);
    193   *pfun = PCIB_DEVSIG_FUNC(sig);
    194   return status ? -1 : 0;
    195 }
    196 
    197 static uint8_t ucBusCount = 0xff;
    198 
    199 unsigned char
    200 pci_bus_count(void)
    201 {
    202   if ( ucBusCount == 0xff ) {
    203     unsigned char bus;
    204     unsigned char dev;
    205     unsigned char fun;
    206     unsigned char nfn;
    207     unsigned char hd = 0;
    208     uint32_t d = 0;
    209 
    210     ucBusCount = 0;
    211 
    212     for (bus=0; bus< 0xff; bus++) {
    213       for (dev=0; dev<PCI_MAX_DEVICES; dev++) {
    214         pci_read_config_dword(bus, dev, fun, PCI_VENDOR_ID, &d);
    215 
    216         if ( -1 == d ) {
    217           continue;
    218         }
    219 
    220         pci_read_config_byte(bus, dev, fun, PCI_HEADER_TYPE, &hd);
    221         nfn = (hd & 0x80) ? PCI_MAX_FUNCTIONS : 1;
    222 
    223         for ( fun=0; fun<nfn; fun++ ) {
    224 
    225           pci_read_config_dword(bus, dev, fun, PCI_VENDOR_ID, &d);
    226           if ( -1 == d )
    227             continue;
    228 
    229           pci_read_config_dword(bus, dev, fun, PCI_CLASS_REVISION, &d);
    230 
    231           if ( (d >> 16) == PCI_CLASS_BRIDGE_PCI ) {
    232             pci_read_config_byte(bus, dev, fun, PCI_SUBORDINATE_BUS, &hd);
    233 
    234             if ( hd > ucBusCount )
    235               ucBusCount = hd;
    236           }
    237 
    238         }
    239       }
    240     }
    241 
    242     if ( ucBusCount == 0 ) {
    243       printk("pci_bus_count() found 0 busses, assuming 1\n");
    244       ucBusCount = 1;
    245     } else if ( ucBusCount == 0xff ) {
    246       printk("pci_bus_count() found 0xff busses, assuming 1\n");
    247       ucBusCount = 1;
    248     }
    249   }
    250 
    251   return ucBusCount;
     145
     146  return &pci_bios_indirect_functions;
    252147}
    253148
     
    569464}
    570465
    571 const pci_config_access_functions pci_indirect_functions = {
     466static const pci_config_access_functions pci_bios_indirect_functions = {
    572467  BSP_pci_read_config_byte,
    573468  BSP_pci_read_config_word,
     
    577472  BSP_pci_write_config_dword
    578473};
    579 
    580 rtems_pci_config_t BSP_pci_configuration = {
    581   (volatile unsigned char*)0,
    582   (volatile unsigned char*)0,
    583   &pci_indirect_functions
    584 };
Note: See TracChangeset for help on using the changeset viewer.