📄 tmipc.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 + -