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

📄 pciconfiglib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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);		    else			status = OK;		    if ( status != OK )			return(ERROR);		    }		}	    /* Proceed to next device if this is a single function device */	    if (function == 0)		{		pciConfigInByte (pciLocBus, pciLocDevice, pciLocFunction,				 PCI_CFG_HEADER_TYPE, &btemp);		if ((btemp & PCI_HEADER_MULTI_FUNC) == 0)		    {		    break; /* No more functions - proceed to next PCI device */		    }		}	    }	}    return(OK);    }/************************************************************************ pciFuncDisable - disable the specified function** pciFuncDisable() disables the function by turning off various*	enable bits of the command register** ERRNO: not set** RETURNS: OK, always** NOMANUAL*/LOCAL STATUS pciFuncDisable    (    UINT	bus,		/* bus */    UINT	device,		/* device */    UINT	function,	/* function */    void *	pArg		/* ignored */    )    {    int		mask;    mask = 	PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE |		PCI_CMD_MASTER_ENABLE;    pciConfigModifyLong (bus, device, function,			PCI_CFG_COMMAND, mask, 0);    return(OK);    }/************************************************************************ pciConfigReset - disable cards for warm boot** pciConfigReset() goes through the list of PCI functions* at the top-level bus and disables them, preventing them* from writing to memory while the system is trying to reboot.** ERRNO: Not set** RETURNS: OK, always*/STATUS pciConfigReset    (    int			startType	/* for reboot hook, ignored */    )    {    /* disable all functions on top-level bus */    pciConfigForeachFunc(0, 0, (PCI_FOREACH_FUNC)pciFuncDisable, NULL);    return(OK);    }#endif /* defined(INCLUDE_PCI) */

⌨️ 快捷键说明

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