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

📄 pciiomaplib.c

📁 vxworks的BSP开发配置文件
💻 C
📖 第 1 页 / 共 3 页
字号:
		    *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 */    ULONG       devIoBaseAdrs,          /* device IO base address */    ULONG       devMemBaseAdrs,         /* device memory base address */    ULONG       command                 /* command to issue */    )    {    INT32       ix;    UINT32      tmp32;    /*     * Disable device by clearing its command register field in its     * configuration header.     */    pciConfigOutWord (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND, 0);    /*     *  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_CLINE_SZ);    /* Configure Latency Timer */    pciConfigOutByte (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_LATENCY_TIMER,		      PCI_LAT_TIMER);    /* Enable the device's capabilities as specified */    pciConfigOutWord (pciBusNo, pciDevNo, pciFuncNo, PCI_CFG_COMMAND,  		      (UINT16)command);    return (OK);    }/********************************************************************************* pciPack - pack parameters for the Configuration Address Register** This routine packs three parameters into one integer for accessing the* Configuration Address Register** RETURNS:* packed integer.**/LOCAL int pciPack    (    int	busNo,		/* bus number */    int	deviceNo,	/* device number */    int	funcNo		/* function number */    )    {    return (((busNo    << 16) & 0x00ff0000) |	    ((deviceNo << 11) & 0x0000f800) |	    ((funcNo   << 8)  & 0x00000700));    }/********************************************************************************* 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 */    char * pData	/* data read from the offset */    )    {    int	retval = 0;    int	key;    int n;    UINT32 w;    if (pciLibInitStatus != OK)			/* sanity check */        return (ERROR);    key = intLock ();				/* mutual exclusion start */    switch (pciConfigMech)	{	case PCI_MECHANISM_1:	    PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) |		          (offset & 0xfc) | 0x80000000);	    retval = PCI_IN_BYTE (pciConfigAddr1 + (offset & 0x3));	    break;	case PCI_MECHANISM_2:	    PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));	    PCI_OUT_BYTE (pciConfigAddr1, busNo);	    retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) |				  (offset & 0xfc));	    PCI_OUT_BYTE (pciConfigAddr0, 0);	    retval >>= (offset & 0x03) * 8;	    break;	case PCI_MECHANISM_3:	    /*	     * There are reports of hardware (both target and bridge)	     * that do not cope well with non-32-bit-aligned accesses,	     * particularly non-32-bit-word accesses. We may be overreacting	     * here, but restricting all the accesses to 32-bits should be	     * safer. Efficiency should not be an issue during PCI	     * configuration. In any case, this code is in the BSP and can be	     * changed, if required.	     */	    n = offset % 4;	    IDSEL(busNo, deviceNo);		/* Setup IDSEL Lines */	    w = PCI_IN_LONG (((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) |			MAKE_CFG_ADDR(busNo, deviceNo, funcNo, (offset & ~3)));	    retval = (w >> (8 * n)) & 0xFF;	    CLR_IDSEL;				/* Clear IDSEL Lines */	    break;	default:	    break;	}    intUnlock (key);				/* mutual exclusion stop */    *pData = (char)retval;    return (OK);    }/********************************************************************************* pciConfigInWord - read one word from the PCI configuration space** This routine reads one word from the PCI configuration space** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigInWord    (    int	busNo,		/* bus number */    int	deviceNo,	/* device number */    int	funcNo,		/* function number */    int	offset,		/* offset into the configuration space */    short * pData	/* data read from the offset */    )    {    int	retval = 0;    int	key;    int n;    UINT32 w;    if (pciLibInitStatus != OK)			/* sanity check */        return (ERROR);    key = intLock ();				/* mutual exclusion start */    switch (pciConfigMech)	{	case PCI_MECHANISM_1:	    PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) |		          (offset & 0xfc) | 0x80000000);	    retval = PCI_IN_WORD (pciConfigAddr1 + (offset & 0x2));	    break;	case PCI_MECHANISM_2:	    PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));	    PCI_OUT_BYTE (pciConfigAddr1, busNo);	    retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) |				  (offset & 0xfc));	    PCI_OUT_BYTE (pciConfigAddr0, 0);	    retval >>= (offset & 0x02) * 8;	    break;	case PCI_MECHANISM_3:	    n = offset % 4;	    IDSEL(busNo, deviceNo);		/* Setup IDSEL Lines */	    w = PCI_IN_LONG (((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) |		MAKE_CFG_ADDR(busNo, deviceNo, funcNo, (offset & ~3)));	    retval = (w >> (8 * n)) & 0xFFFF;	    CLR_IDSEL;				/* Clear IDSEL Lines */	    break;	default:	    break;	}    intUnlock (key);				/* mutual exclusion stop */    *pData = retval;    return (OK);    }/********************************************************************************* pciConfigInLong - read one longword from the PCI configuration space** This routine reads one longword from the PCI configuration space** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigInLong    (    int	busNo,		/* bus number */    int	deviceNo,	/* device number */    int	funcNo,		/* function number */    int	offset,		/* offset into the configuration space */    int * pData		/* data read from the offset */    )    {    int		 key;    volatile int retval = 0;    FAST int	 ix;    if (pciLibInitStatus != OK)			/* sanity check */        return (ERROR);    key = intLock ();				/* mutual exclusion start */    switch (pciConfigMech)	{	case PCI_MECHANISM_1:	    PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) |		          (offset & 0xfc) | 0x80000000);            for (ix = 0; ix < PCI_DELAY; ++ix)  /* XXXmas */                ;	    retval = PCI_IN_LONG (pciConfigAddr1);	    break;	case PCI_MECHANISM_2:	    PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1));	    PCI_OUT_BYTE (pciConfigAddr1, busNo);	    retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) |				  (offset & 0xfc));	    PCI_OUT_BYTE (pciConfigAddr0, 0);	    break;	case PCI_MECHANISM_3:	    IDSEL(busNo, deviceNo);		/* Setup IDSEL Lines */	    retval =		PCI_IN_LONG (((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) |			MAKE_CFG_ADDR(busNo, deviceNo, funcNo, offset));	    CLR_IDSEL;				/* Clear IDSEL Lines */	    break;	default:	    break;	}    intUnlock (key);				/* mutual exclusion stop */    *pData = retval;    return (OK);    }/********************************************************************************* pciConfigOutByte - write one byte to the PCI configuration space** This routine writes one byte to the PCI configuration space.*

⌨️ 快捷键说明

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