Invalidating the D-cache after disabling it turned out to be a bad idea
authorkettenis <kettenis@openbsd.org>
Sun, 10 Mar 2024 15:37:54 +0000 (15:37 +0000)
committerkettenis <kettenis@openbsd.org>
Sun, 10 Mar 2024 15:37:54 +0000 (15:37 +0000)
and broke Allwinner SoCs with Cortex-A7 cores.  So skip that and also
invalidate the I-cache before disabling it.  This seems to work better
on a wide range of boards.

ok deraadt@, jmatthew@

sys/arch/armv7/stand/efiboot/conf.c
sys/arch/armv7/stand/efiboot/exec.c

index e7ffa3d..de536fb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.34 2024/03/03 17:00:14 kettenis Exp $      */
+/*     $OpenBSD: conf.c,v 1.35 2024/03/10 15:37:54 kettenis Exp $      */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff
@@ -42,7 +42,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "1.21";
+const char version[] = "1.22";
 int    debug = 0;
 
 struct fs_ops file_system[] = {
index 29cee33..e3e4c4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: exec.c,v 1.17 2024/03/03 17:00:14 kettenis Exp $      */
+/*     $OpenBSD: exec.c,v 1.18 2024/03/10 15:37:54 kettenis Exp $      */
 
 /*
  * Copyright (c) 2006, 2016 Mark Kettenis
@@ -86,47 +86,6 @@ dcache_wbinv_all(void)
        __asm volatile("dsb");
 }
 
-void
-dcache_inv_all(void)
-{
-       uint32_t clidr;
-       uint32_t ccsidr;
-       uint32_t val;
-       int nways, nsets;
-       int wshift, sshift;
-       int way, set;
-       int level;
-       
-       __asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r"(clidr));
-       for (level = 0; level < CLIDR_LOC(clidr); level++) {
-               if (CLIDR_CTYPE(clidr, level) == CLIDR_CTYPE_NOCACHE)
-                       break;
-               if (CLIDR_CTYPE(clidr, level) == CLIDR_CTYPE_ICACHE)
-                       continue;
-
-               __asm volatile("mcr p15, 2, %0, c0, c0, 0" :: "r"(level << 1));
-               __asm volatile("isb");
-               __asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r"(ccsidr));
-
-               nways = CCSIDR_ASSOCIATIVITY(ccsidr) + 1;
-               nsets = CCSIDR_NUMSETS(ccsidr) + 1;
-
-               sshift = CCSIDR_LINESZ(ccsidr) + 4;
-               wshift = __builtin_clz(CCSIDR_ASSOCIATIVITY(ccsidr));
-
-               for (way = 0; way < nways; way++) {
-                       for (set = 0; set < nsets; set++) {
-                               val = (way << wshift) | (set << sshift) |
-                                   (level << 1);
-                               __asm volatile("mcr p15, 0, %0, c7, c6, 2"
-                                   :: "r"(val));
-                       }
-               }
-       }
-
-       __asm volatile("dsb");
-}
-
 void
 icache_inv_all(void)
 {
@@ -225,9 +184,8 @@ run_loadfile(uint64_t *marks, int howto)
 
        dcache_wbinv_all();
        dcache_disable();
-       dcache_inv_all();
-       icache_disable();
        icache_inv_all();
+       icache_disable();
        mmu_disable();
 
        (*(startfuncp)(marks[MARK_ENTRY]))((void *)esym, NULL, fdt);