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

📄 tmipc.c

📁 wince host 和 target PCI驱动程序
💻 C
字号:
/*	tmipc	Interprocessor communication layer of TriMedia target

	This object will handle only multiplexed interrupt routing to the 
	different clients. It will no longer handle mailbox functionality.
	HISTORY	#define TR	Tilakraj Roy	960426	TR	Created	960428	TR	Added IPC layer to this file 	960502	TR	Seperated common routines for standalone and RTOS compiling.	960531	TR	Put in the Msg interface for other programs to call this module	960618	TR	Added the posting diabled flag checking 
	960923	TR	Added calls for AppMem* for OS scheduling manipulation
	960924	TR	Added Multiplexed interrupt routing  removed mailbox funcs.	961016	TR	Renamed AppMem* AppModel*, added version info*/
/*
	INTERRUPT SAFE code
	ipcSendPacket is the only function that can be potentially called from two
	seperate thread at the same time. All other functions are called once at 
	initialization time.
	TBD : If we insert interuupt safe code in channel manager id there really a 
	need to make ipc thread safe.
*//* TriMedia standard shared includes */#include "tmman.h"
/* internal includes */#include "tmhd.h"#include "tmmmio.h"#include "tmhal.h"#include "tm1/tmInterrupts.h"/* TriMedia local system task includes */#include "tmipc.h"#include "tmshare.h"/* CRT includes */#include <stdio.h>
#include "AppModel.h"/* GLOBALS *//* initialize the symbols so that go into .data or .data 1 and the tmldstops cribbing about patching them */
custom_op DWORD cycles(void);static VOID	ipcHostIRQHandler4Real ( VOID ){/*	#pragma	TCS_handler	           *//*	#pragma	TCS_interruptible_handler  */	DWORD					volatile dwReadIndex;	PTMIPC_MGR_OBJECT		this = GetIPCObject(); /* GLOBAL */	DWORD					dwIdxPacket;
	DWORD					IdxInt;
	DWORD					Start, End;	DWORD					Saved;

	intClear( TMHD_HAL_DSPIRQNUMBER_TM1 );	halIRQDisable ( this->pHal, TMHD_HAL_DSPIRQNUMBER_TM1 , &Saved );

	AppModel_suspend_scheduling ();
/*	DT(1,( "I>")); */

/*	
	tmDBGPrintf ( "I>" );
	Start = cycles(); 
*/
	
	this->pSharedData->H2TInterruptAck++;
	for ( IdxInt = 0 ; IdxInt < TMHD_IPC_MUXCOUNT ; IdxInt ++ )
	{
		DWORD	IntCount;
		
		if ( ! this->Callback[IdxInt].pCallback )
			continue;
		Saved = intCLEAR_IEN();		for (  IntCount = 0; 
			this->pSharedData->H2T[IdxInt].Req != 
			this->pSharedData->H2T[IdxInt].Ack ;
			/* overflow - reset to 0 after 0xffffffff */
			this->pSharedData->H2T[IdxInt].Ack++, IntCount++ )
		{
			
		}
		
		intRESTORE_IEN(Saved);
		if ( IntCount > 0)
		{
			DT(1,( "ipcHostIRQHandler:IntID[%x]:IntCount[%x]\n", IdxInt, IntCount));
			((TMIPC_ONINTERRUPT)this->Callback[IdxInt].pCallback) (
				IdxInt,	IntCount,
				this->Callback[IdxInt].pContext );
		}
	}
	/* 		we are getting out of the ISR - so if the ISR has caused higher		priority to wake up, make the scheduler run now.	*/
	/*intRESTORE_IEN ( ( 1 << TMHD_HAL_DSPIRQNUMBER_TM1 ),   ); */	

	/* DT( 1, ("<I")); */

	halIRQEnable ( this->pHal, TMHD_HAL_DSPIRQNUMBER_TM1 , &Saved );	AppModel_resume_scheduling ();
/*	End = cycles();	if ( End > Start )		tmDBGPrintf( "I[%x]", End - Start );	else		tmDBGPrintf("I[W:%x:%x]",End, Start  );	tmDBGPrintf ( "<I" );
*/}

VOID	ipcHostIRQHandler ( VOID )	{	#pragma TCS_interruptible_handler	    AppModel_suspend_scheduling();	    AppModel_run_on_sstack( (Pointer)ipcHostIRQHandler4Real, Null );	    AppModel_resume_scheduling();	}STATUS	ipcCreate ( PVOID *ppIPC, DWORD CPUVersion )
{	PTMIPC_MGR_OBJECT	this;	/* will be hosed when this function exits, but gives a f...*/	DWORD	dwPCSW; 	DWORD	dwSavedMask;
	DWORD	Idx;
	DWORD	dwIRQ;

	if  ( ( TMSTD_GETTMTYPE(CPUVersion) == TMSTD_TYPE_TM1000 ) &&
			( TMSTD_GETTMREV(CPUVersion) == 0 ) )
	{
		dwIRQ = TMHD_HAL_DSPIRQNUMBER_CTC;
	}
	else
	{
		dwIRQ = TMHD_HAL_DSPIRQNUMBER_TM1;
	}

	if ( ( this =  (PTMIPC_MGR_OBJECT) malloc ( 
		sizeof ( TMIPC_MGR_OBJECT) )  ) == NULL )
	{
		DT(0, ("ipcCreate:ObjectAllcoation:FAIL\n"));
		return TM_STATUS ( TMIPC_ERR_OBJALLOCFAIL );
	}
	this->dwFlags = 0;	this->dwSize = sizeof (TMIPC_MGR_OBJECT);

	tmParameterDWORDGet ( TMHD_PARAM_IPC, (PDWORD)&this->pSharedData );

	this->pSharedData->H2TInterruptAck = 0;

	for ( Idx = 0 ; Idx < TMHD_IPC_MUXCOUNT ; Idx ++)
	{
	  	this->Callback[Idx].pCallback = NULL;
		this->Callback[Idx].pContext = 0;
		this->pSharedData->T2H[Idx].Req = 0;
		this->pSharedData->H2T[Idx].Ack = 0;
	}
		this->pHal	= GetHalObject();

	halIRQDSPAck ( this->pHal, dwIRQ );
	halIRQConnect ( this->pHal, dwIRQ, 
		FALSE, 
		TMHAL_INT_PRIORITY_LEVEL0,  
		(DWORD)ipcHostIRQHandler );

	halIRQEnable ( this->pHal,dwIRQ, &dwSavedMask );

/*	halIRQEnableAll (  this->pHal, &dwPCSW ); */
	FlagSet ( this->dwFlags , TMIPC_MGR_FLAG_INITIALIZED );

	
	*ppIPC = (PVOID)this;
	return TMOK;}
VOID ipcDestroy ( PVOID pIPC ){	PTMIPC_MGR_OBJECT this = pIPC;/*	halIRQDisableAll (  this->pHal ); */
	this->dwSize = 0;
	free ( this );
}
STATUS	ipcRegisterCallback  (	PVOID pIPC,		/* ipc object */	DWORD InterruptID,	/* interrupt command */	TMIPC_ONINTERRUPT	OnInterrupt,	/* interrupt callback function */	PVOID pContext )	/* callback context */
{
	PTMIPC_MGR_OBJECT this = (PTMIPC_MGR_OBJECT)pIPC;
	if ( InterruptID > TMHD_IPC_MUXCOUNT )
	{
		DT(0, ("ipcRegisterCallback:InvalidID:ID[%x]:FAIL\n", InterruptID ));
		return TM_STATUS (TMIPC_ERR_INVALIDIINTID );
	}
	if ( this->Callback[InterruptID].pCallback == NULL )
	{
		 this->Callback[InterruptID].pCallback = (PVOID)OnInterrupt;
		 this->Callback[InterruptID].pContext = pContext;
		 return TMOK;
	}
	else
	{
		DT(0, ("ipcRegisterCallback:InterruptAllocated:ID[%x]:FAIL\n", InterruptID ));
		return TM_STATUS (TMIPC_ERR_INTALLOCATED );
	}

}STATUS	ipcUnregisterCallback  (	PVOID pIPC,		/* ipc object */	DWORD InterruptID )/* interrupt command */
{
	PTMIPC_MGR_OBJECT this = (PTMIPC_MGR_OBJECT)pIPC;
	if ( InterruptID > TMHD_IPC_MUXCOUNT )
	{
		DT(0,( "ipcUnregisterCallback:InvalidID:ID[%x]:FAIL\n", InterruptID ));
		return TM_STATUS (TMIPC_ERR_INVALIDIINTID );
	}

	if ( this->Callback[InterruptID].pCallback != NULL )
	{
		 this->Callback[InterruptID].pCallback = NULL;
		 this->Callback[InterruptID].pContext = NULL;
		 return TMOK;
	}
	else
	{
		DT(0,("ipcUnregisterCallback:InterruptAllocated:ID[%x]:FAIL\n", InterruptID ));
		return TM_STATUS (TMIPC_ERR_INTNOTTALLOCATED );
	}

}

STATUS  ipcGenerateIRQ ( PVOID pIPC , DWORD dwIntID )
{
	PTMIPC_MGR_OBJECT this = pIPC; 
	if ( dwIntID > TMHD_IPC_MUXCOUNT )
	{
		DT(0,( "ipcGenerateIRQ:InvalidID:ID[%x]:FAIL\n", dwIntID ));
		return TM_STATUS (TMIPC_ERR_INVALIDIINTID );
	}
	DT(1, ("ipcGenerateIRQ:IntID[%x]\n", dwIntID ));
	this->pSharedData->T2H[dwIntID].Req++;
	halBIUHostIRQGen( this->pHal );
	return TMOK;
}

⌨️ 快捷键说明

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