^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Heavily based on proc-arm926.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Maintainer: Assaf Hoffman <hoffman@marvell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/assembler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/hwcap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/pgtable-hwdef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "proc-macros.S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * This is the maximum size of an area which will be invalidated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * using the single invalidate entry instructions. Anything larger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * than this, and we go for the whole cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * This value should be chosen such that we choose the cheapest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * alternative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CACHE_DLIMIT 16384
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * the cache line size of the I and D cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CACHE_DLINESIZE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .bss
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .align 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __cache_params_loc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .space 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __cache_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .word __cache_params_loc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * cpu_feroceon_proc_init()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ENTRY(cpu_feroceon_proc_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mrc p15, 0, r0, c0, c0, 1 @ read cache type register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ldr r1, __cache_params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mov r2, #(16 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) tst r0, #(1 << 16) @ get way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mov r0, r0, lsr #18 @ get cache size order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) movne r3, #((4 - 1) << 30) @ 4-way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) and r0, r0, #0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) moveq r3, #0 @ 1-way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) mov r2, r2, lsl r0 @ actual cache size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) movne r2, r2, lsr #2 @ turned into # of sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) sub r2, r2, #(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) stmia r1, {r2, r3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * cpu_feroceon_proc_fin()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ENTRY(cpu_feroceon_proc_fin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #if defined(CONFIG_CACHE_FEROCEON_L2) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mcr p15, 1, r0, c15, c9, 0 @ clean L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mrc p15, 0, r0, c1, c0, 0 @ ctrl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bic r0, r0, #0x1000 @ ...i............
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) bic r0, r0, #0x000e @ ............wca.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mcr p15, 0, r0, c1, c0, 0 @ disable caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * cpu_feroceon_reset(loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Perform a soft reset of the system. Put the CPU into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * same state as it would be if it had been reset, and branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * to what would be the reset vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * loc: location to jump to for soft reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .pushsection .idmap.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ENTRY(cpu_feroceon_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mov ip, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mcr p15, 0, ip, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mrc p15, 0, ip, c1, c0, 0 @ ctrl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bic ip, ip, #0x000f @ ............wcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bic ip, ip, #0x1100 @ ...i...s........
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) mcr p15, 0, ip, c1, c0, 0 @ ctrl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ret r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ENDPROC(cpu_feroceon_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .popsection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * cpu_feroceon_do_idle()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Called with IRQs disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ENTRY(cpu_feroceon_do_idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * flush_icache_all()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * Unconditionally clean and invalidate the entire icache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ENTRY(feroceon_flush_icache_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ENDPROC(feroceon_flush_icache_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * flush_user_cache_all()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Clean and invalidate all cache entries in a particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ENTRY(feroceon_flush_user_cache_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* FALLTHROUGH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * flush_kern_cache_all()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Clean and invalidate the entire cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ENTRY(feroceon_flush_kern_cache_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mov r2, #VM_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __flush_whole_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ldr r1, __cache_params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) ldmia r1, {r1, r3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 1: orr ip, r1, r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 2: mcr p15, 0, ip, c7, c14, 2 @ clean + invalidate D set/way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) subs ip, ip, #(1 << 30) @ next way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) bcs 2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) subs r1, r1, #(1 << 5) @ next set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) bcs 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) tst r2, #VM_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mov ip, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mcrne p15, 0, ip, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * flush_user_cache_range(start, end, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Clean and invalidate a range of cache entries in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * specified address range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * - start - start address (inclusive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * - end - end address (exclusive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * - flags - vm_flags describing address space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ENTRY(feroceon_flush_user_cache_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) sub r3, r1, r0 @ calculate total size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) cmp r3, #CACHE_DLIMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) bgt __flush_whole_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 1: tst r2, #VM_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) tst r2, #VM_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mov ip, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mcrne p15, 0, ip, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * coherent_kern_range(start, end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Ensure coherency between the Icache and the Dcache in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * region described by start, end. If you have non-snooping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Harvard caches, you need to implement this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * - start - virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * - end - virtual end address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ENTRY(feroceon_coherent_kern_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* FALLTHROUGH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * coherent_user_range(start, end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Ensure coherency between the Icache and the Dcache in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * region described by start, end. If you have non-snooping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * Harvard caches, you need to implement this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * - start - virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * - end - virtual end address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ENTRY(feroceon_coherent_user_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) bic r0, r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * flush_kern_dcache_area(void *addr, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Ensure no D cache aliasing occurs, either with itself or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * the I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * - addr - kernel address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * - size - region size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ENTRY(feroceon_flush_kern_dcache_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) add r1, r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ENTRY(feroceon_range_flush_kern_dcache_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mrs r2, cpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) orr r3, r2, #PSR_I_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) msr cpsr_c, r3 @ disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) msr cpsr_c, r2 @ restore interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * dma_inv_range(start, end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * Invalidate (discard) the specified virtual address range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * May not write back any entries. If 'start' or 'end'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * are not cache line aligned, those lines must be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * - start - virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * - end - virtual end address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * (same as v4wb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) feroceon_dma_inv_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) tst r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) bic r0, r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) tst r1, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) feroceon_range_dma_inv_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mrs r2, cpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) tst r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) tst r1, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) cmp r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) subne r1, r1, #1 @ top address is inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) orr r3, r2, #PSR_I_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) msr cpsr_c, r3 @ disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mcr p15, 5, r0, c15, c14, 0 @ D inv range start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) mcr p15, 5, r1, c15, c14, 1 @ D inv range top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) msr cpsr_c, r2 @ restore interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * dma_clean_range(start, end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Clean the specified virtual address range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * - start - virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * - end - virtual end address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * (same as v4wb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) feroceon_dma_clean_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) bic r0, r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) feroceon_range_dma_clean_range:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) mrs r2, cpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cmp r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) subne r1, r1, #1 @ top address is inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) orr r3, r2, #PSR_I_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) msr cpsr_c, r3 @ disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mcr p15, 5, r0, c15, c13, 0 @ D clean range start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) mcr p15, 5, r1, c15, c13, 1 @ D clean range top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) msr cpsr_c, r2 @ restore interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * dma_flush_range(start, end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Clean and invalidate the specified virtual address range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * - start - virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * - end - virtual end address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ENTRY(feroceon_dma_flush_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) bic r0, r0, #CACHE_DLINESIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) cmp r0, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) blo 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ENTRY(feroceon_range_dma_flush_range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mrs r2, cpsr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) cmp r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) subne r1, r1, #1 @ top address is inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) orr r3, r2, #PSR_I_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) msr cpsr_c, r3 @ disable interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) msr cpsr_c, r2 @ restore interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * dma_map_area(start, size, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * - start - kernel virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * - size - size of region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * - dir - DMA direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ENTRY(feroceon_dma_map_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) add r1, r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) cmp r2, #DMA_TO_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) beq feroceon_dma_clean_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) bcs feroceon_dma_inv_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) b feroceon_dma_flush_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ENDPROC(feroceon_dma_map_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * dma_map_area(start, size, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * - start - kernel virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * - size - size of region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * - dir - DMA direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) ENTRY(feroceon_range_dma_map_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) add r1, r1, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cmp r2, #DMA_TO_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) beq feroceon_range_dma_clean_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) bcs feroceon_range_dma_inv_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) b feroceon_range_dma_flush_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) ENDPROC(feroceon_range_dma_map_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * dma_unmap_area(start, size, dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * - start - kernel virtual start address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * - size - size of region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * - dir - DMA direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ENTRY(feroceon_dma_unmap_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ENDPROC(feroceon_dma_unmap_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .globl feroceon_flush_kern_cache_louis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .equ feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) define_cache_functions feroceon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .macro range_alias basename
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .globl feroceon_range_\basename
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .type feroceon_range_\basename , %function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) .equ feroceon_range_\basename , feroceon_\basename
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Most of the cache functions are unchanged for this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * Export suitable alias symbols for the unchanged functions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) range_alias flush_icache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) range_alias flush_user_cache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) range_alias flush_kern_cache_all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) range_alias flush_kern_cache_louis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) range_alias flush_user_cache_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) range_alias coherent_kern_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) range_alias coherent_user_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) range_alias dma_unmap_area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) define_cache_functions feroceon_range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ENTRY(cpu_feroceon_dcache_clean_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #if defined(CONFIG_CACHE_FEROCEON_L2) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) mov r2, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) mov r3, r1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) add r0, r0, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) subs r1, r1, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) bhi 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) #if defined(CONFIG_CACHE_FEROCEON_L2) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) add r2, r2, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) subs r3, r3, #CACHE_DLINESIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) bhi 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* =============================== PageTable ============================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * cpu_feroceon_switch_mm(pgd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Set the translation base pointer to be as described by pgd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * pgd: new page tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ENTRY(cpu_feroceon_switch_mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * Note: we wish to call __flush_whole_cache but we need to preserve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * lr to do so. The only way without touching main memory is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * use r2 which is normally used to test the VM_EXEC flag, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * compensate locally for the skipped ops if it is not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) mov r2, lr @ abuse r2 to preserve lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) bl __flush_whole_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) @ if r2 contains the VM_EXEC bit then the next 2 ops are done already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) tst r2, #VM_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mcreq p15, 0, ip, c7, c5, 0 @ invalidate I cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) mcreq p15, 0, ip, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * cpu_feroceon_set_pte_ext(ptep, pte, ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * Set a PTE and flush it out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .align 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ENTRY(cpu_feroceon_set_pte_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) armv3_set_pte_ext wc_disable=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) mov r0, r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mcr p15, 0, r0, c7, c10, 1 @ clean D entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #if defined(CONFIG_CACHE_FEROCEON_L2) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) mcr p15, 0, r0, c7, c10, 4 @ drain WB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Suspend/resume support: taken from arch/arm/mm/proc-arm926.S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) .globl cpu_feroceon_suspend_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .equ cpu_feroceon_suspend_size, 4 * 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #ifdef CONFIG_ARM_CPU_SUSPEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ENTRY(cpu_feroceon_do_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) stmfd sp!, {r4 - r6, lr}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mrc p15, 0, r4, c13, c0, 0 @ PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mrc p15, 0, r5, c3, c0, 0 @ Domain ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mrc p15, 0, r6, c1, c0, 0 @ Control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) stmia r0, {r4 - r6}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ldmfd sp!, {r4 - r6, pc}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ENDPROC(cpu_feroceon_do_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ENTRY(cpu_feroceon_do_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) mov ip, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ldmia r0, {r4 - r6}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) mcr p15, 0, r4, c13, c0, 0 @ PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) mcr p15, 0, r5, c3, c0, 0 @ Domain ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mcr p15, 0, r1, c2, c0, 0 @ TTB address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) mov r0, r6 @ control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) b cpu_resume_mmu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ENDPROC(cpu_feroceon_do_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .type __feroceon_setup, #function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) __feroceon_setup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) mov r0, #0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) adr r5, feroceon_crval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ldmia r5, {r5, r6}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) mrc p15, 0, r0, c1, c0 @ get control register v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) bic r0, r0, r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) orr r0, r0, r6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret lr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .size __feroceon_setup, . - __feroceon_setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * R P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * .RVI UFRS BLDP WCAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * .011 .001 ..11 0101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .type feroceon_crval, #object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) feroceon_crval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) crval clear=0x0000773f, mmuset=0x00003135, ucset=0x00001134
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) __INITDATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) define_processor_functions feroceon, dabort=v5t_early_abort, pabort=legacy_pabort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .section ".rodata"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) string cpu_arch_name, "armv5te"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) string cpu_elf_name, "v5"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) string cpu_feroceon_name, "Feroceon"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) string cpu_88fr531_name, "Feroceon 88FR531-vd"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) string cpu_88fr571_name, "Feroceon 88FR571-vd"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) string cpu_88fr131_name, "Feroceon 88FR131"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .align
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .section ".proc.info.init", "a"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) .type __\name\()_proc_info,#object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __\name\()_proc_info:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .long \cpu_val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .long \cpu_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .long PMD_TYPE_SECT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) PMD_SECT_BUFFERABLE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) PMD_SECT_CACHEABLE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) PMD_BIT4 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) PMD_SECT_AP_WRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) PMD_SECT_AP_READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .long PMD_TYPE_SECT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) PMD_BIT4 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) PMD_SECT_AP_WRITE | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) PMD_SECT_AP_READ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) initfn __feroceon_setup, __\name\()_proc_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .long cpu_arch_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .long cpu_elf_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .long \cpu_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .long feroceon_processor_functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .long v4wbi_tlb_fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .long feroceon_user_fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .long \cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .size __\name\()_proc_info, . - __\name\()_proc_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #ifdef CONFIG_CPU_FEROCEON_OLD_ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) feroceon_proc_info feroceon_old_id, 0x41009260, 0xff00fff0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) cpu_name=cpu_feroceon_name, cache=feroceon_cache_fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) feroceon_proc_info 88fr531, 0x56055310, 0xfffffff0, cpu_88fr531_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) cache=feroceon_cache_fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) feroceon_proc_info 88fr571, 0x56155710, 0xfffffff0, cpu_88fr571_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) cache=feroceon_range_cache_fns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) feroceon_proc_info 88fr131, 0x56251310, 0xfffffff0, cpu_88fr131_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) cache=feroceon_range_cache_fns