//++ // Copyright (c) 2006, Intel Corporation // All rights reserved. This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License // which accompanies this distribution. The full text of the license may be found at // http://opensource.org/licenses/bsd-license.php // // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // // Module Name: // FlushCacheRange.s // // Abstract: // Assemble routine to flush cache lines // // Revision History: // //-- .file "IpfCpuCache.s" #include "IpfMacro.i" #include "IpfDefines.h" // // Invalidates a range of instruction cache lines in the cache coherency domain // of the calling CPU. // // Invalidates the instruction cache lines specified by Address and Length. If // Address is not aligned on a cache line boundary, then entire instruction // cache line containing Address is invalidated. If Address + Length is not // aligned on a cache line boundary, then the entire instruction cache line // containing Address + Length -1 is invalidated. This function may choose to // invalidate the entire instruction cache if that is more efficient than // invalidating the specified range. If Length is 0, the no instruction cache // lines are invalidated. Address is returned. // // If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT(). // // @param Address The base address of the instruction cache lines to // invalidate. If the CPU is in a physical addressing mode, then // Address is a physical address. If the CPU is in a virtual // addressing mode, then Address is a virtual address. // // @param Length The number of bytes to invalidate from the instruction cache. // // @return Address // // VOID * // EFIAPI // IpfFlushCacheRange ( // IN VOID *Address, // IN UINTN Length // ); // PROCEDURE_ENTRY (IpfFlushCacheRange) NESTED_SETUP (5,8,0,0) mov loc2 = ar.lc mov loc3 = in0 // Start address. mov loc4 = in1;; // Length in bytes. cmp.eq p6,p7 = loc4, r0;; // If Length is zero then don't flush any cache (p6) br.spnt.many DoneFlushingC;; add loc4 = loc4,loc3 mov loc5 = 1;; sub loc4 = loc4, loc5 ;; // the End address to flush dep loc3 = r0,loc3,0,5 dep loc4 = r0,loc4,0,5;; shr loc3 = loc3,5 shr loc4 = loc4,5;; // 32 byte cache line sub loc4 = loc4,loc3;; // total flush count, It should be add 1 but // the br.cloop will first execute one time mov loc3 = in0 mov loc5 = 32 mov ar.lc = loc4;; StillFlushingC: fc loc3;; sync.i;; srlz.i;; add loc3 = loc5,loc3;; br.cloop.sptk.few StillFlushingC;; DoneFlushingC: mov ar.lc = loc2 mov r8 = in0 // return *Address NESTED_RETURN PROCEDURE_EXIT (IpfFlushCacheRange)