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

📄 pciiomaplib.c

📁 这是micrel公司宽带路由ARM9芯片的VXWORKS BSP 源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

/*******************************************************************************
*
* pciMakeConfigAddress - make a Daconfiguration address()
*
* This routine will generate a platform dependent configuration address.
*
* PCI configuration cycles look like this:
*
* Type 0:
*
*  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
*  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*	31:11	Device select bit.
* 	10:8	Function number
* 	 7:2	Register number
*
* Type 1:
*
*  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
*  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*	31:24	reserved
*	23:16	bus number (8 bits = 128 possible buses)
*	15:11	Device number (5 bits)
*	10:8	function number
*	 7:2	register number
*
* RETURNS: configuration address on the PCI bus
*/

UINT32 pciMakeConfigAddress
    (
    int bus,	 	/* bus number */
    int slot, 		/* slot number */
    int function, 	/* function number */
    int offset		/* offset into the configuration space */
    )
    {
    UINT32 address;


    if (bus == 0)
        {
        /*
	 * local bus segment so need a type 0 config cycle
	 */

        address  = 0x80000000;                  /* bits 31     = enable */
        address |= ((bus & 0xFF) << 16);	/* bits 23..16 = bus number */
        address |= ((slot & 0x1F) << 11);  	/* bits 15..11 = slot number */
        address |= ((function & 0x07) << 8);  	/* bits 10..8  = function num */
        address |= offset & 0xFC;	        /* bits  7..2  = register num */
        address |= 0x00000000;  		/* bits  1..0  = type num */

        }
    else
        {
	/* 	-- bus !=0 --
	 *
         * not the local bus segment so need a type 1 config cycle
	 */

        address  = 0x80000000;                  /* bits 31     = enable */
        address |= ((bus & 0xFF) << 16);	/* bits 23..16 = bus number */
        address |= ((slot & 0x1F) << 11);  	/* bits 15..11 = slot number */
        address |= ((function & 0x07) << 8);  	/* bits 10..8  = function num */
        address |= offset & 0xFC;	        /* bits  7..2  = register num */
        address |= 0x00000001;  		/* bits  1..0  = type num */
        }


    return address;
    }

/*******************************************************************************
*
* pciConfigInByte - read a byte from PCI config register.
*
* This routine reads a byte from the given PCI config register.
*
*
* RETURNS: the data value read.
*/

STATUS pciConfigInByte
    (
    int bus,		/* bus number */
    int slot,		/* slot number */
    int function,	/* function number */
    int offset,		/* offset into the configuration space */
    char *data		/* data read from the offset */
    )
    {
    UINT32 cfgAddr;
    UINT32 cfgData;
    UINT8  byteLane;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();



    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);    

    KS8695P_REG_READ(REG_PCI_PBCD, cfgData);

    byteLane = (UINT8)(offset & 0x03);

    *data = (UINT8)(cfgData >> (8 * byteLane));



    /* end of mutual exclusion */

    intUnlock (key);

    return (OK);
    }

/*******************************************************************************
*
* pciConfigInWord - read a word from PCI config register.
*
* This routine reads a word from the given PCI config register.
*
* RETURNS: the data value read.
*/

STATUS pciConfigInWord
    (
    int bus,		/* bus number */
    int slot,		/* slot number */
    int function,	/* function number */
    int offset,		/* offset into the configuration space */
    short *data		/* data read from the offset */
    )
    {
    UINT32 cfgAddr;
    UINT32 cfgData;
    UINT8  byteLane;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();


    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);
    KS8695P_REG_READ(REG_PCI_PBCD, cfgData);

    byteLane = (UINT8)(offset & 0x03);

    *data = (UINT16)(cfgData >> (8 * byteLane));


    /* end of mutual exclusion */

    intUnlock (key);

    return (OK);
    }

/*******************************************************************************
*
* pciConfigInLong - read a long from PCI config register.
*
* This routine reads a long from the given PCI config register.
*
* RETURNS: the data value read.
*/

STATUS pciConfigInLong
    (
    int bus,		/* bus number */
    int slot,		/* slot number */
    int function,	/* function number */
    int offset,		/* offset into the configuration space */
    int *data		/* data read from the offset */
    )
    {
    UINT32 cfgAddr;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();


    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);
    KS8695P_REG_READ(REG_PCI_PBCD, *data);


    /* mutual exclusion stop */

    intUnlock(key);

    return (OK);
    }

/*******************************************************************************
*
* pciConfigOutByte - write a byte to configuration space
*
* This routine writes a byte value to the given PCI config register.
*
* RETURNS: N/A
*/

STATUS pciConfigOutByte
     (
     int bus,		/* bus number */
     int slot,	 	/* slot number */
     int function,	/* function number */
     int offset, 	/* offset into the configuration space */
     char data		/* data written to the offset */
     )
    {
    UINT32 cfgAddr;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();


    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);
    KS8695P_REG_WRITE(REG_PCI_PBCD, (UINT32)data);


    /* mutual exclusion stop */

    intUnlock(key);

    return OK;
    }

/*******************************************************************************
*
* pciConfigOutWord - write a word to configuration space
*
* This routine writes a word value to the given PCI config register.
*
* RETURNS: N/A
*/

STATUS pciConfigOutWord
    (
    int bus,		/* bus number */
    int slot,	 	/* slot number */
    int function, 	/* function number */
    int offset, 	/* offset into the configuration space */
    short data		/* data written to the offset */
    )
    {
    UINT32 cfgAddr;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();


    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);
    KS8695P_REG_WRITE(REG_PCI_PBCD, (UINT16)data);

    /* mutual exclusion stop */

    intUnlock(key);

    return OK;
    }

/*******************************************************************************
*
* pciConfigOutLong - write a long to configuration space
*
* This routine writes a long value to the given PCI config register.
*
* RETURNS: N/A
*/

STATUS pciConfigOutLong
    (
    int bus,	 	/* bus number */
    int slot,	 	/* slot number */
    int function, 	/* function number */
    int offset, 	/* offset into the configuration space */
    int data		/* data written to the offset */
    )
    {
    UINT32 cfgAddr;
    int	  key;

    /* mutual exclusion start */

    key = intLock ();


    /* generate the address of correct configuration space */

    cfgAddr = pciMakeConfigAddress(bus, slot, function, offset);

    /* now that we have valid params, go read the config space data */
    KS8695P_REG_WRITE(REG_PCI_PBCA, cfgAddr);
    KS8695P_REG_WRITE(REG_PCI_PBCD, (UINT32)data);


    /* mutual exclusion stop */

    intUnlock(key);

    return OK;
    }


/*******************************************************************************
*
* pciIomapLibInit - initialize the configuration access-method and addresses
*
* This routine initializes the configuration access-method and addresses.
*
* Configuration mechanism one utilizes two 32-bit IO ports located at addresses
* 0x0cf8 and 0x0cfc. These two ports are:
*   - 32-bit configuration address port, at 0x0cf8
*   - 32-bit configuration data port, at 0x0cfc
* Accessing a PCI function's configuration port is two step process.
*   - Write the bus number, physical device number, function number and
*     register number to the configuration address port.
*   - Perform an IO read from or an write to the configuration data port.
*
* Configuration mechanism two uses following two single-byte IO ports.
*   - Configuration space enable, or CSE, register, at 0x0cf8
*   - Forward register, at 0x0cfa
* To generate a PCI configuration transaction, the following actions are
* performed.
*   - Write the target bus number into the forward register.
*   - Write a one byte value to the CSE register at 0x0cf8.  The bit
*     pattern written to this register has three effects: disables the
*     generation of special cycles; enables the generation of configuration
*     transactions; specifies the target PCI functional device.
*   - Perform a one, two or four byte IO read or write transaction within
*     the IO range 0xc000 through 0xcfff.
*
* Configuration mechanism three is for non-PC/PowerPC environments
* where an area of address space produces PCI configuration
* transactions. No support for special cycles is included.
*
* RETURNS: OK or ERROR if a mechanism is not 1, 2 or 3.
*
*/

STATUS pciIomapLibInit
    (
    int mechanism,	/* configuration mechanism: 1, 2 or 3 */
    int addr0,		/* config-addr-reg / CSE-reg */
    int addr1,		/* config-data-reg / Forward-reg */
    int addr2		/* none            / Base-address */
    )
    {
    int ix;

    if (pciLibInitStatus != NONE)
	return (pciLibInitStatus);

    switch (mechanism)
	{
	case PCI_MECHANISM_1:
	case PCI_MECHANISM_2:
	case PCI_MECHANISM_3:
	    pciConfigMech	= mechanism;
	    pciConfigAddr0	= addr0;
	    pciConfigAddr1	= addr1;
	    pciConfigAddr2	= addr2;
	    pciLibInitStatus	= OK;
	    break;

	default:
    	    pciLibInitStatus	= ERROR;
	    break;
	}

    for (ix = 0; ix < PCI_IRQ_LINES; ix++)
        dllInit (&pciIntList[ix]);

    return (pciLibInitStatus);
    }

/*******************************************************************************
*
* pciFindDevice - find the nth device with the given device & vendor ID
*
* This routine finds the nth device with the given device & vendor ID.
*
* RETURNS: OK or ERROR if the deviceId and vendorId didn't match.
*
*/

STATUS pciFindDevice
    (
    int    vendorId,	/* vendor ID */
    int    deviceId,	/* device ID */

⌨️ 快捷键说明

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