1/* 2 * linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S 3 * 4 * Copyright (C) 2000 ARM Limited 5 * Copyright (C) 2000 Deep Blue Solutions Ltd. 6 * hacked for non-paged-MM by Hyok S. Choi, 2003. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * 14 * These are the low level assembler for performing cache and TLB 15 * functions on the ARM1026EJ-S. 16 */ 17#include <linux/linkage.h> 18#include <linux/init.h> 19#include <asm/assembler.h> 20#include <asm/asm-offsets.h> 21#include <asm/hwcap.h> 22#include <asm/pgtable-hwdef.h> 23#include <asm/pgtable.h> 24#include <asm/ptrace.h> 25 26#include "proc-macros.S" 27 28/* 29 * This is the maximum size of an area which will be invalidated 30 * using the single invalidate entry instructions. Anything larger 31 * than this, and we go for the whole cache. 32 * 33 * This value should be chosen such that we choose the cheapest 34 * alternative. 35 */ 36#define MAX_AREA_SIZE 32768 37 38/* 39 * The size of one data cache line. 40 */ 41#define CACHE_DLINESIZE 32 42 43/* 44 * The number of data cache segments. 45 */ 46#define CACHE_DSEGMENTS 16 47 48/* 49 * The number of lines in a cache segment. 50 */ 51#define CACHE_DENTRIES 64 52 53/* 54 * This is the size at which it becomes more efficient to 55 * clean the whole cache, rather than using the individual 56 * cache line maintenance instructions. 57 */ 58#define CACHE_DLIMIT 32768 59 60 .text 61/* 62 * cpu_arm1026_proc_init() 63 */ 64ENTRY(cpu_arm1026_proc_init) 65 mov pc, lr 66 67/* 68 * cpu_arm1026_proc_fin() 69 */ 70ENTRY(cpu_arm1026_proc_fin) 71 mrc p15, 0, r0, c1, c0, 0 @ ctrl register 72 bic r0, r0, #0x1000 @ ...i............ 73 bic r0, r0, #0x000e @ ............wca. 74 mcr p15, 0, r0, c1, c0, 0 @ disable caches 75 mov pc, lr 76 77/* 78 * cpu_arm1026_reset(loc) 79 * 80 * Perform a soft reset of the system. Put the CPU into the 81 * same state as it would be if it had been reset, and branch 82 * to what would be the reset vector. 83 * 84 * loc: location to jump to for soft reset 85 */ 86 .align 5 87 .pushsection .idmap.text, "ax" 88ENTRY(cpu_arm1026_reset) 89 mov ip, #0 90 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches 91 mcr p15, 0, ip, c7, c10, 4 @ drain WB 92#ifdef CONFIG_MMU 93 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs 94#endif 95 mrc p15, 0, ip, c1, c0, 0 @ ctrl register 96 bic ip, ip, #0x000f @ ............wcam 97 bic ip, ip, #0x1100 @ ...i...s........ 98 mcr p15, 0, ip, c1, c0, 0 @ ctrl register 99 mov pc, r0 100ENDPROC(cpu_arm1026_reset) 101 .popsection 102 103/* 104 * cpu_arm1026_do_idle() 105 */ 106 .align 5 107ENTRY(cpu_arm1026_do_idle) 108 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt 109 mov pc, lr 110 111/* ================================= CACHE ================================ */ 112 113 .align 5 114 115/* 116 * flush_icache_all() 117 * 118 * Unconditionally clean and invalidate the entire icache. 119 */ 120ENTRY(arm1026_flush_icache_all) 121#ifndef CONFIG_CPU_ICACHE_DISABLE 122 mov r0, #0 123 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache 124#endif 125 mov pc, lr 126ENDPROC(arm1026_flush_icache_all) 127 128/* 129 * flush_user_cache_all() 130 * 131 * Invalidate all cache entries in a particular address 132 * space. 133 */ 134ENTRY(arm1026_flush_user_cache_all) 135 /* FALLTHROUGH */ 136/* 137 * flush_kern_cache_all() 138 * 139 * Clean and invalidate the entire cache. 140 */ 141ENTRY(arm1026_flush_kern_cache_all) 142 mov r2, #VM_EXEC 143 mov ip, #0 144__flush_whole_cache: 145#ifndef CONFIG_CPU_DCACHE_DISABLE 1461: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate 147 bne 1b 148#endif 149 tst r2, #VM_EXEC 150#ifndef CONFIG_CPU_ICACHE_DISABLE 151 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 152#endif 153 mcrne p15, 0, ip, c7, c10, 4 @ drain WB 154 mov pc, lr 155 156/* 157 * flush_user_cache_range(start, end, flags) 158 * 159 * Invalidate a range of cache entries in the specified 160 * address space. 161 * 162 * - start - start address (inclusive) 163 * - end - end address (exclusive) 164 * - flags - vm_flags for this space 165 */ 166ENTRY(arm1026_flush_user_cache_range) 167 mov ip, #0 168 sub r3, r1, r0 @ calculate total size 169 cmp r3, #CACHE_DLIMIT 170 bhs __flush_whole_cache 171 172#ifndef CONFIG_CPU_DCACHE_DISABLE 1731: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry 174 add r0, r0, #CACHE_DLINESIZE 175 cmp r0, r1 176 blo 1b 177#endif 178 tst r2, #VM_EXEC 179#ifndef CONFIG_CPU_ICACHE_DISABLE 180 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 181#endif 182 mcrne p15, 0, ip, c7, c10, 4 @ drain WB 183 mov pc, lr 184 185/* 186 * coherent_kern_range(start, end) 187 * 188 * Ensure coherency between the Icache and the Dcache in the 189 * region described by start. If you have non-snooping 190 * Harvard caches, you need to implement this function. 191 * 192 * - start - virtual start address 193 * - end - virtual end address 194 */ 195ENTRY(arm1026_coherent_kern_range) 196 /* FALLTHROUGH */ 197/* 198 * coherent_user_range(start, end) 199 * 200 * Ensure coherency between the Icache and the Dcache in the 201 * region described by start. If you have non-snooping 202 * Harvard caches, you need to implement this function. 203 * 204 * - start - virtual start address 205 * - end - virtual end address 206 */ 207ENTRY(arm1026_coherent_user_range) 208 mov ip, #0 209 bic r0, r0, #CACHE_DLINESIZE - 1 2101: 211#ifndef CONFIG_CPU_DCACHE_DISABLE 212 mcr p15, 0, r0, c7, c10, 1 @ clean D entry 213#endif 214#ifndef CONFIG_CPU_ICACHE_DISABLE 215 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry 216#endif 217 add r0, r0, #CACHE_DLINESIZE 218 cmp r0, r1 219 blo 1b 220 mcr p15, 0, ip, c7, c10, 4 @ drain WB 221 mov pc, lr 222 223/* 224 * flush_kern_dcache_area(void *addr, size_t size) 225 * 226 * Ensure no D cache aliasing occurs, either with itself or 227 * the I cache 228 * 229 * - addr - kernel address 230 * - size - region size 231 */ 232ENTRY(arm1026_flush_kern_dcache_area) 233 mov ip, #0 234#ifndef CONFIG_CPU_DCACHE_DISABLE 235 add r1, r0, r1 2361: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry 237 add r0, r0, #CACHE_DLINESIZE 238 cmp r0, r1 239 blo 1b 240#endif 241 mcr p15, 0, ip, c7, c10, 4 @ drain WB 242 mov pc, lr 243 244/* 245 * dma_inv_range(start, end) 246 * 247 * Invalidate (discard) the specified virtual address range. 248 * May not write back any entries. If 'start' or 'end' 249 * are not cache line aligned, those lines must be written 250 * back. 251 * 252 * - start - virtual start address 253 * - end - virtual end address 254 * 255 * (same as v4wb) 256 */ 257arm1026_dma_inv_range: 258 mov ip, #0 259#ifndef CONFIG_CPU_DCACHE_DISABLE 260 tst r0, #CACHE_DLINESIZE - 1 261 bic r0, r0, #CACHE_DLINESIZE - 1 262 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry 263 tst r1, #CACHE_DLINESIZE - 1 264 mcrne p15, 0, r1, c7, c10, 1 @ clean D entry 2651: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry 266 add r0, r0, #CACHE_DLINESIZE 267 cmp r0, r1 268 blo 1b 269#endif 270 mcr p15, 0, ip, c7, c10, 4 @ drain WB 271 mov pc, lr 272 273/* 274 * dma_clean_range(start, end) 275 * 276 * Clean the specified virtual address range. 277 * 278 * - start - virtual start address 279 * - end - virtual end address 280 * 281 * (same as v4wb) 282 */ 283arm1026_dma_clean_range: 284 mov ip, #0 285#ifndef CONFIG_CPU_DCACHE_DISABLE 286 bic r0, r0, #CACHE_DLINESIZE - 1 2871: mcr p15, 0, r0, c7, c10, 1 @ clean D entry 288 add r0, r0, #CACHE_DLINESIZE 289 cmp r0, r1 290 blo 1b 291#endif 292 mcr p15, 0, ip, c7, c10, 4 @ drain WB 293 mov pc, lr 294 295/* 296 * dma_flush_range(start, end) 297 * 298 * Clean and invalidate the specified virtual address range. 299 * 300 * - start - virtual start address 301 * - end - virtual end address 302 */ 303ENTRY(arm1026_dma_flush_range) 304 mov ip, #0 305#ifndef CONFIG_CPU_DCACHE_DISABLE 306 bic r0, r0, #CACHE_DLINESIZE - 1 3071: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry 308 add r0, r0, #CACHE_DLINESIZE 309 cmp r0, r1 310 blo 1b 311#endif 312 mcr p15, 0, ip, c7, c10, 4 @ drain WB 313 mov pc, lr 314 315/* 316 * dma_map_area(start, size, dir) 317 * - start - kernel virtual start address 318 * - size - size of region 319 * - dir - DMA direction 320 */ 321ENTRY(arm1026_dma_map_area) 322 add r1, r1, r0 323 cmp r2, #DMA_TO_DEVICE 324 beq arm1026_dma_clean_range 325 bcs arm1026_dma_inv_range 326 b arm1026_dma_flush_range 327ENDPROC(arm1026_dma_map_area) 328 329/* 330 * dma_unmap_area(start, size, dir) 331 * - start - kernel virtual start address 332 * - size - size of region 333 * - dir - DMA direction 334 */ 335ENTRY(arm1026_dma_unmap_area) 336 mov pc, lr 337ENDPROC(arm1026_dma_unmap_area) 338 339 @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) 340 define_cache_functions arm1026 341 342 .align 5 343ENTRY(cpu_arm1026_dcache_clean_area) 344#ifndef CONFIG_CPU_DCACHE_DISABLE 345 mov ip, #0 3461: mcr p15, 0, r0, c7, c10, 1 @ clean D entry 347 add r0, r0, #CACHE_DLINESIZE 348 subs r1, r1, #CACHE_DLINESIZE 349 bhi 1b 350#endif 351 mov pc, lr 352 353/* =============================== PageTable ============================== */ 354 355/* 356 * cpu_arm1026_switch_mm(pgd) 357 * 358 * Set the translation base pointer to be as described by pgd. 359 * 360 * pgd: new page tables 361 */ 362 .align 5 363ENTRY(cpu_arm1026_switch_mm) 364#ifdef CONFIG_MMU 365 mov r1, #0 366#ifndef CONFIG_CPU_DCACHE_DISABLE 3671: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate 368 bne 1b 369#endif 370#ifndef CONFIG_CPU_ICACHE_DISABLE 371 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache 372#endif 373 mcr p15, 0, r1, c7, c10, 4 @ drain WB 374 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer 375 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs 376#endif 377 mov pc, lr 378 379/* 380 * cpu_arm1026_set_pte_ext(ptep, pte, ext) 381 * 382 * Set a PTE and flush it out 383 */ 384 .align 5 385ENTRY(cpu_arm1026_set_pte_ext) 386#ifdef CONFIG_MMU 387 armv3_set_pte_ext 388 mov r0, r0 389#ifndef CONFIG_CPU_DCACHE_DISABLE 390 mcr p15, 0, r0, c7, c10, 1 @ clean D entry 391#endif 392#endif /* CONFIG_MMU */ 393 mov pc, lr 394 395 396 __CPUINIT 397 398 .type __arm1026_setup, #function 399__arm1026_setup: 400 mov r0, #0 401 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 402 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 403#ifdef CONFIG_MMU 404 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 405 mcr p15, 0, r4, c2, c0 @ load page table pointer 406#endif 407#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 408 mov r0, #4 @ explicitly disable writeback 409 mcr p15, 7, r0, c15, c0, 0 410#endif 411 adr r5, arm1026_crval 412 ldmia r5, {r5, r6} 413 mrc p15, 0, r0, c1, c0 @ get control register v4 414 bic r0, r0, r5 415 orr r0, r0, r6 416#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN 417 orr r0, r0, #0x4000 @ .R.. .... .... .... 418#endif 419 mov pc, lr 420 .size __arm1026_setup, . - __arm1026_setup 421 422 /* 423 * R 424 * .RVI ZFRS BLDP WCAM 425 * .011 1001 ..11 0101 426 * 427 */ 428 .type arm1026_crval, #object 429arm1026_crval: 430 crval clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934 431 432 __INITDATA 433 @ define struct processor (see <asm/proc-fns.h> and proc-macros.S) 434 define_processor_functions arm1026, dabort=v5t_early_abort, pabort=legacy_pabort 435 436 .section .rodata 437 438 string cpu_arch_name, "armv5tej" 439 string cpu_elf_name, "v5" 440 .align 441 string cpu_arm1026_name, "ARM1026EJ-S" 442 .align 443 444 .section ".proc.info.init", #alloc, #execinstr 445 446 .type __arm1026_proc_info,#object 447__arm1026_proc_info: 448 .long 0x4106a260 @ ARM 1026EJ-S (v5TEJ) 449 .long 0xff0ffff0 450 .long PMD_TYPE_SECT | \ 451 PMD_BIT4 | \ 452 PMD_SECT_AP_WRITE | \ 453 PMD_SECT_AP_READ 454 .long PMD_TYPE_SECT | \ 455 PMD_BIT4 | \ 456 PMD_SECT_AP_WRITE | \ 457 PMD_SECT_AP_READ 458 b __arm1026_setup 459 .long cpu_arch_name 460 .long cpu_elf_name 461 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA 462 .long cpu_arm1026_name 463 .long arm1026_processor_functions 464 .long v4wbi_tlb_fns 465 .long v4wb_user_fns 466 .long arm1026_cache_fns 467 .size __arm1026_proc_info, . - __arm1026_proc_info 468