1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * linux/arch/arm/mm/arm940.S: utility functi 4 * 5 * Copyright (C) 2004-2006 Hyok S. Choi (hyok 6 */ 7 #include <linux/linkage.h> 8 #include <linux/init.h> 9 #include <linux/cfi_types.h> 10 #include <linux/pgtable.h> 11 #include <asm/assembler.h> 12 #include <asm/hwcap.h> 13 #include <asm/pgtable-hwdef.h> 14 #include <asm/ptrace.h> 15 #include "proc-macros.S" 16 17 /* ARM940T has a 4KB DCache comprising 256 lin 18 #define CACHE_DLINESIZE 16 19 #define CACHE_DSEGMENTS 4 20 #define CACHE_DENTRIES 64 21 22 .text 23 /* 24 * cpu_arm940_proc_init() 25 * cpu_arm940_switch_mm() 26 * 27 * These are not required. 28 */ 29 SYM_TYPED_FUNC_START(cpu_arm940_proc_init) 30 ret lr 31 SYM_FUNC_END(cpu_arm940_proc_init) 32 33 SYM_TYPED_FUNC_START(cpu_arm940_switch_mm) 34 ret lr 35 SYM_FUNC_END(cpu_arm940_switch_mm) 36 37 /* 38 * cpu_arm940_proc_fin() 39 */ 40 SYM_TYPED_FUNC_START(cpu_arm940_proc_fin) 41 mrc p15, 0, r0, c1, c0, 0 42 bic r0, r0, #0x00001000 43 bic r0, r0, #0x00000004 44 mcr p15, 0, r0, c1, c0, 0 45 ret lr 46 SYM_FUNC_END(cpu_arm940_proc_fin) 47 48 /* 49 * cpu_arm940_reset(loc) 50 * Params : r0 = address to jump to 51 * Notes : This sets up everything for a res 52 */ 53 .pushsection .idmap.text, "ax" 54 SYM_TYPED_FUNC_START(cpu_arm940_reset) 55 mov ip, #0 56 mcr p15, 0, ip, c7, c5, 0 57 mcr p15, 0, ip, c7, c6, 0 58 mcr p15, 0, ip, c7, c10, 4 59 mrc p15, 0, ip, c1, c0, 0 60 bic ip, ip, #0x00000005 61 bic ip, ip, #0x00001000 62 mcr p15, 0, ip, c1, c0, 0 63 ret r0 64 SYM_FUNC_END(cpu_arm940_reset) 65 .popsection 66 67 /* 68 * cpu_arm940_do_idle() 69 */ 70 .align 5 71 SYM_TYPED_FUNC_START(cpu_arm940_do_idle) 72 mcr p15, 0, r0, c7, c0, 4 73 ret lr 74 SYM_FUNC_END(cpu_arm940_do_idle) 75 76 /* 77 * flush_icache_all() 78 * 79 * Unconditionally clean and invalidate t 80 */ 81 SYM_TYPED_FUNC_START(arm940_flush_icache_all) 82 mov r0, #0 83 mcr p15, 0, r0, c7, c5, 0 84 ret lr 85 SYM_FUNC_END(arm940_flush_icache_all) 86 87 /* 88 * flush_user_cache_all() 89 */ 90 SYM_FUNC_ALIAS(arm940_flush_user_cache_all, ar 91 92 /* 93 * flush_kern_cache_all() 94 * 95 * Clean and invalidate the entire cache. 96 */ 97 SYM_TYPED_FUNC_START(arm940_flush_kern_cache_a 98 mov r2, #VM_EXEC 99 b arm940_flush_user_cache_range 100 SYM_FUNC_END(arm940_flush_kern_cache_all) 101 102 /* 103 * flush_user_cache_range(start, end, fla 104 * 105 * There is no efficient way to flush a r 106 * in the specified address range. Thus, 107 * 108 * - start - start address (inclusive) 109 * - end - end address (exclusive) 110 * - flags - vm_flags describing address 111 */ 112 SYM_TYPED_FUNC_START(arm940_flush_user_cache_r 113 mov ip, #0 114 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 115 mcr p15, 0, ip, c7, c6, 0 116 #else 117 mov r1, #(CACHE_DSEGMENTS - 1) << 118 1: orr r3, r1, #(CACHE_DENTRIES - 1) 119 2: mcr p15, 0, r3, c7, c14, 2 120 subs r3, r3, #1 << 26 121 bcs 2b 122 subs r1, r1, #1 << 4 123 bcs 1b 124 #endif 125 tst r2, #VM_EXEC 126 mcrne p15, 0, ip, c7, c5, 0 127 mcrne p15, 0, ip, c7, c10, 4 128 ret lr 129 SYM_FUNC_END(arm940_flush_user_cache_range) 130 131 /* 132 * coherent_kern_range(start, end) 133 * 134 * Ensure coherency between the Icache an 135 * region described by start, end. If yo 136 * Harvard caches, you need to implement 137 * 138 * - start - virtual start address 139 * - end - virtual end address 140 */ 141 SYM_TYPED_FUNC_START(arm940_coherent_kern_rang 142 b arm940_flush_kern_dcache_area 143 SYM_FUNC_END(arm940_coherent_kern_range) 144 145 /* 146 * coherent_user_range(start, end) 147 * 148 * Ensure coherency between the Icache an 149 * region described by start, end. If yo 150 * Harvard caches, you need to implement 151 * 152 * - start - virtual start address 153 * - end - virtual end address 154 */ 155 SYM_TYPED_FUNC_START(arm940_coherent_user_rang 156 #ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI 157 b arm940_flush_kern_dcache_area 158 #endif 159 SYM_FUNC_END(arm940_coherent_user_range) 160 161 /* 162 * flush_kern_dcache_area(void *addr, siz 163 * 164 * Ensure no D cache aliasing occurs, eit 165 * the I cache 166 * 167 * - addr - kernel address 168 * - size - region size 169 */ 170 SYM_TYPED_FUNC_START(arm940_flush_kern_dcache_ 171 mov r0, #0 172 mov r1, #(CACHE_DSEGMENTS - 1) << 173 1: orr r3, r1, #(CACHE_DENTRIES - 1) 174 2: mcr p15, 0, r3, c7, c14, 2 175 subs r3, r3, #1 << 26 176 bcs 2b 177 subs r1, r1, #1 << 4 178 bcs 1b 179 mcr p15, 0, r0, c7, c5, 0 180 mcr p15, 0, r0, c7, c10, 4 181 ret lr 182 SYM_FUNC_END(arm940_flush_kern_dcache_area) 183 184 /* 185 * dma_inv_range(start, end) 186 * 187 * There is no efficient way to invalidat 188 * address range. Thus, invalidates all. 189 * 190 * - start - virtual start address 191 * - end - virtual end address 192 */ 193 arm940_dma_inv_range: 194 mov ip, #0 195 mov r1, #(CACHE_DSEGMENTS - 1) << 196 1: orr r3, r1, #(CACHE_DENTRIES - 1) 197 2: mcr p15, 0, r3, c7, c6, 2 198 subs r3, r3, #1 << 26 199 bcs 2b 200 subs r1, r1, #1 << 4 201 bcs 1b 202 mcr p15, 0, ip, c7, c10, 4 203 ret lr 204 205 /* 206 * dma_clean_range(start, end) 207 * 208 * There is no efficient way to clean a s 209 * address range. Thus, cleans all. 210 * 211 * - start - virtual start address 212 * - end - virtual end address 213 */ 214 arm940_dma_clean_range: 215 SYM_TYPED_FUNC_START(cpu_arm940_dcache_clean_a 216 mov ip, #0 217 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 218 mov r1, #(CACHE_DSEGMENTS - 1) << 219 1: orr r3, r1, #(CACHE_DENTRIES - 1) 220 2: mcr p15, 0, r3, c7, c10, 2 221 subs r3, r3, #1 << 26 222 bcs 2b 223 subs r1, r1, #1 << 4 224 bcs 1b 225 #endif 226 mcr p15, 0, ip, c7, c10, 4 227 ret lr 228 SYM_FUNC_END(cpu_arm940_dcache_clean_area) 229 230 /* 231 * dma_flush_range(start, end) 232 * 233 * There is no efficient way to clean and 234 * virtual address range. 235 * 236 * - start - virtual start address 237 * - end - virtual end address 238 */ 239 SYM_TYPED_FUNC_START(arm940_dma_flush_range) 240 mov ip, #0 241 mov r1, #(CACHE_DSEGMENTS - 1) << 242 1: orr r3, r1, #(CACHE_DENTRIES - 1) 243 2: 244 #ifndef CONFIG_CPU_DCACHE_WRITETHROUGH 245 mcr p15, 0, r3, c7, c14, 2 246 #else 247 mcr p15, 0, r3, c7, c6, 2 248 #endif 249 subs r3, r3, #1 << 26 250 bcs 2b 251 subs r1, r1, #1 << 4 252 bcs 1b 253 mcr p15, 0, ip, c7, c10, 4 254 ret lr 255 SYM_FUNC_END(arm940_dma_flush_range) 256 257 /* 258 * dma_map_area(start, size, dir) 259 * - start - kernel virtual start address 260 * - size - size of region 261 * - dir - DMA direction 262 */ 263 SYM_TYPED_FUNC_START(arm940_dma_map_area) 264 add r1, r1, r0 265 cmp r2, #DMA_TO_DEVICE 266 beq arm940_dma_clean_range 267 bcs arm940_dma_inv_range 268 b arm940_dma_flush_range 269 SYM_FUNC_END(arm940_dma_map_area) 270 271 /* 272 * dma_unmap_area(start, size, dir) 273 * - start - kernel virtual start address 274 * - size - size of region 275 * - dir - DMA direction 276 */ 277 SYM_TYPED_FUNC_START(arm940_dma_unmap_area) 278 ret lr 279 SYM_FUNC_END(arm940_dma_unmap_area) 280 281 .type __arm940_setup, #function 282 __arm940_setup: 283 mov r0, #0 284 mcr p15, 0, r0, c7, c5, 0 285 mcr p15, 0, r0, c7, c6, 0 286 mcr p15, 0, r0, c7, c10, 4 287 288 mcr p15, 0, r0, c6, c3, 0 289 mcr p15, 0, r0, c6, c4, 0 290 mcr p15, 0, r0, c6, c5, 0 291 mcr p15, 0, r0, c6, c6, 0 292 mcr p15, 0, r0, c6, c7, 0 293 294 mcr p15, 0, r0, c6, c3, 1 295 mcr p15, 0, r0, c6, c4, 1 296 mcr p15, 0, r0, c6, c5, 1 297 mcr p15, 0, r0, c6, c6, 1 298 mcr p15, 0, r0, c6, c7, 1 299 300 mov r0, #0x0000003F 301 mcr p15, 0, r0, c6, c0, 0 302 mcr p15, 0, r0, c6, c0, 1 303 304 ldr r0, =(CONFIG_DRAM_BASE & 0xFFF 305 ldr r7, =CONFIG_DRAM_SIZE >> 12 306 pr_val r3, r0, r7, #1 307 mcr p15, 0, r3, c6, c1, 0 308 mcr p15, 0, r3, c6, c1, 1 309 310 ldr r0, =(CONFIG_FLASH_MEM_BASE & 311 ldr r7, =CONFIG_FLASH_SIZE 312 pr_val r3, r0, r6, #1 313 mcr p15, 0, r3, c6, c2, 0 314 mcr p15, 0, r3, c6, c2, 1 315 316 mov r0, #0x06 317 mcr p15, 0, r0, c2, c0, 0 318 mcr p15, 0, r0, c2, c0, 1 319 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 320 mov r0, #0x00 321 #else 322 mov r0, #0x02 323 #endif 324 mcr p15, 0, r0, c3, c0, 0 325 326 mov r0, #0x10000 327 sub r0, r0, #1 328 mcr p15, 0, r0, c5, c0, 0 329 mcr p15, 0, r0, c5, c0, 1 330 331 mrc p15, 0, r0, c1, c0 332 orr r0, r0, #0x00001000 333 orr r0, r0, #0x00000005 334 335 ret lr 336 337 .size __arm940_setup, . - __arm940_s 338 339 __INITDATA 340 341 @ define struct processor (see <asm/pr 342 define_processor_functions arm940, dab 343 344 .section ".rodata" 345 346 string cpu_arch_name, "armv4t" 347 string cpu_elf_name, "v4" 348 string cpu_arm940_name, "ARM940T" 349 350 .align 351 352 .section ".proc.info.init", "a" 353 354 .type __arm940_proc_info,#object 355 __arm940_proc_info: 356 .long 0x41009400 357 .long 0xff00fff0 358 .long 0 359 initfn __arm940_setup, __arm940_proc_ 360 .long cpu_arch_name 361 .long cpu_elf_name 362 .long HWCAP_SWP | HWCAP_HALF | HWCAP 363 .long cpu_arm940_name 364 .long arm940_processor_functions 365 .long 0 366 .long 0 367 .long arm940_cache_fns 368 .size __arm940_proc_info, . - __arm9 369
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.