Teach cmpintmd to flush the instruction cache on aarch64.
authorTaylor R Campbell <campbell@mumble.net>
Mon, 21 Jan 2019 20:59:02 +0000 (20:59 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Wed, 21 Aug 2019 21:34:04 +0000 (21:34 +0000)
src/microcode/cmpintmd/aarch64.c
src/microcode/cmpintmd/aarch64.h

index f012434c1d7f634d6e8a0c53fea7580217634a25..454a3f0394dad1565053081dbf9883831627b27f 100644 (file)
@@ -346,3 +346,50 @@ aarch64_reset_hook (void)
 {
   /* XXX Make sure we're mapped write and execute.  (Such is the state...)  */
 }
+
+static inline void
+aarch64_cache_line_sizes (unsigned *dsize, unsigned *isize)
+{
+  uint64_t ctr_el0;
+
+  asm volatile ("\n\
+    mrs %0, ctr_el0\n\
+    ubfx %1, %0, #16, #4\n\
+    ubfx %2, %0, #0, #4\n\
+  " : "=r"(ctr_el0), "=r"(*dsize), "=r"(*isize));
+}
+
+void
+aarch64_flush_i_cache_region (SCHEME_OBJECT * start, size_t nwords)
+{
+  unsigned dsize, isize;
+  size_t nbytes = (nwords * (sizeof (SCHEME_OBJECT)));
+  char * p;
+  size_t n;
+
+  /* Get the cache line sizes.  */
+  aarch64_cache_line_sizes ((&dsize), (&isize));
+
+  /* Flush the data cache lines.  */
+  n = ((nbytes + (dsize - 1)) / dsize);
+  for (p = ((char *) start); n --> 0; p += dsize)
+    asm volatile ("dc cvau, %0" : : "r"(p));
+
+  /* All data writes must complete before any following data reads.  */
+  asm volatile ("dsb ish");
+
+  /* Flush the instruction cache lines.  */
+  n = ((nbytes + (isize - 1)) / isize);
+  for (p = ((char *) start); n --> 0; p += isize)
+    asm volatile ("ic ivau, %0" : : "r"(p));
+
+  /* All cache flushes happen before any following instruction fetches.  */
+  asm volatile ("isb");
+}
+
+void
+aarch64_flush_i_cache (void)
+{
+  /* Can't do `ic iallu' because that's privileged.  */
+  aarch64_flush_i_cache_region (constant_start, Free - constant_start);
+}
index 2e9c232af9db1601fe4d01068a7f9c2f5001be9f..3f7d485dbf7e9ead97e822c70d598babb7a2ae78 100644 (file)
@@ -242,4 +242,13 @@ insn_t * read_uuo_target (SCHEME_OBJECT *);
 /* C stack is completely separate.  */
 #define within_c_stack(fn, cookie) (fn)(cookie)
 
+#define FLUSH_I_CACHE_REGION(ptr, nwords)      \
+  aarch64_flush_i_cache_region ((ptr), (nwords))
+
+#define FLUSH_I_CACHE()                                \
+  aarch64_flush_i_cache ()
+
+void aarch64_flush_i_cache_region (SCHEME_OBJECT *, size_t);
+void aarch64_flush_i_cache (void);
+
 #endif /* SCM_CMPINTMD_H_INCLUDED */