www.pudn.com > vxworks0108.rar > sysBusPci.c


/* sysBusPci.c - VG4 specific PCI bus support */

/*
modification history
--------------------
01a,27sep01,bem  written from LM4 01d
*/

/*
DESCRIPTION
This is the SBS VG4 platform specific pciAutoConfigLib information.
*/


/* includes */

#include "vxWorks.h"
#include "type.h"
#include "config.h"
#include "sysLib.h"
#include "vg4.h"
#include "pciConfigLib.h"
#include "pciIntLib.h"
#include "pciAutoConfigLib.h"
#include "sysBusPci.h"


#ifdef PCI_AUTO_DEBUG
#define PCI_AUTO_DEBUG_MSG(s, a, b, c, d, e, f) \
       { \
	printf(s, a, b, c, d, e, f); \
       }
#else
#define PCI_AUTO_DEBUG_MSG(s, a, b, c, d, e, f)
#endif 
   
   

/* static file scope locals */

LOCAL PCI_SYSTEM sysParams;

/* INT LINE TO IRQ assignment for VG4. */

LOCAL UCHAR sysPciIntRoute [][4] = {
    {         0xff,         0xff,         0xff,         0xff}, /* device number  0 - PCI Host bridge     */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  1 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  2 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  3 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  4 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  5 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  6 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  7 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  8 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number  9 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 10 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 11 - not available       */
    { PCI_INTB_LVL,         0xff,         0xff,         0xff}, /* device number 12 - Universe VME bridge */
    { PCI_INTA_LVL,         0xff,         0xff,         0xff}, /* device number 13 - ethernet controller */
    { PCI_INTC_LVL,         0xff,         0xff,         0xff}, /* device number 14 - SCSI controller     */
    { PCI_INTD_LVL, PCI_INTA_LVL, PCI_INTB_LVL, PCI_INTC_LVL}, /* device number 15 - PMC slot 1          */
    { PCI_INTC_LVL, PCI_INTD_LVL, PCI_INTA_LVL, PCI_INTB_LVL}, /* device number 16 - PMC slot 2          */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 17 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 18 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 19 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 20 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 21 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 22 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 23 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 24 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 25 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 26 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 27 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 28 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 29 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 30 - not available       */
    {         0xff,         0xff,         0xff,         0xff}, /* device number 31 - not available       */
};


/*******************************************************************************
*
* sysPciAutoConfig - PCI autoconfig support routine
*
* This routine instantiates the PCI_SYSTEM structure needed to configure
* the system. This consists of assigning address ranges to each category
* of PCI system resource: Prefetchable and Non-Prefetchable 32-bit Memory, and
* 16- and 32-bit I/O. Global values for the Cache Line Size and Maximum Latency
* are also specified. Finally, the four supplemental routines for device
* inclusion/exclusion, interrupt assignment, and pre- and post-enumeration
* bridge initialization are specified.
*
* RETURNS: N/A
*/


void sysPciAutoConfig (void)
    {

    /* 32-bit Non-prefetchable Memory Space */

    sysParams.pciMemIo32     = PCI_MSTR_MEMIO_BUS;
    sysParams.pciMemIo32Size = PCI_MSTR_MEMIO_SIZE;

    /*
     * if address range starts at 0, force non-zero to avoid allocating zero
     * which turns off BAR (per PCI spec).
     */

    if (sysParams.pciMemIo32 == 0)
    {
        sysParams.pciMemIo32     += 1;
        sysParams.pciMemIo32Size -= 1;
    }

    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMemIo32     = 0x%08x (0x%08x)\n",
			sysParams.pciMemIo32,
			TRANSLATE(sysParams.pciMemIo32,PCI_MSTR_MEMIO_BUS,
				  PCI_MSTR_MEMIO_LOCAL),
			0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMemIo32Size = 0x%08x\n",
			sysParams.pciMemIo32Size,0,0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMemIo32End  = 0x%08x (0x%08x)\n",
                       sysParams.pciMemIo32+sysParams.pciMemIo32Size,
                       TRANSLATE(sysParams.pciMemIo32+sysParams.pciMemIo32Size,
                                 PCI_MSTR_MEMIO_BUS, PCI_MSTR_MEMIO_LOCAL),
                       0,0,0,0);

    /* 32-bit Prefetchable Memory Space */

    sysParams.pciMem32     = PCI_MSTR_MEM_BUS;
#if TRUE
    sysParams.pciMem32Size = PCI_MSTR_MEM_SIZE;
#else
    sysParams.pciMem32Size = 0;
#endif /* TRUE */

    /*
     * if address range starts at 0, force non-zero to avoid allocating zero
     * which turns off BAR (per PCI spec).
     */

    if (sysParams.pciMem32 == 0)
    {
        sysParams.pciMem32     += 1;
        sysParams.pciMem32Size -= 1;
    }

    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMem32       = 0x%08x (0x%08x)\n",
                        sysParams.pciMem32,
                        TRANSLATE(sysParams.pciMem32,PCI_MSTR_MEM_BUS,
                                  PCI_MSTR_MEM_LOCAL),
			0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMem32Size   = 0x%08x\n",
                        sysParams.pciMem32Size,0,0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciMem32End    = 0x%08x (0x%08x)\n",
                        sysParams.pciMem32+sysParams.pciMem32Size,
                        TRANSLATE(sysParams.pciMem32+sysParams.pciMem32Size,
                                  PCI_MSTR_MEM_BUS,PCI_MSTR_MEM_LOCAL),
                        0,0,0,0);

    /* 16-bit ISA I/O Space */

    sysParams.pciIo16     = PCI_MSTR_ISA_IO_BUS  + ISA_LEGACY_SIZE;
    sysParams.pciIo16Size = PCI_MSTR_ISA_IO_SIZE - ISA_LEGACY_SIZE;


    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo16        = 0x%08x (0x%08x)\n",
                        sysParams.pciIo16,
                        TRANSLATE(sysParams.pciIo16,PCI_MSTR_ISA_IO_BUS,
                                  PCI_MSTR_ISA_IO_LOCAL),
                        0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo16Size    = 0x%08x\n",
                        sysParams.pciIo16Size,0,0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo16End     = 0x%08x (0x%08x)\n",
                        sysParams.pciIo16+sysParams.pciIo16Size,
                        TRANSLATE(sysParams.pciIo16+sysParams.pciIo16Size,
                                  PCI_MSTR_ISA_IO_BUS, PCI_MSTR_ISA_IO_LOCAL),
                        0,0,0,0);

    /* 32-bit PCI I/O Space */

    sysParams.pciIo32     = PCI_MSTR_IO_BUS;
    sysParams.pciIo32Size = PCI_MSTR_IO_SIZE;

    /*
     * if address range starts at 0, force non-zero to avoid allocating zero
     * which turns off BAR (per PCI spec).
     */

    if (sysParams.pciIo32 == 0)
        {
        sysParams.pciIo32     += 1;
        sysParams.pciIo32Size -= 1;
        }

    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo32        = 0x%08x (0x%08x)\n",
                        sysParams.pciIo32,
                        TRANSLATE(sysParams.pciIo32,PCI_MSTR_IO_BUS,
                                  PCI_MSTR_IO_LOCAL),
                        0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo32Size    = 0x%08x\n",
                        sysParams.pciIo32Size,0,0,0,0,0);
    PCI_AUTO_DEBUG_MSG("sysPciAutoConfig: pciIo32End     = 0x%08x (0x%08x)\n",
                        sysParams.pciIo32+sysParams.pciIo32Size,
                        TRANSLATE(sysParams.pciIo32+sysParams.pciIo32Size,
                                  PCI_MSTR_IO_BUS, PCI_MSTR_IO_LOCAL),
                        0,0,0,0);

    /* Configuration space parameters */

    sysParams.maxBus        = 0;
    sysParams.cacheSize     = ( _CACHE_ALIGN_SIZE / 4 );
    sysParams.maxLatency    = PCI_LAT_TIMER;

    /*
     * Interrupt routing strategy
     * across PCI-to-PCI Bridges
     */

    sysParams.autoIntRouting    = TRUE;

    /* Device inclusion and interrupt routing routines */

    sysParams.includeRtn    = sysPciAutoConfigInclude;
    sysParams.intAssignRtn  = sysPciAutoConfigIntrAssign;

    /*
     * PCI-to-PCI Bridge Pre-
     * and Post-enumeration init
     * routines
     */

    sysParams.bridgePreConfigInit  =
            sysPciAutoconfigPreEnumBridgeInit;
    sysParams.bridgePostConfigInit =
            sysPciAutoconfigPostEnumBridgeInit;

    /* Perform AutoConfig */

    pciAutoConfig (&sysParams);

    }

/*******************************************************************************
*
* sysPciAutoConfigInclude - PCI autoconfig support routine
*
* RETURNS: OK or ERROR for the MPC106 or WINBOND devices.
*/

STATUS sysPciAutoConfigInclude
    (
    PCI_SYSTEM * pSys,      /* input: AutoConfig system information */
    PCI_LOC *    pciLoc,    /* input: PCI address of this function */
    UINT         devVend    /* input: Device/vendor ID number      */
    )
    {
    BOOL retVal = OK;

    /* If it's the host bridge then exclude it */

    if ((pciLoc->bus == 0) && (pciLoc->device == 0) && (pciLoc->function == 0))
        {
        return ERROR;
        }

    switch(devVend)
        {

        /* EXCLUDED Devices */

        case PCI_ID_CHAPARRAL:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoConfigInclude: Excluding MPC107\n",
                               0, 0, 0, 0, 0, 0);
            break;

        case PCI_ID_IBC:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding IBC\n",
                               0, 0, 0, 0, 0, 0);
            break;

#if !defined (INCLUDE_SCSI)
        case PCI_ID_SCSI:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding SCSI\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* !defined (INCLUDE_SCSI) */

#if !defined (INCLUDE_USB)
        case PCI_ID_USB:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding USB\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* !defined (INCLUDE_USB) */

#if !defined (INCLUDE_IDE)
        case PCI_ID_IDE:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding IDE\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* !defined (INCLUDE_IDE) */

#if !defined (INCLUDE_PMU)
        case PCI_ID_PMU:
            retVal = ERROR;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Excluding PMU\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* !defined (INCLUDE_PMU) */


    /* INCLUDED Devices */

        case PCI_ID_LN_DEC:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoConfigInclude: Including ethernet\n",
                0, 0, 0, 0, 0, 0);
            break;

        case PCI_ID_UNIVERSE:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including Universe\n",
                               0, 0, 0, 0, 0, 0);
            break;

#if defined (INCLUDE_SCSI)
        case PCI_ID_SCSI:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoConfigInclude: Including SCSI\n",
                0, 0, 0, 0, 0, 0);
            break;
#endif /* defined (INCLUDE_SCSI) */

#if defined (INCLUDE_USB)
        case PCI_ID_USB:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including USB\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* defined (INCLUDE_USB) */

#if defined (INCLUDE_IDE)
        case PCI_ID_IDE:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including IDE\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* defined (INCLUDE_IDE) */

#if defined (INCLUDE_PMU)
        case PCI_ID_PMU:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including pmu\n",
                               0, 0, 0, 0, 0, 0);
            break;
#endif /* defined (INCLUDE_PMU) */

        case PCI_ID_I82559:
        case PCI_ID_I82559ER:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoconfigInclude: Including i82559\n",
				0, 0, 0, 0, 0, 0);
            break;

        case PCI_ID_DEC21152:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG("sysPciAutoConfigInclude: Including PCI-to-PCI bridge 21152\n",
                0, 0, 0, 0, 0, 0);
            break;

        default:
            retVal = OK;
            PCI_AUTO_DEBUG_MSG(
                "sysPciAutoConfigInclude: Including unknown device /
                 (vendor ID: %04x, device ID: %04x)\n",
                 devVend & 0xffff, devVend >> 16, 0, 0, 0, 0);
            break;
        }

    return (retVal); /* AutoConfigure all devices */
    }

/*******************************************************************************
*
* sysPciAutoConfigIntrAssign - PCI autoconfig support routine
*
* RETURNS: PCI interrupt line number given pin mask
*/

UCHAR sysPciAutoConfigIntrAssign
    (
    PCI_SYSTEM * pSys,      /* input: AutoConfig system information */
    PCI_LOC *    pFunc,     /* input: function's location in the system */
    UCHAR        intPin     /* input: interrupt pin number */
    )
    {
    UCHAR irqValue = 0xff;

    /*
     * Ensure this is a resonable value for bus zero.
     * If OK, return INT level, else we return 0xff.
     */

    if ((intPin > 0) && (intPin < 5))
    {
        irqValue = sysPciIntRoute [(pFunc->device)][(intPin - 1)];
    }

    PCI_AUTO_DEBUG_MSG("intAssign called for device [%d %d %d] IRQ: %d\n",
			pFunc->bus, pFunc->device, pFunc->function,
			irqValue, 0, 0 );

    /* return the value to be assigned to the pin */

    return (irqValue);
    }


/*******************************************************************************
*
* sysPciAutoconfigPreEnumBridgeInit - PCI autoconfig support routine
*
* RETURNS: N/A
*/


void sysPciAutoconfigPreEnumBridgeInit
    (
    PCI_SYSTEM * pSys,          /* PCI_SYSTEM structure pointer */
    PCI_LOC * pLoc,         /* pointer to function in question */
    UINT devVend            /* deviceID/vendorID of device */
    )
    {
    PCI_AUTO_DEBUG_MSG(
        "sysPciAutoconfigPreEnumBridgeInit: vendor ID: %04x, device ID: %04x)\n",
         devVend & 0xffff, devVend >> 16, 0, 0, 0, 0);
    return;
    }


/*******************************************************************************
*
* sysPciAutoconfigPostEnumBridgeInit - PCI autoconfig support routine
*
* RETURNS: N/A
*/

void sysPciAutoconfigPostEnumBridgeInit
    (
    PCI_SYSTEM * pSys,          /* PCI_SYSTEM structure pointer */
    PCI_LOC * pLoc,         /* pointer to function in question */
    UINT devVend            /* deviceID/vendorID of device */
    )
    {
    PCI_AUTO_DEBUG_MSG(
        "sysPciAutoconfigPostEnumBridgeInit: vendor ID: %04x, device ID: %04x)\n",
         devVend & 0xffff, devVend >> 16, 0, 0, 0, 0);
    return;
    }