Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Cache flushing routines. | |
3 | * | |
2074615a DMT |
4 | * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co |
5 | * David Mosberger-Tang <davidm@hpl.hp.com> | |
08357f82 ZM |
6 | * |
7 | * 05/28/05 Zoltan Menyhart Dynamic stride size | |
1da177e4 | 8 | */ |
08357f82 | 9 | |
1da177e4 | 10 | #include <asm/asmmacro.h> |
e007c533 | 11 | #include <asm/export.h> |
08357f82 | 12 | |
1da177e4 LT |
13 | |
14 | /* | |
15 | * flush_icache_range(start,end) | |
08357f82 ZM |
16 | * |
17 | * Make i-cache(s) coherent with d-caches. | |
18 | * | |
19 | * Must deal with range from start to end-1 but nothing else (need to | |
1da177e4 | 20 | * be careful not to touch addresses that may be unmapped). |
08357f82 ZM |
21 | * |
22 | * Note: "in0" and "in1" are preserved for debugging purposes. | |
1da177e4 | 23 | */ |
1f7ad57b | 24 | .section .kprobes.text,"ax" |
1da177e4 | 25 | GLOBAL_ENTRY(flush_icache_range) |
08357f82 | 26 | |
1da177e4 | 27 | .prologue |
08357f82 ZM |
28 | alloc r2=ar.pfs,2,0,0,0 |
29 | movl r3=ia64_i_cache_stride_shift | |
30 | mov r21=1 | |
31 | ;; | |
32 | ld8 r20=[r3] // r20: stride shift | |
33 | sub r22=in1,r0,1 // last byte address | |
1da177e4 | 34 | ;; |
08357f82 ZM |
35 | shr.u r23=in0,r20 // start / (stride size) |
36 | shr.u r22=r22,r20 // (last byte address) / (stride size) | |
37 | shl r21=r21,r20 // r21: stride size of the i-cache(s) | |
38 | ;; | |
39 | sub r8=r22,r23 // number of strides - 1 | |
40 | shl r24=r23,r20 // r24: addresses for "fc.i" = | |
41 | // "start" rounded down to stride boundary | |
42 | .save ar.lc,r3 | |
43 | mov r3=ar.lc // save ar.lc | |
1da177e4 LT |
44 | ;; |
45 | ||
46 | .body | |
08357f82 | 47 | mov ar.lc=r8 |
1da177e4 | 48 | ;; |
08357f82 ZM |
49 | /* |
50 | * 32 byte aligned loop, even number of (actually 2) bundles | |
51 | */ | |
52 | .Loop: fc.i r24 // issuable on M0 only | |
53 | add r24=r21,r24 // we flush "stride size" bytes per iteration | |
54 | nop.i 0 | |
1da177e4 LT |
55 | br.cloop.sptk.few .Loop |
56 | ;; | |
57 | sync.i | |
58 | ;; | |
59 | srlz.i | |
60 | ;; | |
08357f82 | 61 | mov ar.lc=r3 // restore ar.lc |
1da177e4 LT |
62 | br.ret.sptk.many rp |
63 | END(flush_icache_range) | |
e007c533 | 64 | EXPORT_SYMBOL_GPL(flush_icache_range) |
62fdd767 FY |
65 | |
66 | /* | |
67 | * clflush_cache_range(start,size) | |
68 | * | |
69 | * Flush cache lines from start to start+size-1. | |
70 | * | |
71 | * Must deal with range from start to start+size-1 but nothing else | |
72 | * (need to be careful not to touch addresses that may be | |
73 | * unmapped). | |
74 | * | |
75 | * Note: "in0" and "in1" are preserved for debugging purposes. | |
76 | */ | |
77 | .section .kprobes.text,"ax" | |
78 | GLOBAL_ENTRY(clflush_cache_range) | |
79 | ||
80 | .prologue | |
81 | alloc r2=ar.pfs,2,0,0,0 | |
82 | movl r3=ia64_cache_stride_shift | |
83 | mov r21=1 | |
84 | add r22=in1,in0 | |
85 | ;; | |
86 | ld8 r20=[r3] // r20: stride shift | |
87 | sub r22=r22,r0,1 // last byte address | |
88 | ;; | |
89 | shr.u r23=in0,r20 // start / (stride size) | |
90 | shr.u r22=r22,r20 // (last byte address) / (stride size) | |
91 | shl r21=r21,r20 // r21: stride size of the i-cache(s) | |
92 | ;; | |
93 | sub r8=r22,r23 // number of strides - 1 | |
94 | shl r24=r23,r20 // r24: addresses for "fc" = | |
95 | // "start" rounded down to stride | |
96 | // boundary | |
97 | .save ar.lc,r3 | |
98 | mov r3=ar.lc // save ar.lc | |
99 | ;; | |
100 | ||
101 | .body | |
102 | mov ar.lc=r8 | |
103 | ;; | |
104 | /* | |
105 | * 32 byte aligned loop, even number of (actually 2) bundles | |
106 | */ | |
107 | .Loop_fc: | |
108 | fc r24 // issuable on M0 only | |
109 | add r24=r21,r24 // we flush "stride size" bytes per iteration | |
110 | nop.i 0 | |
111 | br.cloop.sptk.few .Loop_fc | |
112 | ;; | |
113 | sync.i | |
114 | ;; | |
115 | srlz.i | |
116 | ;; | |
117 | mov ar.lc=r3 // restore ar.lc | |
118 | br.ret.sptk.many rp | |
119 | END(clflush_cache_range) |