Exemple #1
0
HRESULT llcIntEventAddCallback(uint32 idx, INTEVENT_CALLBACK callback)
{
	HRESULT hResult = NO_ERROR;

	if (idx < LLC_INT_ITEMS)
	{
		if (intEventCallback[idx] == NULL)
		{
			intEventCallback[idx] = callback;
			llcIntInstalledMask |=LLC_INT_BIT(idx);
			llcLinkRegWrite(INTR_MASK_REG_SET_DP, LLC_INT_BIT(idx));
		}
		else
		{
			hResult = E_LLC_INTEVENT_CB_ERR;
		}
	}
	else
	{
		hResult = E_LLC_INTEVENT_CB_RANGE_ERR;
	}

	return hResult;
}
Exemple #2
0
BOOL llcIntEventIsIntEnabled(uint32 index)
{
	uint32 intEventReg;
	uint32 bit;

	if (index >= LLC_INT_ITEMS)
	{
		return FALSE;
	}

	bit = LLC_INT_BIT(index);

	llcLinkRegRead(INTR_MASK_REG_SET_DP, &intEventReg);

	return ((bit & intEventReg) == bit);
}
Exemple #3
0
/*
	Initialize this module
	Add interrupt procedure to vector addresses
*/
HRESULT llcIntInitialize(void)
{
	HRESULT hResult = NO_ERROR;

	llcIntState = LLC_INT_STATE_WAIT_BUSRESET;

	hResult = llcIntEventInitCallbacks();
	if (hResult != NO_ERROR) return hResult;

	// Clear all pending interrupts 
	llcLinkRegWrite(INTERRUPT_REG_CLEAR_DP, LLC_ALL_INTR_MASK);

	//TCInterruptInstallHandler(CYGNUM_HAL_INTERRUPT_SLINK, NULL, &llcIntEventHandler);
	hResult = TCInterruptInstallEcosHandler(CYGNUM_HAL_INTERRUPT_SLINK, &llc_interrupt_isr, &llc_interrupt_dsr);
	//hResult = TCInterruptCreateLLC(&llcIntEventHandler);
	if (hResult != NO_ERROR) return hResult;

	// Enable interrupts from Samsung LLC

	llcLinkRegWrite(INTR_MASK_REG_SET_DP, LLC_INT_BIT(LLCID_INTR_OUT));

	return hResult;
}
Exemple #4
0
HRESULT llcIntEventRemoveCallback(uint32 idx)
{
	HRESULT hResult = NO_ERROR;

	if (idx < LLC_INT_ITEMS)
	{
		if (intEventCallback[idx] != NULL)
		{
			intEventCallback[idx] = NULL;
			llcIntInstalledMask &= ~LLC_INT_BIT(idx);
			llcLinkRegWrite(INTR_MASK_REG_CLEAR_DP, LLC_INT_BIT(idx));
		}
		else
		{
			hResult = E_LLC_INTEVENT_CB_ERR;
		}
	}
	else
	{
		hResult = E_LLC_INTEVENT_CB_RANGE_ERR;
	}

	return hResult;
}
Exemple #5
0
HRESULT		llcIntEventAddIsr(uint32 idx, INTEVENT_ISR_CALLBACK callback)
{
	HRESULT hResult = NO_ERROR;

	if (idx <= LLC_INT_ISR_TX)
	{
		if (intEventIsrCallback[idx] == NULL)
		{
			intEventIsrCallback[idx] = callback;
			llcIsrInstalledMask |=LLC_INT_BIT((idx==LLC_INT_ISR_RX)?LLCID_ASY_RX_PKT_AVL:LLCID_ASY_TX_CMPL);
		}
		else
		{
			hResult = E_LLC_INTEVENT_CB_ERR;
		}
	}
	else
	{
		hResult = E_LLC_INTEVENT_CB_RANGE_ERR;
	}

	return hResult;

}
Exemple #6
0
uint32 llc_interrupt_isr(uint32 vector, void *data)
{
	uint32 intEventReg;
	BOOL bDsr = FALSE;
	
	llcLinkRegRead(INTERRUPT_REG_CLEAR_DP, &intEventReg); //events which are not masked
	if ((intEventReg & LLC_INT_BIT(LLCID_INTR_OUT)) == 0) return CYG_ISR_HANDLED;

	//mask all those handled by DSR, DSR will unmask when done
	bDsr = intEventReg & llcIntInstalledMask;
	if (bDsr) llcLinkRegWrite(INTR_MASK_REG_CLEAR_DP, ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT)));
	
	// Clear the ones we are handeling here
	llcLinkRegWrite(INTERRUPT_REG_CLEAR_DP, intEventReg&(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT)));

	llcIntEvents++;

	//we need to look for bus reset and if we see it we must mask out LLCID_ASY_RX_PKT_AVL and leave it
	//to the DSR BR handler to read whatever is in the FIFO
	//The LLCID_BUS_RST_RXD might be masked waiting for DSR so we need to check the raw status
	uint32 rawEvent;
	llcLinkRegRead(INTERRUPT_REG_DP, &rawEvent);
	if (rawEvent & LLC_INT_BIT(LLCID_BUS_RST_RXD))
	{
		//at some point the DSR will handle this, we really don't need and ISR processing for now
		llcLinkRegWrite(INTR_MASK_REG_CLEAR_DP, HANDLE_BY_ISR);
		//we have to rely on the DSR putting us back into normal mode
	}
	else
	{
		if (intEventReg & LLC_INT_BIT(LLCID_ASY_RX_PKT_AVL))
			if (_llcIntEventIsrCallCallback(LLC_INT_ISR_RX)) llcIsrDsrRxEvent = 1;
		if (intEventReg & LLC_INT_BIT(LLCID_ASY_TX_CMPL))
			if (_llcIntEventIsrCallCallback(LLC_INT_ISR_TX)) llcIsrDsrTxEvent = 1;
			
	}
	//as long as we have unhandled Isr->dsr's keep calling the DSR.
	if (llcIsrDsrRxEvent || llcIsrDsrTxEvent) bDsr = 1;
	
	return bDsr ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED;
}
Exemple #7
0
void llc_interrupt_dsr(uint32 vector, uint32 count, void * data)
{
	uint32 intEventReg;

	llcLinkRegRead(INTERRUPT_REG_DP, &intEventReg); //read raw interrupt stat
	intEventReg &=llcIntInstalledMask; //and with handled stat

	 //is there any ISR requests
	if (llcIsrDsrTxEvent)
	{
		intEventReg |= LLC_INT_BIT(LLCID_ASY_TX_CMPL);
		llcIsrDsrTxEvent = 0;
	}
	if (llcIsrDsrRxEvent)
	{
		intEventReg |= LLC_INT_BIT(LLCID_ASY_RX_PKT_AVL);
		llcIsrDsrRxEvent = 0;
	}
	//fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,intEventReg);	
	if (!intEventReg) 
	{
		//should never happen
		llcLinkRegWrite(INTR_MASK_REG_SET_DP, llcIntInstalledMask & ~HANDLE_BY_ISR);
		return;
	}

	// Clear all pending interrupts serviced
	llcLinkRegWrite(INTERRUPT_REG_CLEAR_DP, intEventReg & ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT)));
	

	if (llcIntState == LLC_INT_STATE_WAIT_BUSRESET ||
		llcIntState == LLC_INT_STATE_PROCESS_NORMAL ||
		llcIntState == LLC_INT_STATE_PROCESS_SI)
	{
		if (intEventReg & LLC_INT_BIT(LLCID_BUS_RST_RXD)) //new bus reset
		{
			_llcIntEventSetState(LLC_INT_STATE_WAIT_SI_COMPLETE);
			llcIntEvent[LLCID_BUS_RST_RXD]++;
			_llcIntEventCallCallback(LLCID_BUS_RST_RXD);	 
		}
		
	}
	if (llcIntState == LLC_INT_STATE_WAIT_SI_COMPLETE)
	{
		if (intEventReg & LLC_INT_BIT(LLCID_BUS_INIT_OVR)) //new selfid complete 
		{
			llcIntEvent[LLCID_BUS_INIT_OVR]++;
			_llcIntEventSetState(LLC_INT_STATE_PROCESS_SI);
			_llcIntEventCallCallback(LLCID_BUS_INIT_OVR);
		}
	}
	if (llcIntState == LLC_INT_STATE_PROCESS_NORMAL)
	{
		uint8 i;
		uint8 id;
		//only handle general items for optimization
		for (i = 0; i < LLCINT_EVENT_GENERAL_ITEMS; i++)
		{
			id = llcIntEventGeneral[i];
			if (intEventReg & LLC_INT_BIT(id))
			{
				llcIntEvent[id]++;
				_llcIntEventCallCallback(id);
				intEventReg &= ~LLC_INT_BIT(id);
				if (intEventReg == 0) break;
			}
		}
	}
	llcLinkRegWrite(INTR_MASK_REG_SET_DP, llcIntInstalledMask & ~(HANDLE_BY_ISR | LLC_INT_BIT(LLCID_INTR_OUT)));
}
Exemple #8
0
static HRESULT context1PostPacket(PB * pPacket,uint32 semID)
{
	HRESULT hResult = NO_ERROR;

	//check if context is available, should be as we only have one thread using the context
	volatile POSTED_TX_CONTEXT * pContext = &postedTxState.contexts[1];
	if (pContext->bPosted)
	{
			hResult = E_LAL_RESPONSE_UNEXPECTED;
			sysLogError(hResult, __LINE__, moduleName);
			return hResult;
	}
	PB_HEADER*	pHeader = 0;
	uint32		speedCode = 0;
#ifdef _LOOSE_ISO
	uint8		asyncStream = FALSE;
#endif //_LOOSE_ISO


 	// ML 140610: Busreset storm fix. Let's skip if we ar ein bus reset
 	if (postedTxState.inBr)
	{
	  hResult = E_LAL_BUS_RESET_IN_PROGRESS;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}

	pbGetPacketHeader(pPacket, &pHeader);
	pbGetPacketSpeed(pPacket, &speedCode);

	PB_PACKETTYPE packetType;
	pbGetPacketType(pPacket, &packetType);

	pContext->header.quadlets[0] = (pHeader->quadlets[0] & 0x0000ffff);		// 0:spd,tag,ch,tcode,sy
	pContext->header.quadlets[0]|= speedCode;

#ifdef _LOOSE_ISO
	pbIsAsyncStreamPacket (pPacket, &asyncStream);
	if (asyncStream == TRUE)
	{
		pContext->header.quadlets[1] = (pHeader->quadlets[1] & 0xffff0000);		// 1:data_length,reserved
	}
	else
#endif //_LOOSE_ISO
	if (packetType == TCODE_PHY_PACKET)
	{
		pContext->header.quadlets[0] = ((uint32)TCODE_LLC_SPECIFIC) << SHIFT_TCODE;
		pContext->header.quadlets[1] = pHeader->quadlets[0];
		pContext->header.quadlets[2] = ~pHeader->quadlets[0];
	}
	else
	{
		pContext->header.quadlets[0] |= LLC_SOURCEID_NODEID;
		pContext->header.quadlets[1] = (pHeader->quadlets[0] & 0xffff0000);		// 1:dstId,destination_offsetHigh
		pContext->header.quadlets[1] |= (pHeader->quadlets[1] & 0x0000ffff);
		pContext->header.quadlets[2] = pHeader->quadlets[2];						// 2:destination_offsetLow
		pContext->header.quadlets[3] = pHeader->quadlets[3];						// 3:data_length,extended_tcode
	}
	hResult = lhlGetHeaderQuadSizeFromTCode(LHL_TX, packetType, (uint16 *)&pContext->headerLen);
	if (hResult != NO_ERROR) return hResult;

	uint32 payloadNumBytes=0;
	
	pbGetPayload(pPacket, (void **)&pContext->pPayload);
	pbGetPayloadSize(pPacket, &payloadNumBytes);
	
	//Ugly, the payload is not always refering to the outgoing packet.
	if ((packetType==PB_TYPE_READ_REQUEST) || (packetType==PB_TYPE_READ_REQUEST_QUADLET) ||(packetType==PB_TYPE_WRITE_RESPONSE) || (packetType==TCODE_PHY_PACKET)) 
		payloadNumBytes=0;
	//Another hack as the read resp payload should always be one quadlet even in case of error
	if (packetType==PB_TYPE_READ_RESPONSE_QUADLET)
		payloadNumBytes=4;

	pContext->payloadLen = (payloadNumBytes+3)>>2;
	
	// ML 140610: Busreset storm fix. There is potentially a race condition here if
	//            Isr or Dsr comes here. Fixed with interrupt disable.
	TCInterruptGlobalDisable();
	if (postedTxState.inBr)
	{
	  TCInterruptGlobalEnable();
	  hResult = E_LAL_BUS_RESET_IN_PROGRESS;
		sysLogError(hResult, __LINE__, moduleName);
		return hResult;
	}
  pContext->semID = semID;
	pContext->bPosted = TRUE;
  fSYS_TRACE1(SYSDEBUG_TRACE_TESTS,0);
  llcLinkRegWrite(INTERRUPT_REG_SET_DP, LLC_INT_BIT(LLCID_ASY_TX_CMPL));	
	TCInterruptGlobalEnable();
	return hResult;
}