Did not check in new files correctly the first time!
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ipf / FlushCacheRange.s
1 //++
2 // Copyright (c) 2006, Intel Corporation
3 // All rights reserved. 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 // FlushCacheRange.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 #include "IpfDefines.h"
24
25 //
26 // Invalidates a range of instruction cache lines in the cache coherency domain
27 // of the calling CPU.
28 //
29 // Invalidates the instruction cache lines specified by Address and Length. If
30 // Address is not aligned on a cache line boundary, then entire instruction
31 // cache line containing Address is invalidated. If Address + Length is not
32 // aligned on a cache line boundary, then the entire instruction cache line
33 // containing Address + Length -1 is invalidated. This function may choose to
34 // invalidate the entire instruction cache if that is more efficient than
35 // invalidating the specified range. If Length is 0, the no instruction cache
36 // lines are invalidated. Address is returned.
37 //
38 // If Length is greater than (MAX_ADDRESS - Address + 1), then ASSERT().
39 //
40 // @param Address The base address of the instruction cache lines to
41 // invalidate. If the CPU is in a physical addressing mode, then
42 // Address is a physical address. If the CPU is in a virtual
43 // addressing mode, then Address is a virtual address.
44 //
45 // @param Length The number of bytes to invalidate from the instruction cache.
46 //
47 // @return Address
48 //
49 // VOID *
50 // EFIAPI
51 // IpfFlushCacheRange (
52 // IN VOID *Address,
53 // IN UINTN Length
54 // );
55 //
56 PROCEDURE_ENTRY (IpfFlushCacheRange)
57
58 NESTED_SETUP (5,8,0,0)
59
60 mov loc2 = ar.lc
61
62 mov loc3 = in0 // Start address.
63 mov loc4 = in1;; // Length in bytes.
64
65 cmp.eq p6,p7 = loc4, r0;; // If Length is zero then don't flush any cache
66 (p6) br.spnt.many DoneFlushingC;;
67
68 add loc4 = loc4,loc3
69 mov loc5 = 1;;
70 sub loc4 = loc4, loc5 ;; // the End address to flush
71
72 dep loc3 = r0,loc3,0,5
73 dep loc4 = r0,loc4,0,5;;
74 shr loc3 = loc3,5
75 shr loc4 = loc4,5;; // 32 byte cache line
76
77 sub loc4 = loc4,loc3;; // total flush count, It should be add 1 but
78 // the br.cloop will first execute one time
79 mov loc3 = in0
80 mov loc5 = 32
81 mov ar.lc = loc4;;
82
83 StillFlushingC:
84 fc loc3;;
85 sync.i;;
86 srlz.i;;
87 add loc3 = loc5,loc3;;
88 br.cloop.sptk.few StillFlushingC;;
89
90 DoneFlushingC:
91 mov ar.lc = loc2
92 mov r8 = in0 // return *Address
93 NESTED_RETURN
94
95 PROCEDURE_EXIT (IpfFlushCacheRange)
96