1 //++ 2 // Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> 3 // This program and the accompanying materials 4 // are licensed and made available under the terms and conditions of the BSD License 5 // which accompanies this distribution. The full text of the license may be found at 6 // http://opensource.org/licenses/bsd-license.php. 7 // 8 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 10 // 11 // Module Name: 12 // InternalFlushCacheRange.s 13 // 14 // Abstract: 15 // Assemble routine to flush cache lines 16 // 17 // Revision History: 18 // 19 //-- 20 .file "IpfCpuCache.s" 21 22 #include <IpfMacro.i> 23 24 // 25 // Internal worker function to invalidate a range of instruction cache lines 26 // in the cache coherency domain of the calling CPU. 27 // 28 // Internal worker function to invalidate the instruction cache lines specified 29 // by Address and Length. If Address is not aligned on a cache line boundary, 30 // then entire instruction cache line containing Address is invalidated. If 31 // Address + Length is not aligned on a cache line boundary, then the entire 32 // instruction cache line containing Address + Length -1 is invalidated. This 33 // function may choose to invalidate the entire instruction cache if that is more 34 // efficient than invalidating the specified range. If Length is 0, the no instruction 35 // cache lines are invalidated. Address is returned. 36 // This function is only available on IPF. 37 // 38 // @param Address The base address of the instruction cache lines to 39 // invalidate. If the CPU is in a physical addressing mode, then 40 // Address is a physical address. If the CPU is in a virtual 41 // addressing mode, then Address is a virtual address. 42 // 43 // @param Length The number of bytes to invalidate from the instruction cache. 44 // 45 // @return Address 46 // 47 // VOID * 48 // EFIAPI 49 // InternalFlushCacheRange ( 50 // IN VOID *Address, 51 // IN UINTN Length 52 // ); 53 // 54 PROCEDURE_ENTRY (InternalFlushCacheRange) 55 56 NESTED_SETUP (5,8,0,0) 57 58 mov loc2 = ar.lc 59 60 mov loc3 = in0 // Start address. 61 mov loc4 = in1;; // Length in bytes. 62 63 cmp.eq p6,p7 = loc4, r0;; // If Length is zero then don't flush any cache 64 (p6) br.spnt.many DoneFlushingC;; 65 66 add loc4 = loc4,loc3 67 mov loc5 = 1;; 68 sub loc4 = loc4, loc5 ;; // the End address to flush 69 70 dep loc3 = r0,loc3,0,5 71 dep loc4 = r0,loc4,0,5;; 72 shr loc3 = loc3,5 73 shr loc4 = loc4,5;; // 32 byte cache line 74 75 sub loc4 = loc4,loc3;; // total flush count, It should be add 1 but 76 // the br.cloop will first execute one time 77 mov loc3 = in0 78 mov loc5 = 32 79 mov ar.lc = loc4;; 80 81 StillFlushingC: 82 fc loc3;; 83 sync.i;; 84 srlz.i;; 85 add loc3 = loc5,loc3;; 86 br.cloop.sptk.few StillFlushingC;; 87 88 DoneFlushingC: 89 mov ar.lc = loc2 90 mov r8 = in0 // return *Address 91 NESTED_RETURN 92 93 PROCEDURE_EXIT (InternalFlushCacheRange) 94 95