26 #include "precompiled.hpp" |
26 #include "precompiled.hpp" |
27 #include "assembler_ppc.inline.hpp" |
27 #include "assembler_ppc.inline.hpp" |
28 #include "runtime/icache.hpp" |
28 #include "runtime/icache.hpp" |
29 |
29 |
30 // Use inline assembler to implement icache flush. |
30 // Use inline assembler to implement icache flush. |
31 int ppc64_flush_icache(address start, int lines, int magic){ |
31 int ICache::ppc64_flush_icache(address start, int lines, int magic) { |
32 address end = start + (unsigned int)lines*ICache::line_size; |
32 address end = start + (unsigned int)lines*ICache::line_size; |
33 assert(start <= end, "flush_icache parms"); |
33 assert(start <= end, "flush_icache parms"); |
34 |
34 |
35 // store modified cache lines from data cache |
35 // store modified cache lines from data cache |
36 for (address a=start; a<end; a+=ICache::line_size) { |
36 for (address a = start; a < end; a += ICache::line_size) { |
37 __asm__ __volatile__( |
37 __asm__ __volatile__( |
38 "dcbst 0, %0 \n" |
38 "dcbst 0, %0 \n" |
39 : |
39 : |
40 : "r" (a) |
40 : "r" (a) |
41 : "memory"); |
41 : "memory"); |
42 } |
42 } |
43 |
43 |
44 // sync instruction |
44 // sync instruction |
45 __asm__ __volatile__( |
45 __asm__ __volatile__( |
46 "sync \n" |
46 "sync \n" |
47 : |
47 : |
48 : |
48 : |
49 : "memory"); |
49 : "memory"); |
50 |
50 |
51 // invalidate respective cache lines in instruction cache |
51 // invalidate respective cache lines in instruction cache |
52 for (address a=start; a<end; a+=ICache::line_size) { |
52 for (address a = start; a < end; a += ICache::line_size) { |
53 __asm__ __volatile__( |
53 __asm__ __volatile__( |
54 "icbi 0, %0 \n" |
54 "icbi 0, %0 \n" |
55 : |
55 : |
56 : "r" (a) |
56 : "r" (a) |
57 : "memory"); |
57 : "memory"); |
58 } |
58 } |
59 |
59 |
60 // discard fetched instructions |
60 // discard fetched instructions |
61 __asm__ __volatile__( |
61 __asm__ __volatile__( |
62 "isync \n" |
62 "isync \n" |
63 : |
63 : |
64 : |
64 : |
65 : "memory"); |
65 : "memory"); |
66 |
66 |
67 return magic; |
67 return magic; |
68 } |
68 } |
69 |
69 |
70 void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) { |
70 void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) { |
71 StubCodeMark mark(this, "ICache", "flush_icache_stub"); |
71 StubCodeMark mark(this, "ICache", "flush_icache_stub"); |
72 |
72 |
73 *flush_icache_stub = (ICache::flush_icache_stub_t)ppc64_flush_icache; |
73 *flush_icache_stub = (ICache::flush_icache_stub_t)ICache::ppc64_flush_icache; |
74 |
74 |
75 // First call to flush itself |
75 // First call to flush itself |
76 ICache::invalidate_range((address)(*flush_icache_stub), 0); |
76 ICache::invalidate_range((address)(*flush_icache_stub), 0); |
77 } |
77 } |