diff options
author | Zoltan Menyhart <Zoltan.Menyhart@bull.net> | 2005-06-03 08:36:00 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-07-12 18:33:18 -0400 |
commit | 08357f82d4decc48bbfd39ae30d5fe0754f7f576 (patch) | |
tree | c8516a8f208e1cb253bd33f41857b0699104b130 /arch/ia64/lib | |
parent | 60a762b6a6dec17cc4339b60154902fd04c2f9f2 (diff) |
[IA64] improve flush_icache_range()
Check with PAL to see what the i-cache line size is for
each level of the cache, and so use the correct stride
when flushing the cache.
Acked-by: David Mosberger
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/lib')
-rw-r--r-- | arch/ia64/lib/flush.S | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S index a1af9146cfdb..3e2cfa2c6d39 100644 --- a/arch/ia64/lib/flush.S +++ b/arch/ia64/lib/flush.S | |||
@@ -3,37 +3,59 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co | 4 | * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co |
5 | * David Mosberger-Tang <davidm@hpl.hp.com> | 5 | * David Mosberger-Tang <davidm@hpl.hp.com> |
6 | * | ||
7 | * 05/28/05 Zoltan Menyhart Dynamic stride size | ||
6 | */ | 8 | */ |
9 | |||
7 | #include <asm/asmmacro.h> | 10 | #include <asm/asmmacro.h> |
8 | #include <asm/page.h> | 11 | |
9 | 12 | ||
10 | /* | 13 | /* |
11 | * flush_icache_range(start,end) | 14 | * flush_icache_range(start,end) |
12 | * Must flush range from start to end-1 but nothing else (need to | 15 | * |
16 | * Make i-cache(s) coherent with d-caches. | ||
17 | * | ||
18 | * Must deal with range from start to end-1 but nothing else (need to | ||
13 | * be careful not to touch addresses that may be unmapped). | 19 | * be careful not to touch addresses that may be unmapped). |
20 | * | ||
21 | * Note: "in0" and "in1" are preserved for debugging purposes. | ||
14 | */ | 22 | */ |
15 | GLOBAL_ENTRY(flush_icache_range) | 23 | GLOBAL_ENTRY(flush_icache_range) |
24 | |||
16 | .prologue | 25 | .prologue |
17 | alloc r2=ar.pfs,2,0,0,0 | 26 | alloc r2=ar.pfs,2,0,0,0 |
18 | sub r8=in1,in0,1 | 27 | movl r3=ia64_i_cache_stride_shift |
28 | mov r21=1 | ||
29 | ;; | ||
30 | ld8 r20=[r3] // r20: stride shift | ||
31 | sub r22=in1,r0,1 // last byte address | ||
19 | ;; | 32 | ;; |
20 | shr.u r8=r8,5 // we flush 32 bytes per iteration | 33 | shr.u r23=in0,r20 // start / (stride size) |
21 | .save ar.lc, r3 | 34 | shr.u r22=r22,r20 // (last byte address) / (stride size) |
22 | mov r3=ar.lc // save ar.lc | 35 | shl r21=r21,r20 // r21: stride size of the i-cache(s) |
36 | ;; | ||
37 | sub r8=r22,r23 // number of strides - 1 | ||
38 | shl r24=r23,r20 // r24: addresses for "fc.i" = | ||
39 | // "start" rounded down to stride boundary | ||
40 | .save ar.lc,r3 | ||
41 | mov r3=ar.lc // save ar.lc | ||
23 | ;; | 42 | ;; |
24 | 43 | ||
25 | .body | 44 | .body |
26 | 45 | mov ar.lc=r8 | |
27 | mov ar.lc=r8 | ||
28 | ;; | 46 | ;; |
29 | .Loop: fc.i in0 // issuable on M2 only | 47 | /* |
30 | add in0=32,in0 | 48 | * 32 byte aligned loop, even number of (actually 2) bundles |
49 | */ | ||
50 | .Loop: fc.i r24 // issuable on M0 only | ||
51 | add r24=r21,r24 // we flush "stride size" bytes per iteration | ||
52 | nop.i 0 | ||
31 | br.cloop.sptk.few .Loop | 53 | br.cloop.sptk.few .Loop |
32 | ;; | 54 | ;; |
33 | sync.i | 55 | sync.i |
34 | ;; | 56 | ;; |
35 | srlz.i | 57 | srlz.i |
36 | ;; | 58 | ;; |
37 | mov ar.lc=r3 // restore ar.lc | 59 | mov ar.lc=r3 // restore ar.lc |
38 | br.ret.sptk.many rp | 60 | br.ret.sptk.many rp |
39 | END(flush_icache_range) | 61 | END(flush_icache_range) |