#include <sys/cdefs.h>
#include <dev/pms/config.h>
#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
#ifdef SA_FW_TEST_BUNCH_STARTS
void mpiMsgProduceBunch( agsaLLRoot_t *saRoot);
#endif
#ifdef SA_ENABLE_TRACE_FUNCTIONS
#ifdef siTraceFileID
#undef siTraceFileID
#endif
#define siTraceFileID 'P'
#endif
GLOBAL void saTimerTick(
agsaRoot_t *agRoot
)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
agsaTimerDesc_t *pTimer;
bit32 Event;
void * pParm;
if(agNULL == saRoot)
{
SA_DBG1(("saTimerTick:agNULL == saRoot \n"));
return;
}
ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
while ( agNULL != pTimer )
{
if ( pTimer->timeoutTick == saRoot->timeTick )
{
saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
pTimer->valid = agFALSE;
Event = pTimer->Event;
pParm = pTimer->pParm;
ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
pTimer->pfnTimeout(agRoot, Event, pParm);
ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
}
else
{
break;
}
pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
}
saRoot->timeTick ++;
if( saRoot->ResetFailed )
{
SA_DBG1(("saTimerTick: siChipResetV saRoot->ResetFailed\n"));
}
#ifdef SA_FW_TEST_BUNCH_STARTS
if (saRoot->BunchStarts_Enable &&
saRoot->BunchStarts_Pending)
{
SA_DBG3(("saTimerTick: mpiMsgProduceBunch\n"));
mpiMsgProduceBunch( saRoot);
}
#endif
#ifdef SA_FW_TEST_INTERRUPT_REASSERT
if(1)
{
mpiOCQueue_t *circularQ;
int i;
SA_DBG4(("saTimerTick:SA_FW_TEST_INTERRUPT_REASSERT\n"));
for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ )
{
circularQ = &saRoot->outboundQueue[i];
OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0);
if(circularQ->producerIdx != circularQ->consumerIdx)
{
if( saRoot->OldCi[i] == circularQ->consumerIdx && saRoot->OldPi[i] >= circularQ->producerIdx)
{
agsaEchoCmd_t payload;
payload.tag = 0xF0;
payload.payload[0]= 0x0;
if( ++saRoot->OldFlag[i] > 1 )
{
saRoot->CheckAll++;
}
SA_DBG1(("saTimerTick:Q %d (%d) PI 0x%03x CI 0x%03x (%d) CheckAll %d %d\n",i,
saRoot->OldFlag[i],
circularQ->producerIdx,
circularQ->consumerIdx,
(circularQ->producerIdx > circularQ->consumerIdx ? (circularQ->producerIdx - circularQ->consumerIdx) : (circularQ->numElements - circularQ->consumerIdx ) + circularQ->producerIdx),
saRoot->CheckAll,
saRoot->sysIntsActive ));
if(smIS64bInt(agRoot))
{
SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X%08X ODMR 0x%08X%08X our Int %x\n",
saRoot->CheckAll,
ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Set_RegisterU),
ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Set_Register),
ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Mask_Set_RegisterU),
ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Mask_Set_Register),
saRoot->OurInterrupt(agRoot,i)
));
}
else
{
SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X ODMR 0x%08X our Int %x\n",
saRoot->CheckAll,
siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register),
siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register),
saRoot->OurInterrupt(agRoot,i)
));
}
if( saRoot->CheckAll > 1)
{
saEchoCommand(agRoot,agNULL, ((i << 16) & 0xFFFF0000 ), (void *)&payload);
}
}
else
{
saRoot->OldFlag[i] = 0;
}
saRoot->OldPi[i] = circularQ->producerIdx;
saRoot->OldCi[i] = circularQ->consumerIdx;
}
}
}
#endif
ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
#ifdef SA_FW_TEST_INTERRUPT_REASSERT
if(saRoot->CheckAll )
{
int a;
for(a=0; a < 32; a++ )
{
if (saRoot->interruptVecIndexBitMap[a] & (1 << a))
{
SA_DBG1(("saTimerTick DI %d\n",a));
saSystemInterruptsEnable ( agRoot, a );
}
}
}
#endif
}
GLOBAL agsaTimerDesc_t *siTimerAdd(
agsaRoot_t *agRoot,
bit32 timeout,
agsaCallback_t pfnTimeout,
bit32 Event,
void * pParm
)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
agsaTimerDesc_t *pTimer;
agsaTimerDesc_t *pValidTimer;
smTraceFuncEnter(hpDBG_VERY_LOUD, "Ta");
ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->freeTimers));
if ( agNULL != pTimer )
{
saLlistRemove(&(saRoot->freeTimers), &(pTimer->linkNode));
saLlinkInitialize(&(pTimer->linkNode));
if ( 0 == timeout )
{
timeout = timeout + 1;
}
pTimer->valid = agTRUE;
pTimer->timeoutTick = saRoot->timeTick + timeout;
pTimer->pfnTimeout = pfnTimeout;
pTimer->Event = Event;
pTimer->pParm = pParm;
pValidTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
while ( agNULL != pValidTimer )
{
if ( pTimer->timeoutTick > saRoot->timeTick )
{
if ( pValidTimer->timeoutTick < saRoot->timeTick )
{
saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
break;
}
else
{
if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
{
saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
break;
}
}
}
else
{
if ( pValidTimer->timeoutTick < saRoot->timeTick )
{
if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
{
saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
break;
}
}
}
pValidTimer = (agsaTimerDesc_t *) saLlistGetNext(&(saRoot->validTimers), &(pValidTimer->linkNode));
}
if ( agNULL == pValidTimer )
{
saLlistAdd(&(saRoot->validTimers), &(pTimer->linkNode));
}
}
ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Ta");
return pTimer;
}
GLOBAL void siTimerRemove(
agsaRoot_t *agRoot,
agsaTimerDesc_t *pTimer
)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
smTraceFuncEnter(hpDBG_VERY_LOUD,"Tb");
ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
if ( agTRUE == pTimer->valid )
{
saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
pTimer->valid = agFALSE;
saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
}
ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Tb");
return;
}
GLOBAL void siTimerRemoveAll(
agsaRoot_t *agRoot
)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
agsaTimerDesc_t *pTimer;
smTraceFuncEnter(hpDBG_VERY_LOUD,"Tc");
ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
while ( agNULL != pTimer )
{
saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
pTimer->valid = agFALSE;
saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
}
ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Tc");
return;
}