summaryrefslogtreecommitdiff
path: root/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s
diff options
context:
space:
mode:
Diffstat (limited to 'MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s')
-rw-r--r--MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s96
1 files changed, 96 insertions, 0 deletions
diff --git a/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s b/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s
new file mode 100644
index 0000000000..6e467f0d13
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ipf/FlushCacheRange.s
@@ -0,0 +1,96 @@
+//++
+// 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)
+