[aarch64-port-dev ] RFC: Use __clear_cache to do cache flushing
Edward Nevill
ed at camswl.com
Wed Apr 2 16:59:34 UTC 2014
Hi,
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?
Ed.
--- CUT HERE ---
exporting patch:
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1396457502 -3600
# Wed Apr 02 17:51:42 2014 +0100
# Node ID 080aebbebb5386e29298abfd5da240f7588ecbc0
# Parent 273f8f0e7109ba0abe8f3697f2f48e34afe0d2f3
Use gcc __clear_cache instead of doing it ourselves
diff -r 273f8f0e7109 -r 080aebbebb53 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 Wed Apr 02 17: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 080aebbebb53 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 Wed Apr 02 17: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
--- CUT HERE ---
More information about the aarch64-port-dev
mailing list