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

📄 pciconfiglib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    int    funcNo;    UINT32 device;    UINT32 vendor;    UINT8  header;    if (pciLibInitStatus != OK)			/* sanity check */        cont = FALSE;    for (busNo = 0; cont == TRUE && busNo <= pciMaxBus; busNo++)        for (deviceNo = 0;	     ((cont == TRUE) && (deviceNo < PCI_MAX_DEV));	     ++deviceNo)            for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++)		{		/* avoid a special bus cycle */		if ((deviceNo == 0x1f) && (funcNo == 0x07))		    continue;		pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID,				 &vendor);		/*		 * If nonexistent device, skip to next, only look at		 * vendor ID field for existence check		 */		if (((vendor & 0x0000ffff) == 0x0000FFFF) && (funcNo == 0))		    break;		device  = vendor >> 16;		device &= 0x0000FFFF;		vendor &= 0x0000FFFF;		if ((vendor == (UINT32)vendorId) &&		    (device == (UINT32)deviceId) &&		    (index-- == 0))		    {		    *pBusNo	= busNo;		    *pDeviceNo	= deviceNo;		    *pFuncNo	= funcNo;		    status	= OK;		    cont	= FALSE;	/* terminate all loops */		    continue;		    }		/* goto next if current device is single function */		pciConfigInByte (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE, 				 &header);		if ((header & PCI_HEADER_MULTI_FUNC) != PCI_HEADER_MULTI_FUNC &&		    funcNo == 0)		    break;		}    return (status);    }/********************************************************************************* pciFindClass - find the nth occurence of a device by PCI class code.** This routine finds the nth device with the given 24-bit PCI class code* (class subclass prog_if).* * The classcode arg of must be carfully constructed from class and sub-class* macros.  * * Example : To find an ethernet class device, construct the classcode arg * as follows:** .CS*     ((PCI_CLASS_NETWORK_CTLR << 16 | PCI_SUBCLASS_NET_ETHERNET << 8))* .CE** RETURNS:* OK, or ERROR if the class didn't match.*/STATUS pciFindClass    (    int    classCode,	/* 24-bit class code */    int	   index,	/* desired instance of device */    int *  pBusNo,	/* bus number */    int *  pDeviceNo,	/* device number */    int *  pFuncNo	/* function number */    )    {    STATUS status = ERROR;    BOOL   cont   = TRUE;    int    busNo;    int    deviceNo;    int    funcNo;    UINT32 classCodeReg;    UINT32 vendor;    UINT8  header;    if (pciLibInitStatus != OK)			/* sanity check */        cont = FALSE;    for (busNo = 0; cont == TRUE && busNo <= pciMaxBus; busNo++)        for (deviceNo = 0;	     ((cont == TRUE) && (deviceNo < PCI_MAX_DEV));	     ++deviceNo)            for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++)		{		/* avoid a special bus cycle */		if ((deviceNo == 0x1f) && (funcNo == 0x07))		    continue;		pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID,				 &vendor);		/*		 * If nonexistent device, skip to next, only look at		 * vendor ID field for existence check		 */		if (((vendor & 0x0000ffff) == 0x0000FFFF) && (funcNo == 0))		    break;			pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_REVISION,				 &classCodeReg);		if ((((classCodeReg >> 8) & 0x00ffffff) == classCode) &&		    (index-- == 0))		    {		    *pBusNo	= busNo;		    *pDeviceNo	= deviceNo;		    *pFuncNo	= funcNo;		    status	= OK;		    cont 	= FALSE;	/* terminate all loops */		    continue;		    }		/* goto next if current device is single function */		pciConfigInByte (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE, 				 &header);		if ((header & PCI_HEADER_MULTI_FUNC) != PCI_HEADER_MULTI_FUNC &&		    funcNo == 0)		    break;		}    return (status);    }/******************************************************************************** pciDevConfig - configure a device on a PCI bus** This routine configures a device that is on a Peripheral Component* Interconnect (PCI) bus by writing to the configuration header of the* selected device.** It first disables the device by clearing the command register in the* configuration header.  It then sets the I/O and/or memory space base* address registers, the latency timer value and the cache line size.* Finally, it re-enables the device by loading the command register with* the specified command.** NOTE: This routine is designed for Type 0 PCI Configuration Headers ONLY.* It is NOT usable for configuring, for example, a PCI-to-PCI bridge.** RETURNS: OK always.*/STATUS pciDevConfig    (    int pciBusNo,          /* PCI bus number */    int pciDevNo,          /* PCI device number */    int pciFuncNo,         /* PCI function number */    UINT32 devIoBaseAdrs,  /* device IO base address */    UINT32 devMemBaseAdrs, /* device memory base address */    UINT32 command         /* command to issue */    )    {    INT32       ix;    UINT32      tmp32;    /*     * Disable device by clearing its command register field in its     * configuration header. Write 0 clears command and preserves status.     */    pciConfigOutLong (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND,			0x0);    /*     *  Due to system constraints, this is a partial implementation     *  of enabling the Base Address Registers (BARs).     *  It is hoped that all PCI devices only require at most one     *  I/O space and/or one memory space.     *  If not, this code will re-allocate the device's memory to     *  each BAR implemented.  Sounds like future trouble!     */    for (ix = PCI_CFG_BASE_ADDRESS_0; ix <= PCI_CFG_BASE_ADDRESS_5; ix+=4)        {        /* Write all f's and read back value */        pciConfigOutLong (pciBusNo, pciDevNo, pciFuncNo, ix, 0xffffffff);        pciConfigInLong  (pciBusNo, pciDevNo, pciFuncNo, ix, &tmp32);        /* BAR implemented? */        if (tmp32 == 0)           {           /*            *   No! According to the spec, BARs must be implemented            *   in sequence starting at BAR 0.  So, all done.            */           break;           }        /* I/O space requested? */        /* Yes, set specified I/O space base address  */        if (tmp32 & 0x1)           {           pciConfigOutLong (pciBusNo, pciDevNo, pciFuncNo, ix,			     devIoBaseAdrs | 0x1);           }        /* No, memory space required, set specified base address */        else           {           pciConfigOutLong (pciBusNo, pciDevNo, pciFuncNo, ix,			     devMemBaseAdrs & ~0x1);           }        }    /* Configure Cache Line Size Register */    pciConfigOutByte (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_CACHE_LINE_SIZE,		      PCI_CACHE_LINE_SIZE);    /* Configure Latency Timer */    pciConfigOutByte (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_LATENCY_TIMER,		      PCI_LATENCY_TIMER);    /*     * Enable the device's capabilities as specified, do not     * reset any status bits in doing so.     */    pciConfigModifyLong (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND,  		      (PCI_CMD_MASK | command), command);    return (OK);    }/********************************************************************************* pciConfigBdfPack - pack parameters for the Configuration Address Register** This routine packs three parameters into one integer for accessing the* Configuration Address Register** RETURNS: packed integer encoded version of bus, device, and function numbers.*/int pciConfigBdfPack    (    int	busNo,    /* bus number */    int	deviceNo, /* device number */    int	funcNo    /* function number */    )    {    return (((busNo    << 16) & 0x00ff0000) |	    ((deviceNo << 11) & 0x0000f800) |	    ((funcNo   << 8)  & 0x00000700));    }/********************************************************************************* pciConfigExtCapFind - find extended capability in ECP linked list** This routine searches for an extended capability in the linked list of * capabilities in config space. If found, the offset of the first byte * of the capability of interest in config space is returned via pOffset.** RETURNS: OK if Extended Capability found, ERROR otherwise*/STATUS pciConfigExtCapFind    (    UINT8 extCapFindId,    /* Extended capabilities ID to search for */    int bus,               /* PCI bus number */    int device,            /* PCI device number */    int function,          /* PCI function number */    UINT8 * pOffset        /* returned config space offset */    )    {    STATUS retStat = ERROR;    UINT16 tmpStat;    UINT8  tmpOffset;    UINT8  capOffset = 0x00;    UINT8  capId = 0x00;    /* Check to see if the device has any extended capabilities */    pciConfigInWord(bus, device, function, PCI_CFG_STATUS, &tmpStat);    if ((tmpStat & PCI_STATUS_NEW_CAP) == 0)        {        return retStat;        }    /* Get the initial ECP offset and make longword aligned */    pciConfigInByte(bus, device, function, PCI_CFG_CAP_PTR, &capOffset);    capOffset &= ~0x02;    /* Bounds check the ECP offset */    if (capOffset < 0x40)        {        return retStat;        }    /* Look for the specified Extended Cap item in the linked list */    while (capOffset != 0x00)        {        /* Get the Capability ID and check */        pciConfigInByte(bus, device, function, (int)capOffset, &capId);        if (capId == extCapFindId)            {            *pOffset = (capOffset + (UINT8)0x02);            retStat = OK;            break;            }        /* Get the offset to the next New Capabilities item */        tmpOffset = capOffset + (UINT8)0x01;        pciConfigInByte(bus, device, function, (int)tmpOffset, &capOffset);        }    return retStat;        }#ifndef USE_PCI_SIMULATOR/********************************************************************************* pciConfigInByte - read one byte from the PCI configuration space** This routine reads one byte from the PCI configuration space** RETURNS: OK, or ERROR if this library is not initialized*/STATUS pciConfigInByte    (    int	busNo,    /* bus number */    int	deviceNo, /* device number */    int	funcNo,	  /* function number */    int	offset,	  /* offset into the configuration space */    UINT8 * pData /* data read from the offset */    )    {    UINT8 retval = 0;    UINT32 retvallong = 0;    STATUS retStat = ERROR;    int	key;    if (pciLibInitStatus != OK)			/* sanity check */        return (ERROR);    key = intLock ();				/* mutual exclusion start */    switch (pciConfigMech)	{        case PCI_MECHANISM_0:            if (pciConfigRead (busNo, deviceNo, funcNo,                               offset, 1, (void *)&retval)		== ERROR)		{                retval = 0xff;		}	    else 		{		retStat = OK;		}            break;	case PCI_MECHANISM_1:	    PCI_OUT_LONG (pciConfigAddr0, 		          pciConfigBdfPack (busNo, deviceNo, funcNo) |		          (offset & 0xfc) | 0x80000000);	    retval = PCI_IN_BYTE (pciConfigAddr1 + (offset & 0x3));	    retStat = OK;	    break;	case PCI_MECHANISM_2:	    PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));	    PCI_OUT_BYTE (pciConfigAddr1, busNo);	    retvallong =		PCI_IN_LONG(pciConfigAddr2 | ((deviceNo & 0x000f) << 8) \			| (offset & 0xfc));	    PCI_OUT_BYTE (pciConfigAddr0, 0);	    retvallong >>= (offset & 0x03) * 8;	    retval = (UINT8)(retvallong & 0xff);	    retStat = OK;

⌨️ 快捷键说明

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