[aarch64-port-dev ] RFC: Use __clear_cache to do cache flushing
Edward Nevill
ed at camswl.com
Thu Apr 3 22:10:07 UTC 2014
Hi Andrew,
On Thu, 2014-04-03 at 10:57 +0100, Andrew Haley wrote:
> Hi,
>
> On 04/02/2014 05:59 PM, Edward Nevill wrote:
> > The current implementation of cache flushing/invalidation assumes that the line size is 64 bytes. This is not necessarily the case.
> >
> > To do this properly we would have to read CTR_EL0. Added to this is the complexity that the D cache and I cache may have different line sizes, so we must be careful to use the D cache line size when flushing the D cache and the I cache line size when invalidating the I cache.
> >
> > I think it would be much better all around if we just used the gcc intrinsic __clear_cache to do this as in the patch below.
> >
> > Comments?
>
> Hmm. I guess this is OK. I am uncomfortable that this leaves
> ICache::line_size incorrectly defined, but maybe that doesn't matter.
> I have written a patch that correctly initializes
> ICache::line_size. as an alternative for you to consider.
>
> If you decide to go with the GCC version, please:
Thanks for this. I think the GCC version offers a more generic solution to the problems with the existing code.
I do not believe that line_size is referenced anywhere outside the cache flushing code.
> Make sure you delete the enums for things that we know to be wrong
> like line_size and log2_line_size.
I have ensured that line_size, log2_line_size and stub_size do not appear in any aarch64 specific code.
I have deleted generate_icache_flush in macroAssembler_aarch64.{cpp,hpp} as it is no longer referenced and it references ICache::line_size which might cause confusion.
> Fix your indentation in icache_aarch64.hpp.
Fixed.
New patch below,
All the best,
Ed.
--- CUT HERE ---
exporting patch:
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1396561902 -3600
# Thu Apr 03 22:51:42 2014 +0100
# Node ID 5a8c184c37d4fc7d6c91b9c79401bd7d8242f4e8
# Parent 273f8f0e7109ba0abe8f3697f2f48e34afe0d2f3
Use gcc __clear_cache instead of doing it ourselves
diff -r 273f8f0e7109 -r 5a8c184c37d4 src/cpu/aarch64/vm/icache_aarch64.cpp
--- a/src/cpu/aarch64/vm/icache_aarch64.cpp Wed Apr 02 11:41:48 2014 +0100
+++ b/src/cpu/aarch64/vm/icache_aarch64.cpp Thu Apr 03 22:51:42 2014 +0100
@@ -29,41 +29,10 @@
#include "runtime/icache.hpp"
extern void aarch64TestHook();
-extern "C" void setup_arm_sim();
-#define __ _masm->
-
-void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {
-
+void ICacheStubGenerator::generate_icache_flush(
+ ICache::flush_icache_stub_t* flush_icache_stub) {
aarch64TestHook();
-
- StubCodeMark mark(this, "ICache", "flush_icache_stub");
-
- address entry = __ pc();
-
- // generate a c stub prolog which will bootstrap into the ARM code
- // which follows, loading the 3 general registers passed by the
- // caller into the first 3 ARM registers
-
-#ifdef BUILTIN_SIM
- __ c_stub_prolog(3, 0, MacroAssembler::ret_type_integral);
-#endif
-
- Register start = r0, lines = r1, auto_magic = r2;
-
- // First flush the dcache
- __ generate_flush_loop(&Assembler::dc, start, lines);
-
- __ dsb(Assembler::SY);
-
- // And then the icache
- __ generate_flush_loop(&Assembler::ic, start, lines);
-
- // the stub is supposed to return the 3rd argument
- __ mov(r0, auto_magic);
- __ ret(r30);
-
- *flush_icache_stub = (ICache::flush_icache_stub_t)entry;
+ // Give anyone who calls this a surprise
+ *flush_icache_stub = (ICache::flush_icache_stub_t)NULL;
}
-
-#undef __
diff -r 273f8f0e7109 -r 5a8c184c37d4 src/cpu/aarch64/vm/icache_aarch64.hpp
--- a/src/cpu/aarch64/vm/icache_aarch64.hpp Wed Apr 02 11:41:48 2014 +0100
+++ b/src/cpu/aarch64/vm/icache_aarch64.hpp Thu Apr 03 22:51:42 2014 +0100
@@ -27,16 +27,19 @@
#ifndef CPU_AARCH64_VM_ICACHE_AARCH64_HPP
#define CPU_AARCH64_VM_ICACHE_AARCH64_HPP
-// Interface for updating the instruction cache. Whenever the VM modifies
-// code, part of the processor instruction cache potentially has to be flushed.
+// Interface for updating the instruction cache. Whenever the VM
+// modifies code, part of the processor instruction cache potentially
+// has to be flushed.
class ICache : public AbstractICache {
public:
- enum {
- stub_size = 128, // Size of the icache flush stub in bytes
- line_size = 64, // Icache line size in bytes
- log2_line_size = 6 // log2(line_size)
- };
+ static void initialize() {}
+ static void invalidate_word(address addr) {
+ __clear_cache((char *)addr, (char *)(addr + 3));
+ }
+ static void invalidate_range(address start, int nbytes) {
+ __clear_cache((char *)start, (char *)(start + nbytes));
+ }
};
#endif // CPU_AARCH64_VM_ICACHE_AARCH64_HPP
diff -r 273f8f0e7109 -r 5a8c184c37d4 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Wed Apr 02 11:41:48 2014 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp Thu Apr 03 22:51:42 2014 +0100
@@ -2889,23 +2889,6 @@
}
}
-void MacroAssembler::generate_flush_loop(flush_insn flush, Register start, Register lines) {
- Label again, exit;
-
- assert_different_registers(start, lines, rscratch1, rscratch2);
-
- cmp(lines, zr);
- br(Assembler::LE, exit);
- mov(rscratch1, start);
- mov(rscratch2, lines);
- bind(again);
- (this->*flush)(rscratch1);
- sub(rscratch2, rscratch2, 1);
- add(rscratch1, rscratch1, ICache::line_size);
- cbnz(rscratch2, again);
- bind(exit);
-}
-
bool MacroAssembler::use_acq_rel_for_volatile_fields() {
#ifdef PRODUCT
return false;
diff -r 273f8f0e7109 -r 5a8c184c37d4 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Wed Apr 02 11:41:48 2014 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp Thu Apr 03 22:51:42 2014 +0100
@@ -1361,9 +1361,6 @@
address read_polling_page(Register r, address page, relocInfo::relocType rtype);
address read_polling_page(Register r, relocInfo::relocType rtype);
- typedef void (Assembler::* flush_insn)(Register Rt);
- void generate_flush_loop(flush_insn flush, Register start, Register lines);
-
// Used by aarch64.ad to control code generation
static bool use_acq_rel_for_volatile_fields();
};
--- CUT HERE ---
More information about the aarch64-port-dev
mailing list