Пример #1
0
void PageTable2 (TPageTable *This, uint32 MemSize)
{
	This->TableAllocated = true;
	This->Table = (TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *) PageAlloc();

	for (unsigned EntryIndex = 0; EntryIndex < SDRAM_SIZE_MBYTE; EntryIndex++)
	{
		uint32 BaseAddress = MEGABYTE * EntryIndex;

		TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR* Entry = &This->Table[EntryIndex];

		Entry->Value10	= 2;
		Entry->BBit	= 1;
		Entry->CBit	= 1;
		Entry->XNBit = 0;
		Entry->Domain = 0;
		Entry->IMPBit = 0;
		Entry->AP = AP_SYSTEM_ACCESS;
		Entry->TEX = 0;
		Entry->APXBit = APX_RW_ACCESS;
		Entry->SBit	= 0;
		Entry->NGBit = 0;
		Entry->Value0 = 0;
		Entry->SBZ = 0;
		Entry->Base	= ARMV6MMUL1SECTIONBASE(BaseAddress);
	}

	CleanDataCache ();
	DataSyncBarrier ();
}
Пример #2
0
boolean CInterruptSystem::Initialize (void)
{
	TExceptionTable *pTable = (TExceptionTable *) ARM_EXCEPTION_TABLE_BASE;
	pTable->IRQ = ARM_OPCODE_BRANCH (ARM_DISTANCE (pTable->IRQ, IRQStub));

	CleanDataCache ();
	DataSyncBarrier ();

	InvalidateInstructionCache ();
	FlushBranchTargetCache ();
	DataSyncBarrier ();

	InstructionSyncBarrier ();

#ifndef USE_RPI_STUB_AT
	DataMemBarrier ();

	write32 (ARM_IC_FIQ_CONTROL, 0);

	write32 (ARM_IC_DISABLE_IRQS_1, (u32) -1);
	write32 (ARM_IC_DISABLE_IRQS_2, (u32) -1);
	write32 (ARM_IC_DISABLE_BASIC_IRQS, (u32) -1);

	DataMemBarrier ();
#endif

	EnableInterrupts ();

	return TRUE;
}
Пример #3
0
void PageTable(TPageTable* This)
{
	This->TableAllocated = false;
	This->Table = (TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR*) MEM_PAGE_TABLE1;

	for (unsigned EntryIndex = 0; EntryIndex < 4096; EntryIndex++)
	{
		uint32 nBaseAddress = MEGABYTE * EntryIndex;
		
		TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR* Entry = &This->Table[EntryIndex];

		Entry->Value10	= 2;
		Entry->BBit = 1;
		Entry->CBit = 0;
		Entry->XNBit = 0;
		Entry->Domain = 0;
		Entry->IMPBit = 0;
		Entry->AP = AP_SYSTEM_ACCESS;
		Entry->TEX = 0;
		Entry->APXBit = APX_RW_ACCESS;
		Entry->SBit = 0;
		Entry->NGBit = 0;
		Entry->Value0 = 0;
		Entry->SBZ = 0;
		Entry->Base	= ARMV6MMUL1SECTIONBASE(nBaseAddress);
	}

	CleanDataCache ();
	DataSyncBarrier ();
}
Пример #4
0
boolean CBcmPropertyTags::GetTag (u32 nTagId, void *pTag, unsigned nTagSize, unsigned nRequestParmSize)
{
	assert (pTag != 0);
	assert (nTagSize >= sizeof (TPropertyTagSimple));
	unsigned nBufferSize = sizeof (TPropertyBuffer) + nTagSize + sizeof (u32);
	assert ((nBufferSize & 3) == 0);

	// cannot use "new" here because this is used before mem_init() is called
	u8 Buffer[nBufferSize + 15];
	TPropertyBuffer *pBuffer = (TPropertyBuffer *) (((u32) Buffer + 15) & ~15);
	
	pBuffer->nBufferSize = nBufferSize;
	pBuffer->nCode = CODE_REQUEST;
	memcpy (pBuffer->Tags, pTag, nTagSize);
	
	TPropertyTag *pHeader = (TPropertyTag *) pBuffer->Tags;
	pHeader->nTagId = nTagId;
	pHeader->nValueBufSize = nTagSize - sizeof (TPropertyTag);
	pHeader->nValueLength = nRequestParmSize & ~VALUE_LENGTH_RESPONSE;

	u32 *pEndTag = (u32 *) (pBuffer->Tags + nTagSize);
	*pEndTag = PROPTAG_END;

	CleanDataCache ();
	DataSyncBarrier ();

	u32 nBufferAddress = GPU_MEM_BASE + (u32) pBuffer;
	if (m_MailBox.WriteRead (nBufferAddress) != nBufferAddress)
	{
		return FALSE;
	}
	
	InvalidateDataCache ();
	DataSyncBarrier ();

	if (pBuffer->nCode != CODE_RESPONSE_SUCCESS)
	{
		return FALSE;
	}
	
	if (!(pHeader->nValueLength & VALUE_LENGTH_RESPONSE))
	{
		return FALSE;
	}
	
	pHeader->nValueLength &= ~VALUE_LENGTH_RESPONSE;
	if (pHeader->nValueLength == 0)
	{
		return FALSE;
	}

	memcpy (pTag, pBuffer->Tags, nTagSize);

	return TRUE;
}
Пример #5
0
void PageTable2 (TPageTable *pThis, u32 nMemSize)
{
	assert (pThis != 0);

	pThis->m_bTableAllocated = TRUE;
	pThis->m_pTable = (TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *) palloc ();

	assert (pThis->m_pTable != 0);
	assert (((u32) pThis->m_pTable & 0xFFF) == 0);

	for (unsigned nEntry = 0; nEntry < SDRAM_SIZE_MBYTE; nEntry++)
	{
		u32 nBaseAddress = MEGABYTE * nEntry;

		TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *pEntry = &pThis->m_pTable[nEntry];

		// outer and inner write back, no write allocate
		pEntry->Value10	= 2;
		pEntry->BBit	= 1;
		pEntry->CBit	= 1;
		pEntry->XNBit	= 0;
		pEntry->Domain	= 0;
		pEntry->IMPBit	= 0;
		pEntry->AP	= AP_SYSTEM_ACCESS;
		pEntry->TEX	= 0;
		pEntry->APXBit	= APX_RW_ACCESS;
		pEntry->SBit	= 0;
		pEntry->NGBit	= 0;
		pEntry->Value0	= 0;
		pEntry->SBZ	= 0;
		pEntry->Base	= ARMV6MMUL1SECTIONBASE (nBaseAddress);

		extern u8 _etext;
		if (nBaseAddress >= (u32) &_etext)
		{
			pEntry->XNBit = 1;

			if (nBaseAddress >= nMemSize)
			{
				// shared device
				pEntry->BBit  = 1;
				pEntry->CBit  = 0;
				pEntry->TEX   = 0;
				pEntry->SBit  = 1;
			}
		}
	}

	CleanDataCache ();
	DataSyncBarrier ();
}
Пример #6
0
void PageTable (TPageTable *pThis)
{
	assert (pThis != 0);

	pThis->m_bTableAllocated = FALSE;
	pThis->m_pTable = (TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *) MEM_PAGE_TABLE1;

	assert (((u32) pThis->m_pTable & 0x3FFF) == 0);

	for (unsigned nEntry = 0; nEntry < 4096; nEntry++)
	{
		u32 nBaseAddress = MEGABYTE * nEntry;
		
		TARMV6MMU_LEVEL1_SECTION_DESCRIPTOR *pEntry = &pThis->m_pTable[nEntry];

		// shared device
		pEntry->Value10	= 2;
		pEntry->BBit    = 1;
		pEntry->CBit    = 0;
		pEntry->XNBit   = 0;
		pEntry->Domain	= 0;
		pEntry->IMPBit	= 0;
		pEntry->AP	= AP_SYSTEM_ACCESS;
		pEntry->TEX     = 0;
		pEntry->APXBit	= APX_RW_ACCESS;
		pEntry->SBit    = 1;
		pEntry->NGBit	= 0;
		pEntry->Value0	= 0;
		pEntry->SBZ	= 0;
		pEntry->Base	= ARMV6MMUL1SECTIONBASE (nBaseAddress);

		if (nEntry >= SDRAM_SIZE_MBYTE)
		{
			pEntry->XNBit = 1;
		}
	}

	CleanDataCache ();
	DataSyncBarrier ();
}
Пример #7
0
void CDWHCIDevice::ChannelInterruptHandler (unsigned nChannel)
{
	CDWHCITransferStageData *pStageData = m_pStageData[nChannel];
	assert (pStageData != 0);
	CUSBRequest *pURB = pStageData->GetURB ();
	assert (pURB != 0);

	switch (pStageData->GetSubState ())
	{
	case StageSubStateWaitForChannelDisable:
		StartChannel (pStageData);
		return;

	case StageSubStateWaitForTransactionComplete: {
		CleanDataCache ();
		InvalidateDataCache ();
		DataMemBarrier ();

		CDWHCIRegister TransferSize (DWHCI_HOST_CHAN_XFER_SIZ (nChannel));
		TransferSize.Read ();

		CDWHCIRegister ChanInterrupt (DWHCI_HOST_CHAN_INT (nChannel));

		assert (   !pStageData->IsPeriodic ()
			||    DWHCI_HOST_CHAN_XFER_SIZ_PID (TransferSize.Get ())
			   != DWHCI_HOST_CHAN_XFER_SIZ_PID_MDATA);

		pStageData->TransactionComplete (ChanInterrupt.Read (),
			DWHCI_HOST_CHAN_XFER_SIZ_PACKETS (TransferSize.Get ()),
			TransferSize.Get () & DWHCI_HOST_CHAN_XFER_SIZ_BYTES__MASK);
		} break;
	
	default:
		assert (0);
		break;
	}
	
	unsigned nStatus;
	
	switch (pStageData->GetState ())
	{
	case StageStateNoSplitTransfer:
		nStatus = pStageData->GetTransactionStatus ();
		if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
		{
			CLogger::Get ()->Write (FromDWHCI, LogError,
						"Transaction failed (status 0x%X)", nStatus);

			pURB->SetStatus (0);
		}
		else if (   (nStatus & (DWHCI_HOST_CHAN_INT_NAK | DWHCI_HOST_CHAN_INT_NYET))
			 && pStageData->IsPeriodic ())
		{
			pStageData->SetState (StageStatePeriodicDelay);

			unsigned nInterval = pURB->GetEndpoint ()->GetInterval ();

			m_pTimer->StartKernelTimer (MSEC2HZ (nInterval), TimerStub, pStageData, this);

			break;
		}
		else
		{
			if (!pStageData->IsStatusStage ())
			{
				pURB->SetResultLen (pStageData->GetResultLen ());
			}

			pURB->SetStatus (1);
		}
		
		DisableChannelInterrupt (nChannel);

		delete pStageData;
		m_pStageData[nChannel] = 0;

		FreeChannel (nChannel);

		pURB->CallCompletionRoutine ();
		break;

	case StageStateStartSplit:
		nStatus = pStageData->GetTransactionStatus ();
		if (   (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
		    || (nStatus & DWHCI_HOST_CHAN_INT_NAK)
		    || (nStatus & DWHCI_HOST_CHAN_INT_NYET))
		{
			CLogger::Get ()->Write (FromDWHCI, LogError,
						"Transaction failed (status 0x%X)", nStatus);

			pURB->SetStatus (0);

			DisableChannelInterrupt (nChannel);

			delete pStageData;
			m_pStageData[nChannel] = 0;

			FreeChannel (nChannel);

			pURB->CallCompletionRoutine ();
			break;
		}

		pStageData->GetFrameScheduler ()->TransactionComplete (nStatus);

		pStageData->SetState (StageStateCompleteSplit);
		pStageData->SetSplitComplete (TRUE);

		if (!pStageData->GetFrameScheduler ()->CompleteSplit ())
		{
			goto LeaveCompleteSplit;
		}
		
		StartTransaction (pStageData);
		break;
		
	case StageStateCompleteSplit:
		nStatus = pStageData->GetTransactionStatus ();
		if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
		{
			CLogger::Get ()->Write (FromDWHCI, LogError,
						"Transaction failed (status 0x%X)", nStatus);

			pURB->SetStatus (0);

			DisableChannelInterrupt (nChannel);

			delete pStageData;
			m_pStageData[nChannel] = 0;

			FreeChannel (nChannel);

			pURB->CallCompletionRoutine ();
			break;
		}
		
		pStageData->GetFrameScheduler ()->TransactionComplete (nStatus);

		if (pStageData->GetFrameScheduler ()->CompleteSplit ())
		{
			StartTransaction (pStageData);
			break;
		}

	LeaveCompleteSplit:
		if (!pStageData->IsStageComplete ())
		{
			if (!pStageData->BeginSplitCycle ())
			{
				pURB->SetStatus (0);

				DisableChannelInterrupt (nChannel);

				delete pStageData;
				m_pStageData[nChannel] = 0;

				FreeChannel (nChannel);

				pURB->CallCompletionRoutine ();
				break;
			}

			if (!pStageData->IsPeriodic ())
			{
				pStageData->SetState (StageStateStartSplit);
				pStageData->SetSplitComplete (FALSE);
				pStageData->GetFrameScheduler ()->StartSplit ();

				StartTransaction (pStageData);
			}
			else
			{
				pStageData->SetState (StageStatePeriodicDelay);

				unsigned nInterval = pURB->GetEndpoint ()->GetInterval ();

				m_pTimer->StartKernelTimer (MSEC2HZ (nInterval),
							    TimerStub, pStageData, this);
			}
			break;
		}

		DisableChannelInterrupt (nChannel);

		if (!pStageData->IsStatusStage ())
		{
			pURB->SetResultLen (pStageData->GetResultLen ());
		}
		pURB->SetStatus (1);

		delete pStageData;
		m_pStageData[nChannel] = 0;

		FreeChannel (nChannel);

		pURB->CallCompletionRoutine ();
		break;

	default:
		assert (0);
		break;
	}
}
Пример #8
0
void CDWHCIDevice::StartChannel (CDWHCITransferStageData *pStageData)
{
	assert (pStageData != 0);
	unsigned nChannel = pStageData->GetChannelNumber ();
	assert (nChannel < m_nChannels);
	
	pStageData->SetSubState (StageSubStateWaitForTransactionComplete);

	// reset all pending channel interrupts
	CDWHCIRegister ChanInterrupt (DWHCI_HOST_CHAN_INT (nChannel));
	ChanInterrupt.SetAll ();
	ChanInterrupt.Write ();
	
	// set transfer size, packet count and pid
	CDWHCIRegister TransferSize (DWHCI_HOST_CHAN_XFER_SIZ (nChannel), 0);
	TransferSize.Or (pStageData->GetBytesToTransfer () & DWHCI_HOST_CHAN_XFER_SIZ_BYTES__MASK);
	TransferSize.Or ((pStageData->GetPacketsToTransfer () << DWHCI_HOST_CHAN_XFER_SIZ_PACKETS__SHIFT)
			 & DWHCI_HOST_CHAN_XFER_SIZ_PACKETS__MASK);
	TransferSize.Or (pStageData->GetPID () << DWHCI_HOST_CHAN_XFER_SIZ_PID__SHIFT);
	TransferSize.Write ();

	// set DMA address
	CDWHCIRegister DMAAddress (DWHCI_HOST_CHAN_DMA_ADDR (nChannel),
				   pStageData->GetDMAAddress () + GPU_MEM_BASE);
	DMAAddress.Write ();

	CleanDataCache ();
	InvalidateDataCache ();
	DataMemBarrier ();

	// set split control
	CDWHCIRegister SplitControl (DWHCI_HOST_CHAN_SPLIT_CTRL (nChannel), 0);
	if (pStageData->IsSplit ())
	{
		SplitControl.Or (pStageData->GetHubPortAddress ());
		SplitControl.Or (   pStageData->GetHubAddress ()
				 << DWHCI_HOST_CHAN_SPLIT_CTRL_HUB_ADDRESS__SHIFT);
		SplitControl.Or (   pStageData->GetSplitPosition ()
				 << DWHCI_HOST_CHAN_SPLIT_CTRL_XACT_POS__SHIFT);
		if (pStageData->IsSplitComplete ())
		{
			SplitControl.Or (DWHCI_HOST_CHAN_SPLIT_CTRL_COMPLETE_SPLIT);
		}
		SplitControl.Or (DWHCI_HOST_CHAN_SPLIT_CTRL_SPLIT_ENABLE);
	}
	SplitControl.Write ();

	// set channel parameters
	CDWHCIRegister Character (DWHCI_HOST_CHAN_CHARACTER (nChannel));
	Character.Read ();
	Character.And (~DWHCI_HOST_CHAN_CHARACTER_MAX_PKT_SIZ__MASK);
	Character.Or (pStageData->GetMaxPacketSize () & DWHCI_HOST_CHAN_CHARACTER_MAX_PKT_SIZ__MASK);

	Character.And (~DWHCI_HOST_CHAN_CHARACTER_MULTI_CNT__MASK);
	Character.Or (1 << DWHCI_HOST_CHAN_CHARACTER_MULTI_CNT__SHIFT);		// TODO: optimize

	if (pStageData->IsDirectionIn ())
	{
		Character.Or (DWHCI_HOST_CHAN_CHARACTER_EP_DIRECTION_IN);
	}
	else
	{
		Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_DIRECTION_IN);
	}

	if (pStageData->GetSpeed () == USBSpeedLow)
	{
		Character.Or (DWHCI_HOST_CHAN_CHARACTER_LOW_SPEED_DEVICE);
	}
	else
	{
		Character.And (~DWHCI_HOST_CHAN_CHARACTER_LOW_SPEED_DEVICE);
	}

	Character.And (~DWHCI_HOST_CHAN_CHARACTER_DEVICE_ADDRESS__MASK);
	Character.Or (pStageData->GetDeviceAddress () << DWHCI_HOST_CHAN_CHARACTER_DEVICE_ADDRESS__SHIFT);

	Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_TYPE__MASK);
	Character.Or (pStageData->GetEndpointType () << DWHCI_HOST_CHAN_CHARACTER_EP_TYPE__SHIFT);

	Character.And (~DWHCI_HOST_CHAN_CHARACTER_EP_NUMBER__MASK);
	Character.Or (pStageData->GetEndpointNumber () << DWHCI_HOST_CHAN_CHARACTER_EP_NUMBER__SHIFT);

	CDWHCIFrameScheduler *pFrameScheduler = pStageData->GetFrameScheduler ();
	if (pFrameScheduler != 0)
	{
		pFrameScheduler->WaitForFrame ();

		if (pFrameScheduler->IsOddFrame ())
		{
			Character.Or (DWHCI_HOST_CHAN_CHARACTER_PER_ODD_FRAME);
		}
		else
		{
			Character.And (~DWHCI_HOST_CHAN_CHARACTER_PER_ODD_FRAME);
		}
	}

	CDWHCIRegister ChanInterruptMask (DWHCI_HOST_CHAN_INT_MASK(nChannel));
	ChanInterruptMask.Set (pStageData->GetStatusMask ());
	ChanInterruptMask.Write ();
	
	Character.Or (DWHCI_HOST_CHAN_CHARACTER_ENABLE);
	Character.And (~DWHCI_HOST_CHAN_CHARACTER_DISABLE);
	Character.Write ();
}
Пример #9
0
TShutdownMode CKernel::Run (void)
{
	m_Logger.Write (FromKernel, LogNotice, "Compile time: " __DATE__ " " __TIME__);

	unsigned nSamples = m_Screen.GetWidth ();
	assert (nSamples > 0);
	
	unsigned *pBuffer = new unsigned[nSamples];
	if (pBuffer == 0)
	{
		m_Logger.Write (FromKernel, LogPanic, "Not enough memory");
	}

	CleanDataCache ();
	InvalidateDataCache ();

	unsigned nRunTime = Sampler (pBuffer, nSamples, 0, 0, SAMPLING_DELAY);
	if (nRunTime == 0)
	{
		m_Logger.Write (FromKernel, LogPanic, "Measurement of run time failed, try again!");
	}

	unsigned nSampleRateKHz = 1000 * nSamples / nRunTime;
	m_Logger.Write (FromKernel, LogNotice, "Sampling rate was %u KHz", nSampleRateKHz);
	m_Logger.Write (FromKernel, LogNotice, "Display covers %u us", nRunTime);
	m_Logger.Write (FromKernel, LogNotice, "A red line is drawn on every 10 us");

	unsigned nPosYLow  = m_Screen.GetHeight () / 2 + 40;
	unsigned nPosYHigh = m_Screen.GetHeight () / 2 - 40;

	boolean bLastLevel = FALSE;
	unsigned nLastMarker = 0;
	for (unsigned nSample = 0; nSample < nSamples; nSample++)
	{
		unsigned nTime = nRunTime * nSample / nSamples / 10;
		if (nLastMarker != nTime)
		{
			for (unsigned nPosY = nPosYHigh-20; nPosY <= nPosYLow+20; nPosY++)
			{
				m_Screen.SetPixel (nSample, nPosY, HIGH_COLOR);
			}

			nLastMarker = nTime;
		}

		assert (pBuffer != 0);
		boolean bThisLevel = pBuffer[nSample] & GPIO_INPUT_PIN_MASK ? TRUE : FALSE;

		unsigned nPosY = bThisLevel ? nPosYHigh : nPosYLow;
		m_Screen.SetPixel (nSample, nPosY,   NORMAL_COLOR);
		m_Screen.SetPixel (nSample, nPosY+1, NORMAL_COLOR);
		m_Screen.SetPixel (nSample, nPosY+2, NORMAL_COLOR);

		if (   nSample > 0
		    && bLastLevel != bThisLevel)
		{
			for (unsigned nPosY = nPosYHigh; nPosY <= nPosYLow+2; nPosY++)
			{
				m_Screen.SetPixel (nSample, nPosY, NORMAL_COLOR);
			}
		}

		bLastLevel = bThisLevel;
	}

	delete pBuffer;
	
	return ShutdownHalt;
}