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

📄 pciconfiglib.c

📁 ge公司的dv4av4信号处理板的bsp源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    int    vendorId,	/* vendor ID */
    int    deviceId,	/* device ID */
    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 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 */
    )
    {

    int	key;

#if 0
    UINT8 retval = 0;
    UINT32 retvallong = 0;
    STATUS retStat = ERROR;

    if (pciLibInitStatus != OK)			/* sanity check */
        return (ERROR);
#endif

    key = intLock ();				/* mutual exclusion start */

#if 0
    switch (pciConfigMech)
	{
        case PCI_MECHANISM_0:
            if (pciConfigRead (busNo, deviceNo, funcNo,
                               offset, 1, (void *)&retval)
		== ERROR)
		{
                retval = 0xff;
		}
	    else 

⌨️ 快捷键说明

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