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

📄 pciconfiglib.c

📁 ge公司的dv4av4信号处理板的bsp源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        return (ERROR);
	}
#endif
#endif

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

#if 0
    switch (pciConfigMech)
	{
        case PCI_MECHANISM_0:
            pciConfigWrite (busNo, deviceNo, funcNo, offset, 4, data);
            break;

	case PCI_MECHANISM_1:
	    PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (busNo, deviceNo, funcNo) |
		          (offset & 0xfc) | 0x80000000);
	    PCI_OUT_LONG (pciConfigAddr1, data);
	    break;

	case PCI_MECHANISM_2:
	    PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));
	    PCI_OUT_BYTE (pciConfigAddr1, busNo);
	    PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) |
			  (offset & 0xfc)), data);
	    PCI_OUT_BYTE (pciConfigAddr0, 0);
	    break;

	default:
	    break;
	}
#else
    bslPciConfigWrite32(busNo, deviceNo, funcNo, offset, data);
#endif

    intUnlock (key);				/* mutual exclusion stop */

    return (OK);
    }


/*****************************************************************************
*
* pciConfigModifyLong - Perform a masked longword register update
*
* This function writes a field into a PCI configuration header without
* altering any bits not present in the field.  It does this by first
* doing a PCI configuration read (into a temporary location) of the PCI
* configuration header word which contains the field to be altered.
* It then alters the bits in the temporary location to match the desired
* value of the field.  It then writes back the temporary location with
* a configuration write.  All configuration accesses are long and the
* field to alter is specified by the "1" bits in the 'bitMask' parameter.
*
* Be careful to using pciConfigModifyLong for updating the Command and
* status register.  The status bits must be written back as zeroes, else
* they will be cleared.  Proper use involves including the status bits in
* the mask value, but setting their value to zero in the data value.
*
* The following example will set the PCI_CMD_IO_ENABLE bit without clearing any
* status bits.  The macro PCI_CMD_MASK includes all the status bits as
* part of the mask.  The fact that PCI_CMD_MASTER doesn't include these bits,
* causes them to be written back as zeroes, therefore they aren't cleared.
*
* .CS
*    pciConfigModifyLong (b,d,f,PCI_CFG_COMMAND,
*                 (PCI_CMD_MASK | PCI_CMD_IO_ENABLE), PCI_CMD_IO_ENABLE);
* .CE
*
* Use of explicit longword read and write operations for dealing with any
* register containing "write 1 to clear" bits is sound policy.
*
* RETURNS: OK if operation succeeds, ERROR if operation fails.
*/

STATUS pciConfigModifyLong
    (
    int busNo,          /* bus number */
    int deviceNo,       /* device number */
    int funcNo,         /* function number */
    int offset,         /* offset into the configuration space */
    UINT32 bitMask,     /* Mask which defines field to alter */
    UINT32 data         /* data written to the offset */
    )
    {
    UINT32 temp;
    STATUS stat;
    int key;

    /* check for library initialization or unaligned access */

#ifdef PCI_CONFIG_OFFSET_NOCHECK
    if (pciLibInitStatus != OK)
	{
        return (ERROR);
	}
#else
    if ((pciLibInitStatus != OK) || ((offset & (int)0x3) > 0) )
	{
        return (ERROR);
	}
#endif
 
    key = intLock ();

    stat = pciConfigInLong (busNo, deviceNo, funcNo, offset, &temp);

    if (stat == OK)
	{
	temp = (temp & ~bitMask) | (data & bitMask);
	stat = pciConfigOutLong (busNo, deviceNo, funcNo, offset, temp);
	}

    intUnlock (key);

    return (stat);
    }


/*****************************************************************************
*
* pciConfigModifyWord - Perform a masked longword register update
*
* This function writes a field into a PCI configuration header without
* altering any bits not present in the field.  It does this by first
* doing a PCI configuration read (into a temporary location) of the PCI
* configuration header word which contains the field to be altered.
* It then alters the bits in the temporary location to match the desired
* value of the field.  It then writes back the temporary location with
* a configuration write.  All configuration accesses are long and the
* field to alter is specified by the "1" bits in the 'bitMask' parameter.
*
* Do not use this routine to modify any register that contains 'write 1
* to clear' type of status bits in the same longword.  This specifically
* applies to the command register.  Modify byte operations could potentially
* be implemented as longword operations with bit shifting and masking.  This
* could have the effect of clearing status bits in registers that aren't being
* updated.  Use pciConfigInLong and pciConfigOutLong, or pciModifyLong,
* to read and update the entire longword.
*
* RETURNS: OK if operation succeeds.  ERROR if operation fails.
*/

STATUS pciConfigModifyWord
    (
    int busNo,          /* bus number */
    int deviceNo,       /* device number */
    int funcNo,         /* function number */
    int offset,         /* offset into the configuration space */
    UINT16 bitMask,     /* Mask which defines field to alter */
    UINT16 data         /* data written to the offset */
    )
    {
    UINT16 temp;
    STATUS stat;
    int key;

    /* check for library initialization or unaligned access */

#ifdef PCI_CONFIG_OFFSET_NOCHECK
    if (pciLibInitStatus != OK)
	{
        return (ERROR);
	}
#else
    if ((pciLibInitStatus != OK) || ((offset & (int)0x1) > 0) )
	{
        return (ERROR);
	}
#endif
 
    key = intLock ();

    stat = pciConfigInWord (busNo, deviceNo, funcNo, offset, &temp);

    if (stat == OK)
	{
	temp = (temp & ~bitMask) | (data & bitMask);
	stat = pciConfigOutWord (busNo, deviceNo, funcNo, offset, temp);
	}

    intUnlock (key);

    return (stat);
    }



/*****************************************************************************
*
* pciConfigModifyByte - Perform a masked longword register update
*
* This function writes a field into a PCI configuration header without
* altering any bits not present in the field.  It does this by first
* doing a PCI configuration read (into a temporary location) of the PCI
* configuration header word which contains the field to be altered.
* It then alters the bits in the temporary location to match the desired
* value of the field.  It then writes back the temporary location with
* a configuration write.  All configuration accesses are long and the
* field to alter is specified by the "1" bits in the 'bitMask' parameter.
*
* Do not use this routine to modify any register that contains 'write 1
* to clear' type of status bits in the same longword.  This specifically
* applies to the command register.  Modify byte operations could potentially
* be implemented as longword operations with bit shifting and masking.  This
* could have the effect of clearing status bits in registers that aren't being
* updated.  Use pciConfigInLong and pciConfigOutLong, or pciModifyLong,
* to read and update the entire longword.
*
* RETURNS: OK if operation succeeds, ERROR if operation fails.
*/

STATUS pciConfigModifyByte
    (
    int busNo,          /* bus number */
    int deviceNo,       /* device number */
    int funcNo,         /* function number */
    int offset,         /* offset into the configuration space */
    UINT8 bitMask,      /* Mask which defines field to alter */
    UINT8 data          /* data written to the offset */
    )
    {
    UINT8 temp;
    STATUS stat;
    int key;

    /* check for library initialization or unaligned access */

    if (pciLibInitStatus != OK)
	{
        return (ERROR);
	}

 
    key = intLock ();

    stat = pciConfigInByte (busNo, deviceNo, funcNo, offset, &temp);

    if (stat == OK)
	{
	temp = (temp & ~bitMask) | (data & bitMask);
	stat = pciConfigOutByte (busNo, deviceNo, funcNo, offset, temp);
	}

    intUnlock (key);

    return (stat);

    }

/*******************************************************************************
*
* pciSpecialCycle - generate a special cycle with a message
*
* This routine generates a special cycle with a message.
*
* RETURNS: OK, or ERROR if this library is not initialized
*/

STATUS pciSpecialCycle
    (
    int	busNo,     /* bus number */
    UINT32 message /* data driven onto AD[31:0] */
    )
    {
    int deviceNo	= 0x0000001f;
    int funcNo		= 0x00000007;
    int key;

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

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

    switch (pciConfigMech)
	{

        case PCI_MECHANISM_0:
            if (pciConfigSpcl != NULL)
                pciConfigSpcl (busNo, message);
            break;
  
	case PCI_MECHANISM_1:
	    PCI_OUT_LONG (pciConfigAddr0, 
		          pciConfigBdfPack (busNo, deviceNo, funcNo) |
		          0x80000000);
	    PCI_OUT_LONG (pciConfigAddr1, message);
	    break;

	case PCI_MECHANISM_2:
	    PCI_OUT_BYTE (pciConfigAddr0, 0xff);
	    PCI_OUT_BYTE (pciConfigAddr1, 0x00);
	    PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8)),
			  message);
	    PCI_OUT_BYTE (pciConfigAddr0, 0);
	    break;

	default:
	    break;
	}

    intUnlock (key);				/* mutual exclusion stop */

    return (OK);
    }
#endif /* USE_PCI_SIMULATOR */

/**********************************************************************
*
* pciConfigForeachFunc - check condition on specified bus
*
* pciConfigForeachFunc() discovers the PCI functions present on the
* bus and calls a specified C-function for each one.  If the 
* function returns ERROR, further processing stops.
*
* pciConfigForeachFunc() does not affect any HOST<->PCI
* bridge on the system.
*
* ERRNO: not set
*
* RETURNS: OK normally, or ERROR if funcCheckRtn() doesn't return OK.
*/

STATUS pciConfigForeachFunc
    (
    UINT8 bus,			    /* bus to start on */
    BOOL recurse,		    /* if TRUE, do subordinate busses */
    PCI_FOREACH_FUNC funcCheckRtn,  /* routine to call for each PCI func */
    void *pArg			    /* argument to funcCheckRtn */
    )
    {
    int		pciLocBus;	/* PCI bus/device/function structure */
    int		pciLocDevice;	/* PCI bus/device/function structure */
    int		pciLocFunction;	/* PCI bus/device/function structure */
    int		device;		/* loop over devices */
    int		function;	/* loop over functions */
    UINT	devVend;
    UINT16	pciClass;	/* PCI class/subclass contents */
    int		status;
    UINT8	btemp;
    UINT8	secBus;		/* secondary bus, for recursion */
    UINT16	hostBridge = (PCI_CLASS_BRIDGE_CTLR<<8) |
			     PCI_SUBCLASS_HOST_PCI_BRIDGE;

    /* Begin the scanning process at [bus,0,0] */

    pciLocBus = (UINT8)bus;
    pciLocDevice = (UINT8)0;
    pciLocFunction = (UINT8)0;

    /* discover devices and perform check */

    /* Locate each active function on the current bus */

    for (device = 0; device < PCI_MAX_DEV; device++)
	{
	pciLocDevice = device;

	/* Check each function until an unused one is detected */

	for (function = 0; function < PCI_MAX_FUNC; function++)
	    {
	    pciLocFunction = function;

	    /* Check for a valid device/vendor number */
	    pciConfigInLong (pciLocBus, pciLocDevice, pciLocFunction,
			     PCI_CFG_VENDOR_ID, &devVend);

	    /* If function 0 then check next dev else check next function */
	    if ( ((devVend & 0x0ffff) == PCI_CONFIG_ABSENT_WORD_F) || 
		 ((devVend & 0x0ffff) == PCI_CONFIG_ABSENT_WORD_0) )
		{
		if (function == 0)
		    {
		    break;	/* non-existent device, goto next device */
		    }
		else
		    {
		    continue;  /* function empty, try the next function */
		    }
		}

	    /* Check to see if this function belongs to a PCI-PCI bridge */
	    pciConfigInWord (pciLocBus, pciLocDevice, pciLocFunction,
			     PCI_CFG_SUBCLASS, &pciClass);

	    if ( pciClass != hostBridge )
		{
	        /* call specified function */
	        status = (*funcCheckRtn)(pciLocBus, pciLocDevice,
					pciLocFunction, pArg);
		if ( status != OK )
		    return(ERROR);
		}

	    if ( recurse )
		{
		/* if P2P bridge, check that bus recursively */
		if ( pciClass == ((PCI_CLASS_BRIDGE_CTLR << 8) + PCI_SUBCLASS_P2P_BRIDGE) )
		    {
		    pciConfigInByte (pciLocBus, pciLocDevice, pciLocFunction,
				PCI_CFG_SECONDARY_BUS, &secBus);
		    if ( secBus > 0 )
		        status = pciConfigForeachFunc(secBus, recurse,
						funcCheckRtn, pArg)

⌨️ 快捷键说明

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