📄 i2o.c
字号:
/***************************************************************************
* 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 + -