linux/arch/arm/mm/proc-arm1020e.S
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mm/proc-arm1020e.S: MMU functions for ARM1020
   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 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21 *
  22 *
  23 * These are the low level assembler for performing cache and TLB
  24 * functions on the arm1020e.
  25 */
  26#include <linux/linkage.h>
  27#include <linux/init.h>
  28#include <asm/assembler.h>
  29#include <asm/asm-offsets.h>
  30#include <asm/hwcap.h>
  31#include <asm/pgtable-hwdef.h>
  32#include <asm/pgtable.h>
  33#include <asm/ptrace.h>
  34
  35#include "proc-macros.S"
  36
  37/*
  38 * This is the maximum size of an area which will be invalidated
  39 * using the single invalidate entry instructions.  Anything larger
  40 * than this, and we go for the whole cache.
  41 *
  42 * This value should be chosen such that we choose the cheapest
  43 * alternative.
  44 */
  45#define MAX_AREA_SIZE   32768
  46
  47/*
  48 * The size of one data cache line.
  49 */
  50#define CACHE_DLINESIZE 32
  51
  52/*
  53 * The number of data cache segments.
  54 */
  55#define CACHE_DSEGMENTS 16
  56
  57/*
  58 * The number of lines in a cache segment.
  59 */
  60#define CACHE_DENTRIES  64
  61
  62/*
  63 * This is the size at which it becomes more efficient to
  64 * clean the whole cache, rather than using the individual
  65 * cache line maintenance instructions.
  66 */
  67#define CACHE_DLIMIT    32768
  68
  69        .text
  70/*
  71 * cpu_arm1020e_proc_init()
  72 */
  73ENTRY(cpu_arm1020e_proc_init)
  74        ret     lr
  75
  76/*
  77 * cpu_arm1020e_proc_fin()
  78 */
  79ENTRY(cpu_arm1020e_proc_fin)
  80        mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
  81        bic     r0, r0, #0x1000                 @ ...i............
  82        bic     r0, r0, #0x000e                 @ ............wca.
  83        mcr     p15, 0, r0, c1, c0, 0           @ disable caches
  84        ret     lr
  85
  86/*
  87 * cpu_arm1020e_reset(loc)
  88 *
  89 * Perform a soft reset of the system.  Put the CPU into the
  90 * same state as it would be if it had been reset, and branch
  91 * to what would be the reset vector.
  92 *
  93 * loc: location to jump to for soft reset
  94 */
  95        .align  5
  96        .pushsection    .idmap.text, "ax"
  97ENTRY(cpu_arm1020e_reset)
  98        mov     ip, #0
  99        mcr     p15, 0, ip, c7, c7, 0           @ invalidate I,D caches
 100        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 101#ifdef CONFIG_MMU
 102        mcr     p15, 0, ip, c8, c7, 0           @ invalidate I & D TLBs
 103#endif
 104        mrc     p15, 0, ip, c1, c0, 0           @ ctrl register
 105        bic     ip, ip, #0x000f                 @ ............wcam
 106        bic     ip, ip, #0x1100                 @ ...i...s........
 107        mcr     p15, 0, ip, c1, c0, 0           @ ctrl register
 108        ret     r0
 109ENDPROC(cpu_arm1020e_reset)
 110        .popsection
 111
 112/*
 113 * cpu_arm1020e_do_idle()
 114 */
 115        .align  5
 116ENTRY(cpu_arm1020e_do_idle)
 117        mcr     p15, 0, r0, c7, c0, 4           @ Wait for interrupt
 118        ret     lr
 119
 120/* ================================= CACHE ================================ */
 121
 122        .align  5
 123
 124/*
 125 *      flush_icache_all()
 126 *
 127 *      Unconditionally clean and invalidate the entire icache.
 128 */
 129ENTRY(arm1020e_flush_icache_all)
 130#ifndef CONFIG_CPU_ICACHE_DISABLE
 131        mov     r0, #0
 132        mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
 133#endif
 134        ret     lr
 135ENDPROC(arm1020e_flush_icache_all)
 136
 137/*
 138 *      flush_user_cache_all()
 139 *
 140 *      Invalidate all cache entries in a particular address
 141 *      space.
 142 */
 143ENTRY(arm1020e_flush_user_cache_all)
 144        /* FALLTHROUGH */
 145/*
 146 *      flush_kern_cache_all()
 147 *
 148 *      Clean and invalidate the entire cache.
 149 */
 150ENTRY(arm1020e_flush_kern_cache_all)
 151        mov     r2, #VM_EXEC
 152        mov     ip, #0
 153__flush_whole_cache:
 154#ifndef CONFIG_CPU_DCACHE_DISABLE
 155        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 156        mov     r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
 1571:      orr     r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
 1582:      mcr     p15, 0, r3, c7, c14, 2          @ clean+invalidate D index
 159        subs    r3, r3, #1 << 26
 160        bcs     2b                              @ entries 63 to 0
 161        subs    r1, r1, #1 << 5
 162        bcs     1b                              @ segments 15 to 0
 163#endif
 164        tst     r2, #VM_EXEC
 165#ifndef CONFIG_CPU_ICACHE_DISABLE
 166        mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
 167#endif
 168        mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
 169        ret     lr
 170
 171/*
 172 *      flush_user_cache_range(start, end, flags)
 173 *
 174 *      Invalidate a range of cache entries in the specified
 175 *      address space.
 176 *
 177 *      - start - start address (inclusive)
 178 *      - end   - end address (exclusive)
 179 *      - flags - vm_flags for this space
 180 */
 181ENTRY(arm1020e_flush_user_cache_range)
 182        mov     ip, #0
 183        sub     r3, r1, r0                      @ calculate total size
 184        cmp     r3, #CACHE_DLIMIT
 185        bhs     __flush_whole_cache
 186
 187#ifndef CONFIG_CPU_DCACHE_DISABLE
 1881:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
 189        add     r0, r0, #CACHE_DLINESIZE
 190        cmp     r0, r1
 191        blo     1b
 192#endif
 193        tst     r2, #VM_EXEC
 194#ifndef CONFIG_CPU_ICACHE_DISABLE
 195        mcrne   p15, 0, ip, c7, c5, 0           @ invalidate I cache
 196#endif
 197        mcrne   p15, 0, ip, c7, c10, 4          @ drain WB
 198        ret     lr
 199
 200/*
 201 *      coherent_kern_range(start, end)
 202 *
 203 *      Ensure coherency between the Icache and the Dcache in the
 204 *      region described by start.  If you have non-snooping
 205 *      Harvard caches, you need to implement this function.
 206 *
 207 *      - start - virtual start address
 208 *      - end   - virtual end address
 209 */
 210ENTRY(arm1020e_coherent_kern_range)
 211        /* FALLTHROUGH */
 212/*
 213 *      coherent_user_range(start, end)
 214 *
 215 *      Ensure coherency between the Icache and the Dcache in the
 216 *      region described by start.  If you have non-snooping
 217 *      Harvard caches, you need to implement this function.
 218 *
 219 *      - start - virtual start address
 220 *      - end   - virtual end address
 221 */
 222ENTRY(arm1020e_coherent_user_range)
 223        mov     ip, #0
 224        bic     r0, r0, #CACHE_DLINESIZE - 1
 2251:
 226#ifndef CONFIG_CPU_DCACHE_DISABLE
 227        mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
 228#endif
 229#ifndef CONFIG_CPU_ICACHE_DISABLE
 230        mcr     p15, 0, r0, c7, c5, 1           @ invalidate I entry
 231#endif
 232        add     r0, r0, #CACHE_DLINESIZE
 233        cmp     r0, r1
 234        blo     1b
 235        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 236        mov     r0, #0
 237        ret     lr
 238
 239/*
 240 *      flush_kern_dcache_area(void *addr, size_t size)
 241 *
 242 *      Ensure no D cache aliasing occurs, either with itself or
 243 *      the I cache
 244 *
 245 *      - addr  - kernel address
 246 *      - size  - region size
 247 */
 248ENTRY(arm1020e_flush_kern_dcache_area)
 249        mov     ip, #0
 250#ifndef CONFIG_CPU_DCACHE_DISABLE
 251        add     r1, r0, r1
 2521:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
 253        add     r0, r0, #CACHE_DLINESIZE
 254        cmp     r0, r1
 255        blo     1b
 256#endif
 257        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 258        ret     lr
 259
 260/*
 261 *      dma_inv_range(start, end)
 262 *
 263 *      Invalidate (discard) the specified virtual address range.
 264 *      May not write back any entries.  If 'start' or 'end'
 265 *      are not cache line aligned, those lines must be written
 266 *      back.
 267 *
 268 *      - start - virtual start address
 269 *      - end   - virtual end address
 270 *
 271 * (same as v4wb)
 272 */
 273arm1020e_dma_inv_range:
 274        mov     ip, #0
 275#ifndef CONFIG_CPU_DCACHE_DISABLE
 276        tst     r0, #CACHE_DLINESIZE - 1
 277        bic     r0, r0, #CACHE_DLINESIZE - 1
 278        mcrne   p15, 0, r0, c7, c10, 1          @ clean D entry
 279        tst     r1, #CACHE_DLINESIZE - 1
 280        mcrne   p15, 0, r1, c7, c10, 1          @ clean D entry
 2811:      mcr     p15, 0, r0, c7, c6, 1           @ invalidate D entry
 282        add     r0, r0, #CACHE_DLINESIZE
 283        cmp     r0, r1
 284        blo     1b
 285#endif
 286        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 287        ret     lr
 288
 289/*
 290 *      dma_clean_range(start, end)
 291 *
 292 *      Clean the specified virtual address range.
 293 *
 294 *      - start - virtual start address
 295 *      - end   - virtual end address
 296 *
 297 * (same as v4wb)
 298 */
 299arm1020e_dma_clean_range:
 300        mov     ip, #0
 301#ifndef CONFIG_CPU_DCACHE_DISABLE
 302        bic     r0, r0, #CACHE_DLINESIZE - 1
 3031:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
 304        add     r0, r0, #CACHE_DLINESIZE
 305        cmp     r0, r1
 306        blo     1b
 307#endif
 308        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 309        ret     lr
 310
 311/*
 312 *      dma_flush_range(start, end)
 313 *
 314 *      Clean and invalidate the specified virtual address range.
 315 *
 316 *      - start - virtual start address
 317 *      - end   - virtual end address
 318 */
 319ENTRY(arm1020e_dma_flush_range)
 320        mov     ip, #0
 321#ifndef CONFIG_CPU_DCACHE_DISABLE
 322        bic     r0, r0, #CACHE_DLINESIZE - 1
 3231:      mcr     p15, 0, r0, c7, c14, 1          @ clean+invalidate D entry
 324        add     r0, r0, #CACHE_DLINESIZE
 325        cmp     r0, r1
 326        blo     1b
 327#endif
 328        mcr     p15, 0, ip, c7, c10, 4          @ drain WB
 329        ret     lr
 330
 331/*
 332 *      dma_map_area(start, size, dir)
 333 *      - start - kernel virtual start address
 334 *      - size  - size of region
 335 *      - dir   - DMA direction
 336 */
 337ENTRY(arm1020e_dma_map_area)
 338        add     r1, r1, r0
 339        cmp     r2, #DMA_TO_DEVICE
 340        beq     arm1020e_dma_clean_range
 341        bcs     arm1020e_dma_inv_range
 342        b       arm1020e_dma_flush_range
 343ENDPROC(arm1020e_dma_map_area)
 344
 345/*
 346 *      dma_unmap_area(start, size, dir)
 347 *      - start - kernel virtual start address
 348 *      - size  - size of region
 349 *      - dir   - DMA direction
 350 */
 351ENTRY(arm1020e_dma_unmap_area)
 352        ret     lr
 353ENDPROC(arm1020e_dma_unmap_area)
 354
 355        .globl  arm1020e_flush_kern_cache_louis
 356        .equ    arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
 357
 358        @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 359        define_cache_functions arm1020e
 360
 361        .align  5
 362ENTRY(cpu_arm1020e_dcache_clean_area)
 363#ifndef CONFIG_CPU_DCACHE_DISABLE
 364        mov     ip, #0
 3651:      mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
 366        add     r0, r0, #CACHE_DLINESIZE
 367        subs    r1, r1, #CACHE_DLINESIZE
 368        bhi     1b
 369#endif
 370        ret     lr
 371
 372/* =============================== PageTable ============================== */
 373
 374/*
 375 * cpu_arm1020e_switch_mm(pgd)
 376 *
 377 * Set the translation base pointer to be as described by pgd.
 378 *
 379 * pgd: new page tables
 380 */
 381        .align  5
 382ENTRY(cpu_arm1020e_switch_mm)
 383#ifdef CONFIG_MMU
 384#ifndef CONFIG_CPU_DCACHE_DISABLE
 385        mcr     p15, 0, r3, c7, c10, 4
 386        mov     r1, #0xF                        @ 16 segments
 3871:      mov     r3, #0x3F                       @ 64 entries
 3882:      mov     ip, r3, LSL #26                 @ shift up entry
 389        orr     ip, ip, r1, LSL #5              @ shift in/up index
 390        mcr     p15, 0, ip, c7, c14, 2          @ Clean & Inval DCache entry
 391        mov     ip, #0
 392        subs    r3, r3, #1
 393        cmp     r3, #0
 394        bge     2b                              @ entries 3F to 0
 395        subs    r1, r1, #1
 396        cmp     r1, #0
 397        bge     1b                              @ segments 15 to 0
 398
 399#endif
 400        mov     r1, #0
 401#ifndef CONFIG_CPU_ICACHE_DISABLE
 402        mcr     p15, 0, r1, c7, c5, 0           @ invalidate I cache
 403#endif
 404        mcr     p15, 0, r1, c7, c10, 4          @ drain WB
 405        mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
 406        mcr     p15, 0, r1, c8, c7, 0           @ invalidate I & D TLBs
 407#endif
 408        ret     lr
 409        
 410/*
 411 * cpu_arm1020e_set_pte(ptep, pte)
 412 *
 413 * Set a PTE and flush it out
 414 */
 415        .align  5
 416ENTRY(cpu_arm1020e_set_pte_ext)
 417#ifdef CONFIG_MMU
 418        armv3_set_pte_ext
 419        mov     r0, r0
 420#ifndef CONFIG_CPU_DCACHE_DISABLE
 421        mcr     p15, 0, r0, c7, c10, 1          @ clean D entry
 422#endif
 423#endif /* CONFIG_MMU */
 424        ret     lr
 425
 426        .type   __arm1020e_setup, #function
 427__arm1020e_setup:
 428        mov     r0, #0
 429        mcr     p15, 0, r0, c7, c7              @ invalidate I,D caches on v4
 430        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer on v4
 431#ifdef CONFIG_MMU
 432        mcr     p15, 0, r0, c8, c7              @ invalidate I,D TLBs on v4
 433#endif
 434        adr     r5, arm1020e_crval
 435        ldmia   r5, {r5, r6}
 436        mrc     p15, 0, r0, c1, c0              @ get control register v4
 437        bic     r0, r0, r5
 438        orr     r0, r0, r6
 439#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 440        orr     r0, r0, #0x4000                 @ .R.. .... .... ....
 441#endif
 442        ret     lr
 443        .size   __arm1020e_setup, . - __arm1020e_setup
 444
 445        /*
 446         *  R
 447         * .RVI ZFRS BLDP WCAM
 448         * .011 1001 ..11 0101
 449         */
 450        .type   arm1020e_crval, #object
 451arm1020e_crval:
 452        crval   clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
 453
 454        __INITDATA
 455        @ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
 456        define_processor_functions arm1020e, dabort=v4t_early_abort, pabort=legacy_pabort
 457
 458        .section ".rodata"
 459
 460        string  cpu_arch_name, "armv5te"
 461        string  cpu_elf_name, "v5"
 462        string  cpu_arm1020e_name, "ARM1020E"
 463
 464        .align
 465
 466        .section ".proc.info.init", #alloc
 467
 468        .type   __arm1020e_proc_info,#object
 469__arm1020e_proc_info:
 470        .long   0x4105a200                      @ ARM 1020TE (Architecture v5TE)
 471        .long   0xff0ffff0
 472        .long   PMD_TYPE_SECT | \
 473                PMD_BIT4 | \
 474                PMD_SECT_AP_WRITE | \
 475                PMD_SECT_AP_READ
 476        .long   PMD_TYPE_SECT | \
 477                PMD_BIT4 | \
 478                PMD_SECT_AP_WRITE | \
 479                PMD_SECT_AP_READ
 480        initfn  __arm1020e_setup, __arm1020e_proc_info
 481        .long   cpu_arch_name
 482        .long   cpu_elf_name
 483        .long   HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP
 484        .long   cpu_arm1020e_name
 485        .long   arm1020e_processor_functions
 486        .long   v4wbi_tlb_fns
 487        .long   v4wb_user_fns
 488        .long   arm1020e_cache_fns
 489        .size   __arm1020e_proc_info, . - __arm1020e_proc_info
 490