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

📄 cfwbvd1.c

📁 Xcale270Bsp包,wince平台
💻 C
📖 第 1 页 / 共 4 页
字号:
If this function is implemented by the OEM, the pointer pQueryPerformanceCounter
should be initialized as follows:

BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
*/

BOOL OEMQueryPerformanceCounter(LARGE_INTEGER *lpliPerformanceCount)
{
    extern DWORD PerfCountSinceTick();
    extern DWORD CurMSec;
    
    ULARGE_INTEGER liBase;
    DWORD dwCurCount;

    //
    // Get current tick count
    //
    liBase.QuadPart = CurMSec * RESCHED_INCREMENT;

    //
    // Get ticks since last timer firing
    //
    dwCurCount = PerfCountSinceTick();

    lpliPerformanceCount->QuadPart = liBase.QuadPart + dwCurCount;
    
    return TRUE;
}


/* ************************************************************************* */
/*
OEMQueryPerformanceFrequency

The OEMQueryPerformanceFrequency function retrieves the frequency of 
the high-resolution performance counter, if one exists. 

BOOL OEMQueryPerformanceFrequency(

    LARGE_INTEGER  *lpliPerformanceFreq 	// address of current frequency
   );	

Parameters

lpliPerformanceFreq

Points to a variable that the function sets, in ticks per second, to 
the current performance-counter frequency. If the installed hardware 
does not support a high-resolution performance counter, this parameter
can be to zero. 

Return Value

If the installed hardware supports a high-resolution performance 
counter, the return value is TRUE.
If the installed hardware does not support a high-resolution 
performance counter, the return value is FALSE.

If this function is implemented by the OEM, the pointer pQueryPerformanceFrequency
should be initialized as follows:

BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpPerformanceFrequency)=OEMQueryPerformanceFrequency;
*/

BOOL OEMQueryPerformanceFrequency(LARGE_INTEGER *lpliPerformanceFreq)
{
    // 
    // Return the performance clock's freq in seconds
    // (We use the OST for these calls...)
    //
    lpliPerformanceFreq->HighPart=0;
    lpliPerformanceFreq->LowPart=OEM_CLOCK_FREQ;
    return TRUE;
}

// set pointers to OEM functions
BOOL (*pQueryPerformanceCounter)(LARGE_INTEGER *lpliPerformanceCount)=OEMQueryPerformanceCounter;
BOOL (*pQueryPerformanceFrequency)(LARGE_INTEGER *lpliPerformanceFreq)=OEMQueryPerformanceFrequency;



#if defined(USING_COPROCSUPPORT) || defined(USING_XSCALEBROWSER)
/* ************************************************************************* */
/*
OEMInitCoProcRegisterSavedArea

   This function sets up the memory area allocated for use in saving/restoring
   CoProcessor registers.  This function is called for every thread created.

Parameters
   Pointer to a memory are defined above by the value of cbNkCoProcRegSize

Return Value
   None
*/
void OEMInitCoProcRegisterSavedArea(LPBYTE pArea)
{
   // Set initial state of CoProc Reg Area (which will in turn be the Register value) here
   memset(pArea,0,284);

}


/* ************************************************************************* */
/*
OEMSaveCoProcRegister

   This function calls the Assembly routines to read the contents of the 
   CoProcessor register, storing it in pArea.  It is only called when both 
   cbNkCoProcRegSize and fNKSaveCoProcReg are fo non-zero values.  This 
   function is called every time a thread is to be switched out, so it 
   adds to the overall worst-case time of thread switches!

Parameters
   Pointer to a memory are defined above by the value of cbNkCoProcRegSize

Return Value
   None
*/
void OEMSaveCoProcRegister( LPBYTE pArea )
{
#ifdef USING_XSCALEBROWSER
  if (XSCBwrThreadID == GetCurrentThreadId() ) {
    XSCBwrExecutionTraceOff(0);
    XSCBwrSaveThreadContextArea.ThreadId = XSCBwrThreadID;
    XSCBwrSaveThreadContextArea.ContextPtr = (DWORD) pArea;
    BVDSaveCoProcessors((LPBYTE)
			&XSCBwrSaveThreadContextArea.Context_Area[0] );
    return;
  }
#endif // USING_XSCALEBROWSER
    BVDSaveCoProcessors( pArea );
}


/* ************************************************************************* */
/*
OEMRestoreCoProcRegister

   This function calls the Assembly routines to set the contents of the 
   CoProcessor register back to what was stored in pArea.  It is only called
   when both cbNkCoProcRegSize and fNKSaveCoProcReg are fo non-zero values.
   This function is called every time a thread is to be switched in, so it 
   adds to the overall worst-case time of thread switches!

Parameters
   Pointer to a memory are defined above by the value of cbNkCoProcRegSize

Return Value
   None
*/
void OEMRestoreCoProcRegister( LPBYTE pArea)
{
#ifdef USING_XSCALEBROWSER
  if (XSCBwrSaveThreadContextArea.ContextPtr == (DWORD) pArea ) {
    BVDRestoreCoProcessors(
			(LPBYTE)&XSCBwrSaveThreadContextArea.Context_Area[0] );
    if ( XSCBwrThreadID == (DWORD) INVALID_HANDLE_VALUE ) {
      XSCBwrSaveThreadContextArea.ContextPtr = 0;
    } else {
      XSCBwrExecutionTraceOn(0);
    }
    return;
  }
#endif //USING_XSCALEBROWSER
    BVDRestoreCoProcessors( pArea );
}

#endif  //USING_COPROCSUPPORT || defined(USING_XSCALEBROWSER)


#if (WINCEOSVER >= 420)


/*
OEMCacheRangeFlush()

  Single OAL entry point for all cache flush operations.
  
    Parameters:
    
      pAddr	 - starting VA on which the cache operation is to be performed
      dwLength - length of flush
      dwFlags  - specifies the cache operation to be performed:
      
        CACHE_SYNC_WRITEBACK: write back DATA cache
        CACHE_SYNC_DISCARD: write back and discard DATA cache
        CACHE_SYNC_INSTRUCTIONS: discard I-Cache
        CACHE_SYNC_FLUSH_I_TLB: flush instruction TLB
        CACHE_SYNC_FLUSH_D_TLB: flush data TLB
        CACHE_SYNC_FLUSH_TLB: flush both I/D TLB
        CACHE_SYNC_L2_WRITEBACK: write back L2 cache
        CACHE_SYNC_L2_DISCARD: write back and discard L2 cache
        CACHE_SYNC_ALL: perform all the above operations.
        
    Return Value
          
        None.
            
    Remarks
              
        If both pAddr and dwLength are 0, the entire cache (or TLB, as directed by dwFlags) will be flushed.
        Only the kernel can set the TLB flush flags when it calls this routine, and when a TLB flush is performed
        with dwLength == PAGE_SIZE, pAddr is guaranteed to be on a page boundary.
                
*/


void OEMCacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags)
{
	const DWORD PID_MASK = 0xFE000000;	   // Adx[31:25]

    // cache maintenance constants
    //
    const DWORD CACHE_LINE_SIZE = 32;      		// 32 bytes per line
    const DWORD PAGE_SIZE       = 4096;         // 4KB pages used by winCE on XScale
    const DWORD CACHE_SIZE      = 0x8000;       // 32KB cache size

    // these are defined in cache.s (ASM routines)
    //
    extern void FlushDCache(void);
    extern void WriteBackDCacheLines(LPVOID, DWORD);
    extern void WriteBackAndInvalidateDCacheLines(LPVOID, DWORD);
    extern void FlushICache(void);
    extern void FlushICacheLines(LPVOID, DWORD);
    extern void ClearITLB(void);
    extern void ClearDTLB(void);
    extern void ClearDTLBEntry(LPVOID);
    extern void ClearITLBEntry(LPVOID);
    extern void TLBClear(void);



	///////////////////////////////////////////////////////////////////////////
	//  Flush DCACHE 
	///////////////////////////////////////////////////////////////////////////

	if (dwFlags & CACHE_SYNC_DISCARD)
	{
		// Write-back and invalidate either all or a range.  
		//  For CACHE_SYNC_ALL, it is expected that we will invalidate the d$; we would want to use this block
		//

		if (! ((DWORD)pAddr & PID_MASK))
		{
			// we have a pidifiable VA; must not try and range it
			//
			FlushDCache();
		}
		else if (!(dwLength | (DWORD)pAddr))
		{
			FlushDCache();
		}
		else if (dwLength >= (DWORD)CACHE_SIZE)
		{
			FlushDCache();
		}
		else
		{
			DWORD dwNormalizedAddress = (DWORD) pAddr & ~(CACHE_LINE_SIZE - 1);
			DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);

			// Clean all the indicated cache entries.  Must invalidate each line.
			//
			WriteBackAndInvalidateDCacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength);
		}
	}

	else if (dwFlags & CACHE_SYNC_WRITEBACK)
	{
		// write back the address range
		//
		if (! ((DWORD)pAddr & PID_MASK))
		{
			// we have a pidifiable VA; must not try and range it
			//
			FlushDCache();
		}
		else if (!(dwLength | (DWORD)pAddr))
		{
			FlushDCache();
		}
		else if (dwLength >= (DWORD)CACHE_SIZE)
		{
			FlushDCache();
		}
		else
		{
			DWORD dwNormalizedAddress = (DWORD) pAddr & ~(CACHE_LINE_SIZE - 1);
			DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);

			// Clean all the indicated cache entries.  Do not invalidate.
			//
			WriteBackDCacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength);
		}
	}



	///////////////////////////////////////////////////////////////////////////
	//  Flush ICACHE
	///////////////////////////////////////////////////////////////////////////

	if (dwFlags & CACHE_SYNC_INSTRUCTIONS)
	{

		if (! ((DWORD)pAddr & PID_MASK))
		{
			// we have a pidifiable VA; must not try and range it
			//
			FlushICache();
		}
		else if (!(dwLength | (DWORD)pAddr))
		{
			FlushICache();
		}
		else if (dwLength >= (DWORD)CACHE_SIZE)
		{
			FlushICache();
		}
		else
		{
			DWORD dwNormalizedAddress = (DWORD) pAddr & ~(CACHE_LINE_SIZE - 1);
			DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);

			// flush all the indicated cache entries
			//
			FlushICacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength);         
		}
	}


	///////////////////////////////////////////////////////////////////////////
	//  Flush D-TLB
	///////////////////////////////////////////////////////////////////////////

	if (dwFlags & CACHE_SYNC_FLUSH_D_TLB)
	{
		if (! ((DWORD)pAddr & PID_MASK))
		{
			// we have a pidifiable VA; must not try and range it
			//
			ClearDTLB();
		}
		else if (dwLength == PAGE_SIZE)
		{
			// flush a single entry from the I-TLB
			//
			ClearDTLBEntry(pAddr);
		}
		else
		{
			ClearDTLB();
		}
	}


	///////////////////////////////////////////////////////////////////////////
	//  Flush I-TLB
	///////////////////////////////////////////////////////////////////////////

	if (dwFlags & CACHE_SYNC_FLUSH_I_TLB)
	{
		if (! ((DWORD)pAddr & PID_MASK))
		{
			// we have a pidifiable VA; must not try and range it
			//
			ClearITLB();
		}
		else if (dwLength == PAGE_SIZE)
		{
			// flush a single entry from the I-TLB
			//
			ClearITLBEntry(pAddr);         
		}
		else
		{
			ClearITLB();
		}

	}

	return;
}



/*
 * Called by Kernel to get status of processor features
 * supported by this OEM.
 */
BOOL OEMIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{
	BOOL	rtnValue = FALSE;

	switch (dwProcessorFeature)
	{
		case PF_ARM_V5:
		case PF_ARM_THUMB:
		case PF_ARM_DSP:
		case PF_ARM_INTEL_WMMX:
		case PF_ARM_INTEL_XSCALE:
		case PF_ARM_INTEL_PMU:
		case PF_ARM_WRITE_BACK_CACHE:
		case PF_ARM_CACHE_CAN_BE_LOCKED_DOWN:
			rtnValue = TRUE;
			break;
		default:

			rtnValue = FALSE;
			break;
	}

	return rtnValue;

}

#endif  // winceosver


⌨️ 快捷键说明

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