armv8/cache: Change cache invalidate and flush function
authorYork Sun <yorksun@freescale.com>
Wed, 26 Feb 2014 21:26:04 +0000 (13:26 -0800)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Mon, 7 Apr 2014 15:43:41 +0000 (17:43 +0200)
When SoC first boots up, we should invalidate the cache but not flush it.
We can use the same function for invalid and flush mostly, with a wrapper.

Invalidating large cache can ben slow on emulator, so we postpone doing
so until I-cache is enabled, and before enabling D-cache.

Signed-off-by: York Sun <yorksun@freescale.com>
CC: David Feng <fenghua@phytium.com.cn>
arch/arm/cpu/armv8/cache.S
arch/arm/cpu/armv8/cache_v8.c
arch/arm/cpu/armv8/start.S
arch/arm/include/asm/system.h

index 546a83e8f8bb3daeb96260f24c02b32b8f2e0705..249799cd01973facb26ff65f73050beea8458325 100644 (file)
  * clean and invalidate one level cache.
  *
  * x0: cache level
- * x1~x9: clobbered
+ * x1: 0 flush & invalidate, 1 invalidate only
+ * x2~x9: clobbered
  */
 ENTRY(__asm_flush_dcache_level)
-       lsl     x1, x0, #1
-       msr     csselr_el1, x1          /* select cache level */
+       lsl     x12, x0, #1
+       msr     csselr_el1, x12         /* select cache level */
        isb                             /* sync change of cssidr_el1 */
        mrs     x6, ccsidr_el1          /* read the new cssidr_el1 */
        and     x2, x6, #7              /* x2 <- log2(cache line size)-4 */
@@ -35,7 +36,7 @@ ENTRY(__asm_flush_dcache_level)
        clz     w5, w4                  /* bit position of #ways */
        mov     x4, #0x7fff
        and     x4, x4, x6, lsr #13     /* x4 <- max number of #sets */
-       /* x1 <- cache level << 1 */
+       /* x12 <- cache level << 1 */
        /* x2 <- line length offset */
        /* x3 <- number of cache ways - 1 */
        /* x4 <- number of cache sets - 1 */
@@ -45,11 +46,14 @@ loop_set:
        mov     x6, x3                  /* x6 <- working copy of #ways */
 loop_way:
        lsl     x7, x6, x5
-       orr     x9, x1, x7              /* map way and level to cisw value */
+       orr     x9, x12, x7             /* map way and level to cisw value */
        lsl     x7, x4, x2
        orr     x9, x9, x7              /* map set number to cisw value */
-       dc      cisw, x9                /* clean & invalidate by set/way */
-       subs    x6, x6, #1              /* decrement the way */
+       tbz     w1, #0, 1f
+       dc      isw, x9
+       b       2f
+1:     dc      cisw, x9                /* clean & invalidate by set/way */
+2:     subs    x6, x6, #1              /* decrement the way */
        b.ge    loop_way
        subs    x4, x4, #1              /* decrement the set */
        b.ge    loop_set
@@ -58,11 +62,14 @@ loop_way:
 ENDPROC(__asm_flush_dcache_level)
 
 /*
- * void __asm_flush_dcache_all(void)
+ * void __asm_flush_dcache_all(int invalidate_only)
+ *
+ * x0: 0 flush & invalidate, 1 invalidate only
  *
  * clean and invalidate all data cache by SET/WAY.
  */
-ENTRY(__asm_flush_dcache_all)
+ENTRY(__asm_dcache_all)
+       mov     x1, x0
        dsb     sy
        mrs     x10, clidr_el1          /* read clidr_el1 */
        lsr     x11, x10, #24
@@ -76,13 +83,13 @@ ENTRY(__asm_flush_dcache_all)
        /* x15 <- return address */
 
 loop_level:
-       lsl     x1, x0, #1
-       add     x1, x1, x0              /* x0 <- tripled cache level */
-       lsr     x1, x10, x1
-       and     x1, x1, #7              /* x1 <- cache type */
-       cmp     x1, #2
+       lsl     x12, x0, #1
+       add     x12, x12, x0            /* x0 <- tripled cache level */
+       lsr     x12, x10, x12
+       and     x12, x12, #7            /* x12 <- cache type */
+       cmp     x12, #2
        b.lt    skip                    /* skip if no cache or icache */
-       bl      __asm_flush_dcache_level
+       bl      __asm_flush_dcache_level        /* x1 = 0 flush, 1 invalidate */
 skip:
        add     x0, x0, #1              /* increment cache level */
        cmp     x11, x0
@@ -96,8 +103,24 @@ skip:
 
 finished:
        ret
+ENDPROC(__asm_dcache_all)
+
+ENTRY(__asm_flush_dcache_all)
+       mov     x16, lr
+       mov     x0, #0
+       bl      __asm_dcache_all
+       mov     lr, x16
+       ret
 ENDPROC(__asm_flush_dcache_all)
 
+ENTRY(__asm_invalidate_dcache_all)
+       mov     x16, lr
+       mov     x0, #0xffff
+       bl      __asm_dcache_all
+       mov     lr, x16
+       ret
+ENDPROC(__asm_invalidate_dcache_all)
+
 /*
  * void __asm_flush_dcache_range(start, end)
  *
index 7acae1b0aca55639f3271fa46f445816e2951b87..a96ecda7e3146996d20a2e46b975dced2769255c 100644 (file)
@@ -80,7 +80,7 @@ static void mmu_setup(void)
  */
 void invalidate_dcache_all(void)
 {
-       __asm_flush_dcache_all();
+       __asm_invalidate_dcache_all();
 }
 
 /*
@@ -177,6 +177,7 @@ int dcache_status(void)
 
 void icache_enable(void)
 {
+       __asm_invalidate_icache_all();
        set_sctlr(get_sctlr() | CR_I);
 }
 
index e70c51d43d86fef80d86781c6363e14ad92bf5f9..4f95289b5ebb9808f0b1f43a1669a91637afbcca 100644 (file)
@@ -64,10 +64,12 @@ reset:
        msr     cpacr_el1, x0                   /* Enable FP/SIMD */
 0:
 
-       /* Cache/BPB/TLB Invalidate */
-       bl      __asm_flush_dcache_all          /* dCache clean&invalidate */
-       bl      __asm_invalidate_icache_all     /* iCache invalidate */
-       bl      __asm_invalidate_tlb_all        /* invalidate TLBs */
+       /*
+        * Cache/BPB/TLB Invalidate
+        * i-cache is invalidated before enabled in icache_enable()
+        * tlb is invalidated before mmu is enabled in dcache_enable()
+        * d-cache is invalidated before enabled in dcache_enable()
+        */
 
        /* Processor specific initialization */
        bl      lowlevel_init
index 4178f8cf7e360edd17cb1715eefad9fe43743dd9..74ee9a4df9bc573fda7cc818fbb0f0eb9079a85d 100644 (file)
@@ -66,6 +66,7 @@ static inline void set_sctlr(unsigned int val)
 }
 
 void __asm_flush_dcache_all(void);
+void __asm_invalidate_dcache_all(void);
 void __asm_flush_dcache_range(u64 start, u64 end);
 void __asm_invalidate_tlb_all(void);
 void __asm_invalidate_icache_all(void);