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

📄 cfw.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
字号:
/*
*   The content of this file or document is CONFIDENTIAL and PROPRIETARY
*   to Jade Technologies Co., Ltd.  It is subjected to the terms of a
*   License Agreement between Licensee and Jade Technologies Co., Ltd.
*   restricting among other things, the use, reproduction, distribution
*   and transfer.  Each of the embodiments, including this information 
*   and any derivative work shall retain this copyright notice.
* 
*   Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd. 
*   All rights reserved.
*/
// ----------------------------------------------------------------
// File:     cfw.c,v
// Revision: 1.0
// ----------------------------------------------------------------
// $

#include <windows.h>

// these are defined in assembly language
extern void ARMFlushDCache(DWORD, DWORD, DWORD, DWORD);
extern void ARMFlushDCacheLines(LPVOID, DWORD, DWORD);
extern void ARMCleanDCache(DWORD, DWORD, DWORD, DWORD);
extern void ARMCleanDCacheLines(LPVOID, DWORD, DWORD);
extern void ARMFlushICache(void);
extern void ARMFlushICacheLines(LPVOID, DWORD, DWORD);
extern void ARMClearITLB(void);
extern void ARMClearITLBEntry(LPVOID);
extern void ARMClearDTLB(void);
extern void ARMClearDTLBEntry(LPVOID);
extern DWORD ARMReadCacheInfo(void);

/*
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)
{
    // cache maintenance constant
    const DWORD MMU_PAGE_SIZE = 4096;

    // We can flush individual entries in the instruction TLB    
    if (dwFlags & CACHE_SYNC_FLUSH_I_TLB)
    {
        if(dwLength == MMU_PAGE_SIZE) {
            // flush one TLB entry
            ARMClearITLBEntry(pAddr);
        } else {
            // flush the whole TLB
            ARMClearITLB();
        }
    }
    
    // We can flush individual entries in the data TLB    
    if (dwFlags & CACHE_SYNC_FLUSH_D_TLB)
    {
        // check first for TLB updates forced by paging
        if(dwLength == MMU_PAGE_SIZE) {
            // flush one TLB entry
            ARMClearDTLBEntry(pAddr);
        } else {
            // flush the whole TLB
            ARMClearDTLB();
        }
    }

    // Avoid reading the cache info if there is nothing more to do
    if ((dwFlags & (CACHE_SYNC_DISCARD | CACHE_SYNC_WRITEBACK | CACHE_SYNC_INSTRUCTIONS)) != 0)
    {
        DWORD dwCacheInfo = ARMReadCacheInfo();

        /*
        ** Cache information other than the page size needs to be extracted
        ** from CP15 info. See the ARM ARM for more details. This code will
        ** work for any CPU with split caches that conform to the ARM ARM (v5)
        */

#define CACHE_LINES_PER_SET_BITS(_cdata_) (((_cdata_)>>3) & 7)
#define CACHE_LINE_SIZE_BITS(_cdata_)      ((_cdata_)     & 3)
#define CACHE_M(_cdata_)                  (((_cdata_)>>2) & 1)
#define CACHE_SIZE_BITS(_cdata_)          (((_cdata_)>>6) & 7)

        // Extract the info from the DCache field (bits 23-12)
#define DCACHE_FIELD               (dwCacheInfo >> 12)
#define DCACHE_LINES_PER_SET_BITS  CACHE_LINES_PER_SET_BITS(DCACHE_FIELD)
#define DCACHE_LINES_PER_SET       ((2+CACHE_M(DCACHE_FIELD)) << (DCACHE_LINES_PER_SET_BITS-1))
#define DCACHE_LINE_SIZE           (1<<(CACHE_LINE_SIZE_BITS(DCACHE_FIELD)+3))
#define DCACHE_SETS                (1<<(CACHE_SIZE_BITS(DCACHE_FIELD)+6-DCACHE_LINES_PER_SET_BITS-CACHE_LINE_SIZE_BITS(DCACHE_FIELD)))

        // Extract the info from the ICache field (bits 12-0)
#define ICACHE_FIELD (dwCacheInfo)
#define ICACHE_LINE_SIZE (1 << (CACHE_LINE_SIZE_BITS(ICACHE_FIELD)+3))

        if (dwFlags & CACHE_SYNC_DISCARD)
        {
            // write back and invalidate the selected portions of the data cache
            if(dwLength == 0) {
                if(pAddr == 0) {
                    // yes, invalidate it also
                    ARMFlushDCache(DCACHE_LINES_PER_SET - 1, DCACHE_SETS - 1, (32 - DCACHE_LINES_PER_SET_BITS), DCACHE_LINE_SIZE);
                }
            } else if(dwLength > MMU_PAGE_SIZE) {
                    // too much work, invalidate the whole cache
                    ARMFlushDCache(DCACHE_LINES_PER_SET - 1, DCACHE_SETS - 1, (32 - DCACHE_LINES_PER_SET_BITS), DCACHE_LINE_SIZE);
            } else {
                // normalize address to cache line alignment and adjust the length accordingly
                DWORD dwNormalizedAddress = (DWORD) pAddr & ~(DCACHE_LINE_SIZE - 1);
                DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);
            
                // flush all the indicated cache entries
                ARMFlushDCacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength, DCACHE_LINE_SIZE);
            }
        }
        else if (dwFlags & CACHE_SYNC_WRITEBACK) {
            // write back the address range -- is it the whole cache?
            if(dwLength == 0) {
                if(pAddr == 0) {
                    // yes, invalidate it also
                    ARMCleanDCache(DCACHE_LINES_PER_SET - 1, DCACHE_SETS - 1, (32 - DCACHE_LINES_PER_SET_BITS), DCACHE_LINE_SIZE);
                }
            } else if(dwLength > MMU_PAGE_SIZE) {
                    // too much work, invalidate the whole cache
                    ARMCleanDCache(DCACHE_LINES_PER_SET - 1, DCACHE_SETS - 1, (32 - DCACHE_LINES_PER_SET_BITS), DCACHE_LINE_SIZE);
            } else {
                // normalize address to cache line alignment and adjust the length accordingly
                DWORD dwNormalizedAddress = (DWORD) pAddr & ~(DCACHE_LINE_SIZE - 1);
                DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);
            
                // write back all the indicated cache entries
                ARMCleanDCacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength, DCACHE_LINE_SIZE);
            }
        }
    
        if (dwFlags & CACHE_SYNC_INSTRUCTIONS)
        {
            if(dwLength == 0) {
                if(pAddr == 0) {
                    // yes, invalidate it also
                    ARMFlushICache();
                }
            } else if(dwLength > MMU_PAGE_SIZE) {
                    // too much work, invalidate the whole cache
                    ARMFlushICache();
            } else {
                // normalize address to cache line alignment and adjust the length accordingly
                DWORD dwNormalizedAddress = (DWORD) pAddr & ~(ICACHE_LINE_SIZE - 1);
                DWORD dwNormalizedLength = dwLength + ((DWORD) pAddr - dwNormalizedAddress);
            
                // write back all the indicated cache entries
                ARMFlushICacheLines((LPVOID) dwNormalizedAddress, dwNormalizedLength, ICACHE_LINE_SIZE);
            }
        }
    }
}

⌨️ 快捷键说明

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