⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syspciinit.c

📁 VxWorks下 Spruce的BSP源代码
💻 C
字号:
/* sysPciInit.c - IBM CPC700-specific PCI initialization *//*******************************************************************************   This source and object code has been made available to you by IBM on an   AS-IS basis.   IT IS PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING THE WARRANTIES OF   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE OR OF   NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL IBM OR ITS   LICENSORS BE LIABLE FOR INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES.   IBM'S OR ITS LICENSOR'S DAMAGES FOR ANY CAUSE OF ACTION, WHETHER IN   CONTRACT OR IN TORT, AT LAW OR AT EQUITY, SHALL BE LIMITED TO A MAXIMUM   OF $1,000 PER LICENSE.  Anyone receiving this source or object code is   licensed under IBM copyrights to use it in any way he or she deems fit,   including copying it, modifying it, compiling it, and redistributing it   either with or without modifications.  No license under IBM patents or   patent applications is to be implied by the copyright license.   Any user of this software should understand that neither IBM nor its   licensors will be responsible for any consequences resulting from the   use of this software.   Any person who transfers this object code or any derivative work must   include the IBM copyright notice in the transferred software.   COPYRIGHT   I B M   CORPORATION 1999   LICENSED MATERIAL  -  PROGRAM PROPERTY OF  I B M"*******************************************************************************//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/* modification history-----------------------01c,21jun02,pch  remove functionality which duplicates generic pciConfigLib,		 but retain CPC700 initialization; rename to sysPciInit.		 Import autoconfig support from Walnut.01b,27mar01,kab  Removed IBM support info per request01a,08mar99,mcg  created from IBM OpenBIOS eval kit software*//*This library provides functions to initialize and configure the PCI buson the Spruce board.*/#define  PCI_STATUS_66MHZ_CAPABLE  0x0020/* globals */PCI_SYSTEM sysPciParams;/* * For each of the 4 PCI expansion slot on the Spruce board, the INTA, INTB, * INTC, and INTD pins are wire-ORed together.  Each wire-ORed signal is then * connected to a unique pin on the CPC700. */#define DEV1_INT    INT_VEC_PCI_SLOT3     /* INTA/B/C/D for PCI slot 3 (J25) */#define DEV2_INT    INT_VEC_PCI_SLOT2     /* INTA/B/C/D for PCI slot 2 (J26) */#define DEV3_INT    INT_VEC_PCI_SLOT1     /* INTA/B/C/D for PCI slot 1 (J29) */#define DEV4_INT    INT_VEC_PCI_SLOT0     /* INTA/B/C/D for PCI slot 0 (J31) */static UCHAR intLine [][4] =    {    /*    IntA      IntB      IntC      IntD                            */        { 0xff,     0xff,     0xff,     0xff     },  /* device number 0 */        { DEV1_INT, DEV1_INT, DEV1_INT, DEV1_INT },  /* device number 1 */        { DEV2_INT, DEV2_INT, DEV2_INT, DEV2_INT },  /* device number 2 */        { DEV3_INT, DEV3_INT, DEV3_INT, DEV3_INT },  /* device number 3 */        { DEV4_INT, DEV4_INT, DEV4_INT, DEV4_INT }   /* device number 4 */    };/* forward declarations */LOCAL UCHAR sysPciAutoConfigIntAsgn ( PCI_SYSTEM * pSys, PCI_LOC * pFunc,    UCHAR intPin );LOCAL STATUS sysPciAutoConfigInclude ( PCI_SYSTEM *pSys, PCI_LOC *pciLoc,    UINT devVend );LOCAL void sysPciAutoConfig (void);/******************************************************************************** sysPciInit - Initialize the CPC700 PCI Configuration regs and attached devices** Initializes the CPC700 PCI configuration registers so that it can operate* as both a PCI initiator and target.* Parameters set are:*     CPU->PCI (master/initiator) address translation*     PCI->CPU (slave/target) address translation** This routine assumes the PowerPC processor and CPC700 bridge chip* are in a PCI host environment.** RETURNS: N/A*/void sysPciInit()    {    unsigned long  temp_long;    unsigned short temp_short;    unsigned char  temp_char;    /*     * Drive PCI Reset out.  This is done mainly for warm start.     * Reset must be held for at least 1ms.     */    pciConfigInWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		    PCI_CFG_BRIDGE_OPT2, &temp_short);    pciConfigOutWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		     PCI_CFG_BRIDGE_OPT2, temp_short | 0x0008);    sysLocalDelay(1);    pciConfigOutWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		     PCI_CFG_BRIDGE_OPT2, temp_short);    /*     * Set up the PCI Master configuration (PMM).  This is the local memory     * address to PCI memory address mapping.     * See config.h     */    sysPciOutLong(PMM0LA,    PMM0_LOCAL_ADRS);          /* PMM region 0 */    sysPciOutLong(PMM0PCILA, PMM0_PCI_LOW_ADRS);    sysPciOutLong(PMM0PCIHA, PMM0_PCI_HIGH_ADRS);    sysPciOutLong(PMM0MA,    PMM0_PCI_MASK_ATTRIB);    sysPciOutLong(PMM1LA,    PMM1_LOCAL_ADRS);          /* PMM region 1 */    sysPciOutLong(PMM1PCILA, PMM1_PCI_LOW_ADRS);    sysPciOutLong(PMM1PCIHA, PMM1_PCI_HIGH_ADRS);    sysPciOutLong(PMM1MA,    PMM1_PCI_MASK_ATTRIB);    sysPciOutLong(PMM2LA,    PMM2_LOCAL_ADRS);          /* PMM region 2 */    sysPciOutLong(PMM2PCILA, PMM2_PCI_LOW_ADRS);    sysPciOutLong(PMM2PCIHA, PMM2_PCI_HIGH_ADRS);    sysPciOutLong(PMM2MA,    PMM2_PCI_MASK_ATTRIB);    /*     * Set up the PCI Target configuration (PTM).  This is the PCI memory     * address to local memory address mapping.     * See config.h     * If region two is not being used, we must make sure that its enable bit     * is turned off!!  The enable bit for region 1 is hardwired on.     */    sysPciOutLong(PTM1LA,    PTM1_LOCAL_ADRS);    sysPciOutLong(PTM1MS,    PTM1_SIZE_ATTRIB);    /*     * It is possible that the enable bit in PTM2MS could be set at power up.     * If PTM2 is not going to be used, we must make sure that PTM2 is properly     * disabled to avoid PCI target conflicts.  PTM2MS must be enabled to write     * PTM 2 BAR.  Zero out PTM 2 BAR, then disable via PTM2MS.     */    if (PTM2_SIZE_ATTRIB == PTM_UNUSED)                /* PTM2 not being used */        {        sysPciOutLong(PTM2LA, PTM_UNUSED);        sysPciOutLong(PTM2MS, PTM_ENABLE);             /* enable temporarily */        pciConfigOutLong(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,			 PCI_CFG_BASE_ADDRESS_2, PTM_UNUSED);        sysPciOutLong(PTM2MS, PTM_UNUSED);             /* now disable */        }    else                                               /* PTM2 will be used */        {        sysPciOutLong(PTM2LA,    PTM2_LOCAL_ADRS);        sysPciOutLong(PTM2MS,    PTM2_SIZE_ATTRIB);        }    /*     * Write the CPC700 PCI Configuration regs.     *   Enable CPC700 to be a master on the PCI bus (PMM).     *   Enable CPC700 to act as a PCI memory target (PTM).     */    pciConfigInWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		    PCI_CFG_COMMAND, &temp_short);    temp_short = temp_short | PCI_CMD_MASTER_ENABLE | PCI_CMD_MEM_ENABLE;    pciConfigOutWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		     PCI_CFG_COMMAND, temp_short);    /*     * Read the CPC700 Strapping Pin Register.     * If the internal PCI arbiter is disabled, enable the external PCI arbiter.     * Check to be sure the internal arbiter is not being used if the PCI     * bus speed is greater than 33MHz.     * The Spruce board is currently not configurable for 66MHz PCI, but if     * a custom board can be designed that is.  In this case...     * If the both the PCI_66_STRAP and TSIZ(2) pins are pulled up, the PCI     * bus is capable of running at 66MHz.  Set the 66MHz capable bit in the     * CPC700 PCI Status register if this is the case.     */    temp_long = sysInLong(CPRSTRAPREAD);    if ((temp_long & MUXARBPAR) == 0)        /* internal arbiter is disabled */    {        temp_char = sysInByte(FPGA_REG_B);       /* enable external arbiter  */        sysOutByte(FPGA_REG_B, temp_char | PCI_ARB_CTL);    }    if (temp_long & PCIFREQ1)                    /* PCI_66_STRAP pulled up   */    {        if (temp_long & MUXARBPAR)               /* internal arbiter selected */        {            printf("\n ERROR : The internal PCI arbiter cannot be used when\n");            printf("the PCI bus speed is faster than 33MHz.");            while(1);        }        if (temp_long & PCIFREQ0)        {            pciConfigInWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,			    PCI_CFG_STATUS, &temp_short);            pciConfigOutWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		      PCI_CFG_STATUS, (temp_short | PCI_STATUS_66MHZ_CAPABLE));        }    }    /*     * Default value of the Bridge Options1 register is OK (0xFF60).     * No need to change it.     */    /*     * Set Bridge Options2 register.  On the Spruce board, the PCI bus is run     * asynchronously to the processor bus.  This was necessary to be able to     * run the PCI bus at speeds higher than 33MHz.     *   Bits  7:3  '10010'b  Initial Target Latency Timer = 18 (MITL=32)     *   Bits 11:8   '0010'b  Subsequent Target Latency    =  2     */    pciConfigOutWord(CPC700_PCI_BUS, CPC700_PCI_DEV, CPC700_PCI_FUNC,		     PCI_CFG_BRIDGE_OPT2, 0x0290);    sysPciAutoConfig();    }/******************************************************************************** sysPciAutoConfigInclude - Determine if function is to be autoConfigured** This function is called with PCI bus, device, function, and vendor* information.  It returns an indication of whether or not the particular* function should be included in the automatic configuration process.* This capability is useful if it is desired that a particular function* NOT be automatically configured.  Of course, if the device is not* included in automatic configuration, it will be unusable unless the* user's code made provisions to configure the function outside of the* the automatic process.** RETURNS: TRUE if function is to be included in automatic configuration,* FALSE otherwise.*/LOCAL 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 == CPC700_PCI_BUS)     && (pciLoc->device == CPC700_PCI_DEV)     && (pciLoc->function == CPC700_PCI_FUNC))        return ERROR;    switch(devVend)        {        /* TODO - add any excluded devices by device/vendor ID here */        default:            retVal = OK;            break;        }    return retVal;    }/******************************************************************************** sysPciAutoConfigIntAssign - Assign the "interrupt line" value** RETURNS: "interrupt line" value.**/LOCAL UCHAR sysPciAutoConfigIntAsgn    (    PCI_SYSTEM * pSys,          /* input: AutoConfig system information */    PCI_LOC * pFunc,    UCHAR intPin                /* input: interrupt pin number */    )    {    UCHAR irqValue = 0xff;    /* Calculated value                */    if (intPin == 0)        return irqValue;    irqValue = intLine [(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 (irqValue);    }/********************************************************************************* 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 */    sysPciParams.pciMemIo32 = PCI_MEMORY_START;    sysPciParams.pciMemIo32Size = 0x20000000;	/* 512MB */    /* 32-bit Prefetchable Memory Space */    sysPciParams.pciMem32= 0;    sysPciParams.pciMem32Size = 0;    /* 16-bit ISA I/O Space not supported */    sysPciParams.pciIo16 = 0;    sysPciParams.pciIo16Size = 0;    /* 32-bit PCI I/O Space */    sysPciParams.pciIo32 = 0;    sysPciParams.pciIo32Size = 0;    /* Configuration space parameters */    sysPciParams.cacheSize = (_CACHE_ALIGN_SIZE / sizeof(UINT32));    sysPciParams.maxLatency = 0;    sysPciParams.autoIntRouting = TRUE;    sysPciParams.includeRtn = sysPciAutoConfigInclude;    sysPciParams.intAssignRtn = sysPciAutoConfigIntAsgn;    sysPciParams.bridgePreConfigInit = NULL;    sysPciParams.bridgePostConfigInit = NULL;    /* Perform AutoConfig */    pciAutoConfig (&sysPciParams);    return;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -