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

📄 flush.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  flush.c
//
//  This file implements OEMCacheRangeFlush for Au1 based systems. The Au1 SoC
//  has coherent data cache, so we don't need to do anything when DATA cache
//  operation is required...
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oal_log.h>
#include <oal_cache.h>

//------------------------------------------------------------------------------
//
//  Function:  OEMCacheRangeFlush
//
//  Implements entry point for all cache and TLB flush operations. It takes
//  following parameters:
//    
//      pAddress - starting VA on which the cache operation is to be performed
//      length - length of flush
//      flags  - 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.
//            
//  If both pAddress and length are 0, the entire cache (or TLB, as directed by
//  flags) 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 
//  length == PAGE_SIZE, pAddress is guaranteed to be on a page boundary.
//                
//  Note: On stress test we hit issue with I-Cache inconsistency. It looks like
//  hardware related issue. The code used when AU1_CACHE_ISSUE flush/clean all
//  cache memory.
//
#define AU1_CACHE_ISSUE


//------------------------------------------------------------------------------
//
//  Function:  OEMCacheRangeFlush
//
void OEMCacheRangeFlush(VOID *pAddress, DWORD length, DWORD flags)
{
    OALMSGS(OAL_CACHE&&OAL_VERBOSE, (
        L"+OEMCacheRangeFlush(0x%08x, %d, 0x%08x)\r\n", pAddress, length, flags
    ));

#ifndef AU1_CACHE_ISSUE

    if ((flags & CACHE_SYNC_DISCARD) != 0) {
        // Write back and invalidate the selected portions of the data cache
        if (length == 0) {
            if (pAddress == NULL) OALFlushDCache();
        } else {
            // Normalize address to cache line alignment
            UINT32 mask = g_oalCacheInfo.L1DLineSize - 1;
            UINT32 address = (UINT32)pAddress & ~mask;
            // Adjust size to reflect cache line alignment
            length += (UINT32)pAddress - address;
            // If range is bigger than cache size flush all
            if (length >= g_oalCacheInfo.L1DSize) {
                OALFlushDCache();
            } else {                
                // Flush all the indicated cache entries
                OALFlushDCacheLines((VOID*)address, length);
            }                
        }
    } else if ((flags & CACHE_SYNC_WRITEBACK) != 0) {
        // Write back the selected portion of the data cache
        if (length == 0) {
            if (pAddress == NULL) OALCleanDCache();
        } else {
            // Normalize address to cache line alignment
            UINT32 mask = g_oalCacheInfo.L1DLineSize - 1;
            UINT32 address = (UINT32)pAddress & ~mask;
            // Adjust size to reflect cache line alignment
            length += (UINT32)pAddress - address;
            // If range is bigger than cache size clean all
            if (length >= g_oalCacheInfo.L1DSize) {
                OALCleanDCache();
            } else {                
                // Flush all the indicated cache entries
                OALCleanDCacheLines((VOID*)address, length);
            }                
        }
    }

    if ((flags & CACHE_SYNC_INSTRUCTIONS) != 0) {
        if (length == 0) {
            if (pAddress == NULL) OALFlushICache();
        } else {
            // Normalize address to cache line alignment
            UINT32 mask = g_oalCacheInfo.L1ILineSize - 1;
            UINT32 address = (UINT32)pAddress & ~mask;
            length += (UINT32)pAddress - address;
            if (length >= g_oalCacheInfo.L1ISize) {
                OALFlushICache();
            } else {        
                OALFlushICacheLines((VOID*)address, length);
            }                
        }
    }

#else

    if ((flags & CACHE_SYNC_DISCARD) != 0) {
        BOOL enabled = INTERRUPTS_ENABLE(FALSE);
        OALFlushDCache();
        INTERRUPTS_ENABLE(enabled);
    } else if ((flags & CACHE_SYNC_WRITEBACK) != 0) {
        BOOL enabled = INTERRUPTS_ENABLE(FALSE);
        OALCleanDCache();
        INTERRUPTS_ENABLE(enabled);
    }

    if ((flags & CACHE_SYNC_INSTRUCTIONS) != 0) {
        BOOL enabled = INTERRUPTS_ENABLE(FALSE);
        OALFlushICache();
        INTERRUPTS_ENABLE(enabled);
    }        

#endif

    // We assume a unified instruction/data TLB.  Although MIPS supports
    // probing for individual TLB entries, probing is not efficient because
    // of the way Windows CE handles migrating threads between processes.
    // Probing requires the address space ID and the virtual address to match,
    // and the CE model allows a VA to appear with multiple ASIDs.
    // This means we would have to probe all valid ASIDs for a particular VA,
    // so it more efficient to simply clear the whole TLB.

    if (flags & CACHE_SYNC_FLUSH_TLB) {
        // flush the whole TLB
        OALClearTLB();
    }

    OALMSGS(OAL_CACHE&&OAL_VERBOSE, (L"-OEMCacheRangeFlush\r\n"));
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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