]> cvs.zerfleddert.de Git - ms2-kexec/blobdiff - cache-v7.S
update kexec to 2.6.39 version, still doesn't work...
[ms2-kexec] / cache-v7.S
index bd38e6164c64807c185983413f97b0a49376a45d..ae604c90845dd5692040b6e65d53b967be25617a 100644 (file)
@@ -3,7 +3,6 @@
  *
  *  Copyright (C) 2001 Deep Blue Solutions Ltd.
  *  Copyright (C) 2005 ARM Ltd.
- * This Edition is maintained by Matthew Veety (aliasxerog) <mveety@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
-#include <asm/assembler.h>
+#include "assembler.h"
+#include <asm/unwind.h>
 
 #include "proc-macros.S"
 
+/*
+ *     v7_flush_icache_all()
+ *
+ *     Flush the whole I-cache.
+ *
+ *     Registers:
+ *     r0 - set to 0
+ */
+ENTRY(v7_flush_icache_all)
+       mov     r0, #0
+       ALT_SMP(mcr     p15, 0, r0, c7, c1, 0)          @ invalidate I-cache inner shareable
+       ALT_UP(mcr      p15, 0, r0, c7, c5, 0)          @ I+BTB cache invalidate
+       mov     pc, lr
+ENDPROC(v7_flush_icache_all)
+
 /*
  *     v7_flush_dcache_all()
  *
  *     Flush the whole D-cache.
  *
- *     Corrupted registers: r0-r5, r7, r9-r11
+ *     Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
  *
  *     - mm    - mm_struct describing address space
  */
@@ -52,8 +67,12 @@ loop1:
 loop2:
        mov     r9, r4                          @ create working copy of max way size
 loop3:
-       orr     r11, r10, r9, lsl r5            @ factor way and cache number into r11
-       orr     r11, r11, r7, lsl r2            @ factor index number into r11
+ ARM(  orr     r11, r10, r9, lsl r5    )       @ factor way and cache number into r11
+ THUMB(        lsl     r6, r9, r5              )
+ THUMB(        orr     r11, r10, r6            )       @ factor way and cache number into r11
+ ARM(  orr     r11, r11, r7, lsl r2    )       @ factor index number into r11
+ THUMB(        lsl     r6, r7, r2              )
+ THUMB(        orr     r11, r11, r6            )       @ factor index number into r11
        mcr     p15, 0, r11, c7, c14, 2         @ clean & invalidate by set/way
        subs    r9, r9, #1                      @ decrement the way
        bge     loop3
@@ -77,17 +96,20 @@ ENDPROC(v7_flush_dcache_all)
  *     Flush the entire cache system.
  *  The data cache flush is now achieved using atomic clean / invalidates
  *  working outwards from L1 cache. This is done using Set/Way based cache
- *  maintainance instructions.
+ *  maintenance instructions.
  *  The instruction cache can still be invalidated back to the point of
  *  unification in a single instruction.
  *
  */
 ENTRY(v7_flush_kern_cache_all)
-       stmfd   sp!, {r4-r5, r7, r9-r11, lr}
+ ARM(  stmfd   sp!, {r4-r5, r7, r9-r11, lr}    )
+ THUMB(        stmfd   sp!, {r4-r7, r9-r11, lr}        )
        bl      v7_flush_dcache_all
        mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 0           @ I+BTB cache invalidate
-       ldmfd   sp!, {r4-r5, r7, r9-r11, lr}
+       ALT_SMP(mcr     p15, 0, r0, c7, c1, 0)  @ invalidate I-cache inner shareable
+       ALT_UP(mcr      p15, 0, r0, c7, c5, 0)  @ I+BTB cache invalidate
+ ARM(  ldmfd   sp!, {r4-r5, r7, r9-r11, lr}    )
+ THUMB(        ldmfd   sp!, {r4-r7, r9-r11, lr}        )
        mov     pc, lr
 ENDPROC(v7_flush_kern_cache_all)
 
@@ -148,34 +170,57 @@ ENTRY(v7_coherent_kern_range)
  *     - the Icache does not read data from the write buffer
  */
 ENTRY(v7_coherent_user_range)
+ UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
-       bic     r0, r0, r3
-1:     mcr     p15, 0, r0, c7, c11, 1          @ clean D line to the point of unification
-       dsb
-       mcr     p15, 0, r0, c7, c5, 1           @ invalidate I line
-       add     r0, r0, r2
-       cmp     r0, r1
+       bic     r12, r0, r3
+1:
+ USER( mcr     p15, 0, r12, c7, c11, 1 )       @ clean D line to the point of unification
+       add     r12, r12, r2
+       cmp     r12, r1
        blo     1b
+       dsb
+       icache_line_size r2, r3
+       sub     r3, r2, #1
+       bic     r12, r0, r3
+2:
+ USER( mcr     p15, 0, r12, c7, c5, 1  )       @ invalidate I line
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     2b
+3:
        mov     r0, #0
-       mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
+       ALT_SMP(mcr     p15, 0, r0, c7, c1, 6)  @ invalidate BTB Inner Shareable
+       ALT_UP(mcr      p15, 0, r0, c7, c5, 6)  @ invalidate BTB
        dsb
        isb
        mov     pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+       mov     r12, r12, lsr #12
+       mov     r12, r12, lsl #12
+       add     r12, r12, #4096
+       b       3b
+ UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
 
 /*
- *     v7_flush_kern_dcache_page(kaddr)
+ *     v7_flush_kern_dcache_area(void *addr, size_t size)
  *
  *     Ensure that the data held in the page kaddr is written back
  *     to the page in question.
  *
- *     - kaddr   - kernel address (guaranteed to be page aligned)
+ *     - addr  - kernel address
+ *     - size  - region size
  */
-ENTRY(v7_flush_kern_dcache_page)
+ENTRY(v7_flush_kern_dcache_area)
        dcache_line_size r2, r3
-       add     r1, r0, #PAGE_SZ
+       add     r1, r0, r1
 1:
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line / unified line
        add     r0, r0, r2
@@ -183,7 +228,7 @@ ENTRY(v7_flush_kern_dcache_page)
        blo     1b
        dsb
        mov     pc, lr
-ENDPROC(v7_flush_kern_dcache_page)
+ENDPROC(v7_flush_kern_dcache_area)
 
 /*
  *     v7_dma_inv_range(start,end)
@@ -195,7 +240,7 @@ ENDPROC(v7_flush_kern_dcache_page)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v7_dma_inv_range)
+v7_dma_inv_range:
        dcache_line_size r2, r3
        sub     r3, r2, #1
        tst     r0, r3
@@ -219,7 +264,7 @@ ENDPROC(v7_dma_inv_range)
  *     - start   - virtual start address of region
  *     - end     - virtual end address of region
  */
-ENTRY(v7_dma_clean_range)
+v7_dma_clean_range:
        dcache_line_size r2, r3
        sub     r3, r2, #1
        bic     r0, r0, r3
@@ -254,13 +299,12 @@ ENDPROC(v7_dma_flush_range)
 
        .type   v7_cache_fns, #object
 ENTRY(v7_cache_fns)
+       .long   v7_flush_icache_all
        .long   v7_flush_kern_cache_all
        .long   v7_flush_user_cache_all
        .long   v7_flush_user_cache_range
        .long   v7_coherent_kern_range
        .long   v7_coherent_user_range
-       .long   v7_flush_kern_dcache_page
-       .long   v7_dma_inv_range
-       .long   v7_dma_clean_range
+       .long   v7_flush_kern_dcache_area
        .long   v7_dma_flush_range
        .size   v7_cache_fns, . - v7_cache_fns
Impressum, Datenschutz