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

📄 i2o1.c

📁 自己修改的U-boot1.1.4For AT91RM9200DK. 请用armgcc3.3.2编译。
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* QBA must be aligned at 1Mbyte boundary */	return I2OQUEINVALID;    }    store_runtime_reg( eumbbar, I2O_QBAR, qba );    store_runtime_reg( eumbbar, I2O_MUCR, (unsigned int)sz );    store_runtime_reg( eumbbar, I2O_IFHPR, qba );    store_runtime_reg( eumbbar, I2O_IFTPR, qba );    store_runtime_reg( eumbbar, I2O_IPHPR, qba + 1 * ( sz << 11 ));    store_runtime_reg( eumbbar, I2O_IPTPR, qba + 1 * ( sz << 11 ));    store_runtime_reg( eumbbar, I2O_OFHPR, qba + 2 * ( sz << 11 ));    store_runtime_reg( eumbbar, I2O_OFTPR, qba + 2 * ( sz << 11 ));    store_runtime_reg( eumbbar, I2O_OPHPR, qba + 3 * ( sz << 11 ));    store_runtime_reg( eumbbar, I2O_OPTPR, qba + 3 * ( sz << 11 ));    fifo_stat.qsz = sz;    fifo_stat.qba = qba;    return I2OSUCCESS;}/************************************************** * function: I2OFIFOEnable * * description: Enable the circular queue *              return I2OSUCCESS if no error. *              Otherwise I2OQUEINVALID is returned. * * note: *************************************************/I2OSTATUS I2OFIFOEnable( unsigned int eumbbar ){    unsigned int val;    if ( fifo_stat.qba == 0xfffffff )    {	return I2OQUEINVALID;    }    val = load_runtime_reg( eumbbar, I2O_MUCR );    store_runtime_reg( eumbbar, I2O_MUCR, val | 0x1 );    return I2OSUCCESS;}/************************************************** * function: I2OFIFODisable * * description: Disable the circular queue * * note: *************************************************/void I2OFIFODisable( unsigned int eumbbar ){    if ( fifo_stat.qba == 0xffffffff )    {	/* not enabled */	return;    }    unsigned int val = load_runtime_reg( eumbbar, I2O_MUCR );    store_runtime_reg( eumbbar, I2O_MUCR, val & 0xfffffffe );}/**************************************************** * function: I2OFIFOAlloc * * description: Allocate a free MFA from free FIFO. *              return I2OSUCCESS if no error. *              return I2OQUEEMPTY if no more free MFA. *              return I2OINVALID on other errors. * *              A free MFA must be allocated before a *              message can be posted. * * note: * PCI Master allocates a free MFA from inbound queue of device * (pcsrbar is the base,) through the inbound queue port of device * while local processor allocates a free MFA from its outbound * queue (eumbbar is the base.) * ****************************************************/I2OSTATUS I2OFIFOAlloc( LOCATION loc,			unsigned int base,			void         **pMsg ){    I2OSTATUS stat = I2OSUCCESS;    void *pHdr, *pTil;    if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )    {	/* not configured */	return I2OQUEINVALID;    }    if ( loc == REMOTE )    {	/* pcsrbar is the base and read the inbound free tail ptr */	pTil = (void *)load_runtime_reg( base, I2O_IFQPR );	if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )	{	    stat = I2OQUEEMPTY;	}	else	{	    *pMsg = pTil;	}    }    else    {	/* eumbbar is the base and read the outbound free tail ptr */	pHdr = (void *)load_runtime_reg( base, I2O_OFHPR ); /* queue head */	pTil = (void *)load_runtime_reg( base, I2O_OFTPR ); /* queue tail */	/* check underflow */	if ( pHdr == pTil )	{	    /* hdr and til point to the same fifo item, no free MFA */	    stat = I2OQUEEMPTY;	}	else	{	  /* update OFTPR */	  *pMsg = (void *)(*(unsigned char *)pTil);	  pTil = (void *)((unsigned int)pTil + 4);	  if ( (unsigned int)pTil == fifo_stat.qba + ( 4 * ( fifo_stat.qsz << 11 ) ) )	  {		/* reach the upper limit */		pTil = (void *)(fifo_stat.qba + ( 3 * (fifo_stat.qsz << 11) ));	  }	  store_runtime_reg( base, I2O_OFTPR, (unsigned int)pTil );	}    }    return stat;}/****************************************************** * function: I2OFIFOFree * * description: Free a used MFA back to free queue after *              use. *              return I2OSUCCESS if no error. *              return I2OQUEFULL if inbound free queue *              overflow * * note: PCI Master frees a MFA into device's outbound queue *       (OFQPR) while local processor frees a MFA into its *       inbound queue (IFHPR). *****************************************************/I2OSTATUS I2OFIFOFree( LOCATION loc,		  unsigned int base,		  void *pMsg ){    void **pHdr, **pTil;    I2OSTATUS stat = I2OSUCCESS;    if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )    {	    return I2OQUEINVALID;    }    if ( loc == REMOTE )    {	/* pcsrbar is the base */	store_runtime_reg( base, I2O_OFQPR, (unsigned int)pMsg );    }    else    {	/* eumbbar is the base */	pHdr = (void **)load_runtime_reg( base, I2O_IFHPR );	pTil = (void **)load_runtime_reg( base, I2O_IFTPR );	/* store MFA */	*pHdr = pMsg;	/* update IFHPR */	pHdr += 4;	if ( (unsigned int)pHdr == fifo_stat.qba + ( fifo_stat.qsz << 11 ) )	{	  /* reach the upper limit */	  pHdr = (void **)fifo_stat.qba;	}	/* check inbound free queue overflow */	if ( pHdr != pTil )	{	   store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);	}	else	{	    stat = I2OQUEFULL;	}    }    return stat;}/********************************************* * function: I2OFIFOPost * * description: Post a msg into FIFO post queue *              the value of msg must be the one *              returned by I2OFIFOAlloc * * note: PCI Master posts a msg into device's inbound queue *       (IFQPR) while local processor post a msg into device's *       outbound queue (OPHPR) *********************************************/I2OSTATUS I2OFIFOPost( LOCATION loc,		       unsigned int base,		       void *pMsg ){    void **pHdr, **pTil;    I2OSTATUS stat = I2OSUCCESS;    if ( fifo_stat.qba == 0xffffffff || pMsg == 0 )    {	return I2OQUEINVALID;    }    if ( loc == REMOTE )    {	/* pcsrbar is the base */	store_runtime_reg( base, I2O_IFQPR, (unsigned int)pMsg );    }    else    {	/* eumbbar is the base */	pHdr = (void **)load_runtime_reg( base, I2O_OPHPR );	pTil = (void **)load_runtime_reg( base, I2O_OPTPR );	/* store MFA */	*pHdr = pMsg;	/* update IFHPR */	pHdr += 4;	if ( (unsigned int)pHdr == fifo_stat.qba + 3 * ( fifo_stat.qsz << 11 ) )	{	  /* reach the upper limit */	  pHdr = (void **)(fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) );	}	/* check post queue overflow */	if ( pHdr != pTil )	{	   store_runtime_reg( base, I2O_OPHPR, (unsigned int)pHdr);	}	else	{	    stat = I2OQUEFULL;	}    }    return stat;}/************************************************ * function: I2OFIFOGet * * description:  Read a msg from FIFO *               This function should be called *               only when there is a corresponding *               msg interrupt. * * note: PCI Master reads a msg from device's outbound queue *       (OFQPR) while local processor reads a msg from device's *       inbound queue (IPTPR) ************************************************/I2OSTATUS I2OFIFOGet( LOCATION loc,		       unsigned int base,		       void **pMsg ){    I2OSTATUS stat = I2OSUCCESS;    void *pHdr, *pTil;    if ( pMsg == 0 || *pMsg == 0 || fifo_stat.qba == 0xffffffff )    {	/* not configured */	return I2OQUEINVALID;    }    if ( loc == REMOTE )    {	/* pcsrbar is the base */	pTil = (void *)load_runtime_reg( base, I2O_OFQPR );	if ( ( (unsigned int)pTil & 0xFFFFFFF ) == 0xFFFFFFFF )	{	    stat = I2OQUEEMPTY;	}	else	{	    *pMsg = pTil;	}    }    else    {	/* eumbbar is the base and read the outbound free tail ptr */	pHdr = (void *)load_runtime_reg( base, I2O_IPHPR ); /* queue head */	pTil = (void *)load_runtime_reg( base, I2O_IPTPR ); /* queue tail */	/* check underflow */	if ( pHdr == pTil )	{	    /* no free MFA */	    stat = I2OQUEEMPTY;	}	else	{	  /* update OFTPR */	  *pMsg = (void *)(*(unsigned char *)pTil);	  pTil = (void *)((unsigned int)pTil + 4);	  if ( (unsigned int)pTil == fifo_stat.qba + 2 * ( fifo_stat.qsz << 11 ) )	  {		/* reach the upper limit */		pTil = (void *)(fifo_stat.qba + 1 * (fifo_stat.qsz << 11) );	  }	  store_runtime_reg( base, I2O_IPTPR, (unsigned int)pTil );	}    }    return stat;}/******************************************************** * function: I2OIOP * * description: Get the I2O PCI configuration identification *              register. * * note: PCI master should pass pcsrbar while local processor *       should pass eumbbar. *********************************************************/I2OSTATUS I2OPCIConfigGet( LOCATION loc,			unsigned int base,			I2OIOP * val){    unsigned int tmp;    if ( val == 0 )    {	    return I2OINVALID;    }    tmp = load_runtime_reg( base, PCI_CFG_CLA );    val->base_class = ( tmp & 0xFF) << 16;    tmp = load_runtime_reg( base, PCI_CFG_SCL );    val->sub_class= ( (tmp & 0xFF) << 8 );    tmp = load_runtime_reg( base, PCI_CFG_PIC );    val->prg_code = (tmp & 0xFF);    return I2OSUCCESS;}/********************************************************* * function: I2OFIFOIntEnable * * description: Enable the circular post queue interrupt * * note: * PCI master enables outbound FIFO interrupt of device * pscrbar is the base * Device enables its inbound FIFO interrupt * eumbbar is the base *******************************************************/void I2OFIFOIntEnable( LOCATION loc, unsigned int base  ){    unsigned int reg, val;    /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base     *            LOCAL  : enable local inbound message, eumbbar as base     */    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );    val = load_runtime_reg( base, reg );    val &= 0xffffffdf; /* clear the msg interrupt bits */    store_runtime_reg( base, reg, val );}/**************************************************** * function: I2OFIFOIntDisable * * description: Disable the circular post queue interrupt * * note: * PCI master disables outbound FIFO interrupt of device * (pscrbar is the base) * Device disables its inbound FIFO interrupt * (eumbbar is the base) *****************************************************/void I2OFIFOIntDisable( LOCATION loc, unsigned int base ){    /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base     *            LOCAL  : disable local inbound message interrupt, eumbbar as base     */    unsigned int reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );    unsigned int val = load_runtime_reg( base, reg );    val |= 0x00000020; /* masked out the msg interrupt bits */    store_runtime_reg( base, reg, val );}/********************************************************* * function: I2OFIFOOverflowIntEnable * * description: Enable the circular queue overflow interrupt * * note: * Device enables its inbound FIFO post overflow interrupt * and outbound free overflow interrupt. * eumbbar is the base *******************************************************/void I2OFIFOOverflowIntEnable( unsigned int eumbbar  ){    unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );    val &= 0xfffffe7f; /* clear the two overflow interrupt bits */    store_runtime_reg( eumbbar, I2O_IMIMR, val );}/**************************************************** * function: I2OFIFOOverflowIntDisable * * description: Disable the circular queue overflow interrupt * * note: * Device disables its inbound post FIFO overflow interrupt * and outbound free FIFO overflow interrupt * (eumbbar is the base) *****************************************************/void I2OFIFOOverflowIntDisable( unsigned int eumbbar ){    unsigned int val = load_runtime_reg( eumbbar, I2O_IMIMR );    val |= 0x00000180; /* masked out the msg overflow interrupt bits */    store_runtime_reg( eumbbar, I2O_IMIMR, val );}

⌨️ 快捷键说明

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