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

📄 i2o.c

📁 MPC8241:本程序是freescale的824*系列的BSP源程序
💻 C
📖 第 1 页 / 共 3 页
字号:

/***************************************************************************
 *     Copyright Motorola, Inc. 1989-2001 ALL RIGHTS RESERVED
 *
 *  $ID:$
 *
 * You are hereby granted a copyright license to use, modify, and
 * distribute the SOFTWARE, also know as DINK32 (Dynamic Interactive Nano 
 * Kernel for 32-bit processors) solely in conjunction with the development 
 * and marketing of your products which use and incorporate microprocessors 
 * which implement the PowerPC(TM) architecture manufactured by 
 * Motorola and provided you comply with all of the following restrictions 
 * i) this entire notice is retained without alteration in any
 * modified and/or redistributed versions, and 
 * ii) that such modified versions are clearly identified as such. 
 * No licenses are granted by implication, estoppel or
 * otherwise under any patents or trademarks of Motorola, Inc.
 * 
 * The SOFTWARE is provided on an "AS IS" basis and without warranty. To
 * the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS ALL
 * WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED WARRANTIES OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE AND ANY WARRANTY 
 * AGAINST INFRINGEMENT WITH REGARD TO THE SOFTWARE 
 * (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY ACCOMPANYING 
 * WRITTEN MATERIALS.
 * 
 * To the maximum extent permitted by applicable law, IN NO EVENT SHALL
 * MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING WITHOUT 
 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS 
 * INTERRUPTION, LOSS OF BUSINESS INFORMATION,
 * OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
 * SOFTWARE.
 * Motorola assumes no responsibility for the maintenance and support of
 * the SOFTWARE.
 ************************************************************************/

#include "vxWorks.h"
#include "logLib.h"
#include "iv.h"
#include "intLib.h"
#include "config.h"
#include "sysLib.h"  
#include "i2o.h"
extern void    led12(unsigned short );
extern unsigned int get_kahlua_pcsrbar( ); /* for I2O_ISR_host */
extern unsigned int get_eumbbar( );        /* for I2O_ISR_agent */

 
extern unsigned int load_runtime_reg( unsigned int eumbbar, unsigned int reg );
/*#pragma Alias( load_runtime_reg, "load_runtime_reg" );*/

extern void store_runtime_reg( unsigned int eumbbar, unsigned int reg, unsigned int val );
/*#pragma Alias( store_runtime_reg, "store_runtime_reg" );*/
void useI2O(void);
int runled12;
typedef struct _fifo_stat
{
    QUEUE_SIZE   qsz;
    unsigned int qba;
} FIFOSTAT;

FIFOSTAT fifo_stat = { QSIZE_4K, 0xffffffff };

/**********************************************************************************
 * function: I2OMsgEnable
 *
 * description: Enable the interrupt associated with in/out bound msg
 *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
 *
 *              All previously enabled interrupts are preserved.
 * note:
 * Inbound message interrupt generated by PCI master and serviced by local processor
 * Outbound message interrupt generated by local processor and serviced by PCI master
 *
 * local processor needs to enable its inbound interrupts it wants to handle(LOCAL)
 * PCI master needs to enable the outbound interrupts of devices it wants to handle(REMOTE)
 ************************************************************************************/
I2OSTATUS I2OMsgEnable ( LOCATION loc,        /*  REMOTE/LOCALA   */
                         unsigned int base,   /* pcsrbar/eumbbar */
                         unsigned char n )    /* b'1' - msg 0
				               * b'10'- msg 1
		 		               * b'11'- both
					       */
{
    unsigned int reg, val;
    if ( ( n & 0x3 ) == 0 )
    {
	/* neither msg 0, nor msg 1 */
	return I2OMSGINVALID;
    }

    n = (~n) & 0x3;
    /* LOCATION - REMOTE : enable outbound message of device, pcsrbar as base
     *            LOCALA  : enable local inbound message, eumbbar as base
     */
    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
    val = load_runtime_reg( base, reg );

    val &= 0xfffffffc; /* masked out the msg interrupt bits */
    val |= n;          /* LSB are the one we want */
    store_runtime_reg( base, reg, val );

    return I2OSUCCESS;
}

/*********************************************************************************
 * function: I2OMsgDisable
 *
 * description: Disable the interrupt associated with in/out bound msg
 *              Other previously enabled interrupts are preserved.
 *              return I2OSUCCESS if no error otherwise return I2OMSGINVALID
 *
 * note:
 *  local processor needs to disable its inbound interrupts it is not interested(LOCAL)
 *  PCI master needs to disable outbound interrupts of devices it is not interested(REMOTE)
 *********************************************************************************/
I2OSTATUS I2OMsgDisable( LOCATION loc,      /*  REMOTE/LOCALA   */
                         unsigned int base, /* pcsrbar/eumbbar */
                         unsigned char n )  /* b'1' - msg 0
					     * b'10'- msg 1
					     * b'11'- both
					     */
{
    unsigned int reg, val;
    
    if ( ( n & 0x3 ) == 0 )
    {
	/* neither msg 0, nor msg 1 */
	return I2OMSGINVALID;
    }

    /* LOCATION - REMOTE : disable outbound message interrupt of device, pcsrbar as base
     *            LOCALA  : disable local inbound message interrupt, eumbbar as base
     */
    reg = ( loc == REMOTE ? I2O_OMIMR : I2O_IMIMR );
    val = load_runtime_reg( base, reg );

    val &= 0xfffffffc; /* masked out the msg interrupt bits */
    val |= ( n & 0x3 );
    store_runtime_reg( base, reg, val );

    return I2OSUCCESS;
    
}

/**************************************************************************
 * function: I2OMsgGet
 *
 * description: Local processor reads the nth Msg register from its inbound msg,
 *              or a PCI Master reads nth outbound msg from device
 *
 *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
 *
 * note:
 * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
 * If it is remote, outbound msg on the device is read; otherwise local inbound msg is read
 *************************************************************************/
I2OSTATUS I2OMsgGet ( LOCATION loc,             /* REMOTE/LOCAL */
                         unsigned int base,        /*pcsrbar/eumbbar */
                         unsigned int n,           /* 0 or 1 */
                         unsigned int *msg )
{
    if ( n >= I2O_NUM_MSG || msg == 0 )
    {
	return I2OMSGINVALID;
    }

    if ( loc == REMOTE )
    {
	/* read the outbound msg of the device, pcsrbar as base */
	*msg = load_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET );
    }
    else
    {
	/* read the inbound msg sent by PCI master, eumbbar as base */
	*msg = load_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET );
    }
	    
    return I2OSUCCESS;
}

/***************************************************************
 * function: I2OMsgPost
 *
 * description: Kahlua  writes to its nth outbound msg register
 *              PCI master writes to nth inbound msg register of device
 *
 *              return I2OSUCCESS if no error, otherwise return I2OMSGINVALID.
 *
 * note:
 * If it is not local, pcsrbar must be passed to the function. Otherwise eumbbar is passed.
 *
 * If it is remote, inbound msg on the device is written; otherwise local outbound msg is written
 ***************************************************************/
I2OSTATUS I2OMsgPost( LOCATION loc,             /* REMOTE/LOCAL */
                      unsigned int base,        /*pcsrbar/eumbbar */
                      unsigned int n,           /* 0 or 1 */
                      unsigned int msg )
{
    if ( n >= I2O_NUM_MSG )
    {
	return I2OMSGINVALID;
    }
    
    if ( loc == REMOTE )
    {
	/* write to the inbound msg register of the device, pcsrbar as base  */
	store_runtime_reg( base, I2O_IMR0+n*I2O_REG_OFFSET, msg );
    }
    else
    {
	/* write to the outbound msg register for PCI master to read, eumbbar as base */
	store_runtime_reg( base, I2O_OMR0+n*I2O_REG_OFFSET, msg );	
    }
    
    return I2OSUCCESS;
}

/***********************************************************************
 * function: I2ODBEnable
 *
 * description: Local processor enables it's inbound doorbell interrupt
 *              PCI master enables outbound doorbell interrupt of devices
 *              Other previously enabled interrupts are preserved.
 *              Return I2OSUCCESS if no error otherwise return I2ODBINVALID
 *
 * note:
 * In DoorBell interrupt is generated by PCI master and serviced by local processor
 * Out Doorbell interrupt is generated by local processor and serviced by PCI master
 * PCI master needs to enable the outbound doorbell interrupts of device it wants to handle
 **********************************************************************/
I2OSTATUS I2ODBEnable( LOCATION loc,        /*  REMOTE/LOCAL   */
                  unsigned int base,   /* pcsrbar/eumbbar */
                  unsigned int in_db ) /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
{

    /* LOCATION - REMOTE : PCI master initializes outbound doorbell message of device
     *            LOCAL  : Kahlua initializes its inbound doorbell message
     */
    unsigned int val;

    if ( loc == LOCALA && ( in_db & 0x3 ) == 0 )
    {
	return I2ODBINVALID;
    }
    
    if ( loc == REMOTE )
    {
	/* pcsrbar is base, clear the ODIM bit to enable interrupt */
	val = load_runtime_reg( base, I2O_OMIMR );
	val &= 0xfffffff7;
        store_runtime_reg( base, I2O_OMIMR , val );	    
    }
    else
    {
	/* eumbbar is base, clear the IDIM and/or MCIM bit(s) to enable
         * interrupt
         */
	val = load_runtime_reg( base, I2O_IMIMR);
        in_db = ( (~in_db) & 0x3 ) << 3;
        val = ( val & 0xffffffe7) | in_db;
        store_runtime_reg( base,  I2O_IMIMR, val ); 	    
    }

    return I2OSUCCESS;
}

/**********************************************************************************
 * function: I2ODBDisable
 *
 * description: local processor disables its inbound DoorBell Interrupt
 *              PCI master disables outbound DoorBell interrupt of device
 *              Other previously enabled interrupts are preserved.
 *              return I2OSUCCESS if no error.Otherwise return I2ODBINVALID
 *
 * note:
 * local processor needs to disable its inbound doorbell interrupts it is not interested
 *
 * PCI master needs to disable outbound doorbell interrupts of device it is not interested
 ************************************************************************************/
I2OSTATUS I2ODBDisable( LOCATION loc,          /*  REMOTE/LOCAL   */
                        unsigned int base,     /* pcsrbar/eumbbar */
                        unsigned int in_db )   /* when LOCAL, I2O_IN_DB, MC, I2O_IN_DB|MC */
{
    /* LOCATION - REMOTE : handle device's out bound message initialization
     *            LOCAL  : handle local in bound message initialization
     */
    unsigned int val;

    if ( loc == LOCALA && ( in_db & 0x3 ) == 0 )
    {
	    return I2ODBINVALID;
    }
    
    if ( loc == REMOTE )
    {
	/* pcsrbar is the base */
	val = load_runtime_reg( base, I2O_OMIMR );
	val |= 0x8; /* set ODIM to disable */
        store_runtime_reg( base, I2O_OMIMR, val );	    
    }
    else
    {
	    val = load_runtime_reg( base, I2O_IMIMR);
            in_db = ( in_db & 0x3 ) << 3;
            val |= in_db; /* set IDIM and/or MC to disable */
            store_runtime_reg( base, I2O_IMIMR, val ); 	    
    }

    return I2OSUCCESS;
}

/**********************************************************************************
 * function: I2ODBGet
 *
 * description: Local processor reads its in doorbell register,
 *              PCI master reads the outdoorbell register of device.
 *              After a doorbell register is read, the whole register will be cleared.
 *              Otherwise, HW keeps generating interrupt.
 *
 * note:
 * If it is not local, pcsrbar must be passed to the function.
 * Otherwise eumbbar is passed.
 *
 * If it is remote, out doorbell register on the device is read.
 * Otherwise local in doorbell is read
 *
 * If the register is not cleared by write to it, any remaining bit of b'1's
 * will cause interrupt pending.
 *********************************************************************************/
unsigned int I2ODBGet( LOCATION loc,         /*  REMOTE/LOCAL   */
                       unsigned int base)    /* pcsrbar/eumbbar */
{
    unsigned int msg =0;
	unsigned int val,i;
	UINT32 *addr;
    if ( loc == REMOTE )
    {
	/* read outbound doorbell register of device, pcsrbar is the base */
     /*   val = load_runtime_reg( base, 0 );	
        msg = val & ~0x00000000;*/
       
       /* if((*(UINT32 *)(0x88000000))==0x55555555)
        	logMsg("\ndoorbell receive is ok",0,0,0,0,0,0);
        else 
        	logMsg("\ndoorbell receive is wrong",0,0,0,0,0,0);*/
       
        addr=(UINT32 *)(0x88000000);
        for(i=0;i<2*1024;i++)
        addr[i]=0;
        store_runtime_reg( base, 0, (0x1<<1) );
         /* clear the register */
    }
    else
    {
	/* read the inbound doorbell register, eumbbar is the base */
        val = load_runtime_reg( base, I2O_IDBR );
        store_runtime_reg( base, I2O_IDBR, val ); /* clear the register */
	
	msg = val;
    }

    return msg;
}

⌨️ 快捷键说明

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