linux-old/arch/arm/mm/proc-arm2,3.S
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mm/proc-arm2,3.S
   3 *
   4 *  Copyright (C) 1997-1999 Russell King
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 *  MMU functions for ARM2,3
  11 *
  12 *  These are the low level assembler for performing cache
  13 *  and memory functions on ARM2, ARM250 and ARM3 processors.
  14 */
  15#include <linux/linkage.h>
  16#include <asm/assembler.h>
  17#include <asm/constants.h>
  18#include <asm/procinfo.h>
  19
  20/*
  21 * MEMC workhorse code.  It's both a horse which things it's a pig.
  22 */
  23/*
  24 * Function: cpu_memc_update_entry(pgd_t *pgd, unsigned long phys_pte, unsigned long addr)
  25 * Params  : pgd        Page tables/MEMC mapping
  26 *         : phys_pte   physical address, or PTE
  27 *         : addr       virtual address
  28 */
  29ENTRY(cpu_memc_update_entry)
  30                tst     r1, #PAGE_PRESENT               @ is the page present
  31                orreq   r1, r1, #PAGE_OLD | PAGE_CLEAN
  32                moveq   r2, #0x01f00000
  33                mov     r3, r1, lsr #13                 @ convert to physical page nr
  34                and     r3, r3, #0x3fc
  35                adr     ip, memc_phys_table_32
  36                ldr     r3, [ip, r3]
  37                tst     r1, #PAGE_OLD | PAGE_NOT_USER
  38                biceq   r3, r3, #0x200
  39                tsteq   r1, #PAGE_READONLY | PAGE_CLEAN
  40                biceq   r3, r3, #0x300
  41                mov     r2, r2, lsr #15                 @ virtual -> nr
  42                orr     r3, r3, r2, lsl #15
  43                and     r2, r2, #0x300
  44                orr     r3, r3, r2, lsl #2
  45                and     r2, r3, #255
  46                sub     r0, r0, #256 * 4
  47                str     r3, [r0, r2, lsl #2]
  48                strb    r3, [r3]
  49                movs    pc, lr
  50/*
  51 * Params  : r0 = preserved
  52 *         : r1 = memc table base (preserved)
  53 *         : r2 = page table entry
  54 *         : r3 = preserved
  55 *         : r4 = unused
  56 *         : r5 = memc physical address translation table
  57 *         : ip = virtual address (preserved)
  58 */
  59update_pte:
  60                mov     r4, r2, lsr #13
  61                and     r4, r4, #0x3fc
  62                ldr     r4, [r5, r4]                    @ covert to MEMC page
  63
  64                tst     r2, #PAGE_OLD | PAGE_NOT_USER   @ check for MEMC read
  65                biceq   r4, r4, #0x200
  66                tsteq   r2, #PAGE_READONLY | PAGE_CLEAN @ check for MEMC write
  67                biceq   r4, r4, #0x300
  68
  69                orr     r4, r4, ip
  70                and     r2, ip, #0x01800000
  71                orr     r4, r4, r2, lsr #13
  72
  73                and     r2, r4, #255
  74                str     r4, [r1, r2, lsl #2]
  75                movs    pc, lr
  76
  77/*
  78 * Params  : r0 = preserved
  79 *         : r1 = memc table base (preserved)
  80 *         : r2 = page table base
  81 *         : r3 = preserved
  82 *         : r4 = unused
  83 *         : r5 = memc physical address translation table
  84 *         : ip = virtual address (updated)
  85 */
  86update_pte_table:
  87                stmfd   sp!, {r0, lr}
  88                bic     r0, r2, #3
  891:              ldr     r2, [r0], #4                    @ get entry
  90                tst     r2, #PAGE_PRESENT               @ page present
  91                blne    update_pte                      @ process pte
  92                add     ip, ip, #32768                  @ increment virt addr
  93                ldr     r2, [r0], #4                    @ get entry
  94                tst     r2, #PAGE_PRESENT               @ page present
  95                blne    update_pte                      @ process pte
  96                add     ip, ip, #32768                  @ increment virt addr
  97                ldr     r2, [r0], #4                    @ get entry
  98                tst     r2, #PAGE_PRESENT               @ page present
  99                blne    update_pte                      @ process pte
 100                add     ip, ip, #32768                  @ increment virt addr
 101                ldr     r2, [r0], #4                    @ get entry
 102                tst     r2, #PAGE_PRESENT               @ page present
 103                blne    update_pte                      @ process pte
 104                add     ip, ip, #32768                  @ increment virt addr
 105                tst     ip, #32768 * 31                 @ finished?
 106                bne     1b
 107                ldmfd   sp!, {r0, pc}^
 108
 109/*
 110 * Function: cpu_memc_update_all(pgd_t *pgd)
 111 * Params  : pgd        Page tables/MEMC mapping
 112 * Notes   : this is optimised for 32k pages
 113 */
 114ENTRY(cpu_memc_update_all)
 115                stmfd   sp!, {r4, r5, lr}
 116                bl      clear_tables
 117                sub     r1, r0, #256 * 4                @ start of MEMC tables
 118                adr     r5, memc_phys_table_32          @ Convert to logical page number
 119                mov     ip, #0                          @ virtual address
 1201:              ldmia   r0!, {r2, r3}
 121                tst     r2, #PAGE_PRESENT
 122                addeq   ip, ip, #1048576
 123                blne    update_pte_table
 124                mov     r2, r3
 125                tst     r2, #PAGE_PRESENT
 126                addeq   ip, ip, #1048576
 127                blne    update_pte_table
 128                teq     ip, #32 * 1048576
 129                bne     1b
 130                ldmfd   sp!, {r4, r5, pc}^
 131
 132/*
 133 * Build the table to map from physical page number to memc page number
 134 */
 135                .type   memc_phys_table_32, #object
 136memc_phys_table_32:
 137                .irp    b7, 0x00, 0x80
 138                .irp    b6, 0x00, 0x02
 139                .irp    b5, 0x00, 0x04
 140                .irp    b4, 0x00, 0x01
 141
 142                .irp    b3, 0x00, 0x40
 143                .irp    b2, 0x00, 0x20
 144                .irp    b1, 0x00, 0x10
 145                .irp    b0, 0x00, 0x08
 146                .long   0x03800300 + \b7 + \b6 + \b5 + \b4 + \b3 + \b2 + \b1 + \b0
 147                .endr
 148                .endr
 149                .endr
 150                .endr
 151
 152                .endr
 153                .endr
 154                .endr
 155                .endr
 156                .size   memc_phys_table_32, . - memc_phys_table_32
 157
 158/*
 159 * helper for cpu_memc_update_all, this clears out all
 160 * mappings, setting them close to the top of memory,
 161 * and inaccessible (0x01f00000).
 162 * Params  : r0 = page table pointer
 163 */
 164clear_tables:   ldr     r1, _arm3_set_pgd - 4
 165                ldr     r2, [r1]
 166                sub     r1, r0, #256 * 4                @ start of MEMC tables
 167                add     r2, r1, r2, lsl #2              @ end of tables
 168                mov     r3, #0x03f00000                 @ Default mapping (null mapping)
 169                orr     r3, r3, #0x00000f00
 170                orr     r4, r3, #1
 171                orr     r5, r3, #2
 172                orr     ip, r3, #3
 1731:              stmia   r1!, {r3, r4, r5, ip}
 174                add     r3, r3, #4
 175                add     r4, r4, #4
 176                add     r5, r5, #4
 177                add     ip, ip, #4
 178                stmia   r1!, {r3, r4, r5, ip}
 179                add     r3, r3, #4
 180                add     r4, r4, #4
 181                add     r5, r5, #4
 182                add     ip, ip, #4
 183                teq     r1, r2
 184                bne     1b
 185                mov     pc, lr
 186
 187/*
 188 * Function: *_set_pgd(pgd_t *pgd)
 189 * Params  : pgd        New page tables/MEMC mapping
 190 * Purpose : update MEMC hardware with new mapping
 191 */
 192                .word   SYMBOL_NAME(page_nr)
 193_arm3_set_pgd:  mcr     p15, 0, r1, c1, c0, 0           @ flush cache
 194_arm2_set_pgd:  stmfd   sp!, {lr}
 195                ldr     r1, _arm3_set_pgd - 4
 196                ldr     r2, [r1]
 197                sub     r0, r0, #256 * 4                @ start of MEMC tables
 198                add     r1, r0, r2, lsl #2              @ end of tables
 1991:              ldmia   r0!, {r2, r3, ip, lr}
 200                strb    r2, [r2]
 201                strb    r3, [r3]
 202                strb    ip, [ip]
 203                strb    lr, [lr]
 204                ldmia   r0!, {r2, r3, ip, lr}
 205                strb    r2, [r2]
 206                strb    r3, [r3]
 207                strb    ip, [ip]
 208                strb    lr, [lr]
 209                teq     r0, r1
 210                bne     1b
 211                ldmfd   sp!, {pc}^
 212
 213/*
 214 * Function: *_proc_init (void)
 215 * Purpose : Initialise the cache control registers
 216 */
 217_arm3_proc_init:
 218                mov     r0, #0x001f0000
 219                orr     r0, r0, #0x0000ff00
 220                orr     r0, r0, #0x000000ff
 221                mcr     p15, 0, r0, c3, c0              @ ARM3 Cacheable
 222                mcr     p15, 0, r0, c4, c0              @ ARM3 Updateable
 223                mov     r0, #0
 224                mcr     p15, 0, r0, c5, c0              @ ARM3 Disruptive
 225                mcr     p15, 0, r0, c1, c0              @ ARM3 Flush
 226                mov     r0, #3
 227                mcr     p15, 0, r0, c2, c0              @ ARM3 Control
 228_arm2_proc_init:
 229                movs    pc, lr
 230
 231/*
 232 * Function: *_proc_fin (void)
 233 * Purpose : Finalise processor (disable caches)
 234 */
 235_arm3_proc_fin: mov     r0, #2
 236                mcr     p15, 0, r0, c2, c0
 237_arm2_proc_fin: orrs    pc, lr, #I_BIT|F_BIT
 238
 239/*
 240 * Function: *_xchg_1 (int new, volatile void *ptr)
 241 * Params  : new        New value to store at...
 242 *         : ptr        pointer to byte-wide location
 243 * Purpose : Performs an exchange operation
 244 * Returns : Original byte data at 'ptr'
 245 */
 246_arm2_xchg_1:   mov     r2, pc
 247                orr     r2, r2, #I_BIT
 248                teqp    r2, #0
 249                ldrb    r2, [r1]
 250                strb    r0, [r1]
 251                mov     r0, r2
 252                movs    pc, lr
 253
 254_arm3_xchg_1:   swpb    r0, r0, [r1]
 255                movs    pc, lr
 256
 257/*
 258 * Function: *_xchg_4 (int new, volatile void *ptr)
 259 * Params  : new        New value to store at...
 260 *         : ptr        pointer to word-wide location
 261 * Purpose : Performs an exchange operation
 262 * Returns : Original word data at 'ptr'
 263 */
 264_arm2_xchg_4:   mov     r2, pc
 265                orr     r2, r2, #I_BIT
 266                teqp    r2, #0
 267                ldr     r2, [r1]
 268                str     r0, [r1]
 269                mov     r0, r2
 270                movs    pc, lr
 271
 272_arm3_xchg_4:   swp     r0, r0, [r1]
 273                movs    pc, lr
 274
 275_arm2_3_check_bugs:
 276                bics    pc, lr, #0x04000000             @ Clear FIQ disable bit
 277
 278_arm2_name:     .asciz  "ARM 2"
 279_arm250_name:   .asciz  "ARM 250"
 280_arm3_name:     .asciz  "ARM 3"
 281
 282                .section ".text.init", #alloc, #execinstr
 283/*
 284 * Purpose : Function pointers used to access above functions - all calls
 285 *           come through these
 286 */
 287                .globl  SYMBOL_NAME(arm2_processor_functions)
 288SYMBOL_NAME(arm2_processor_functions):
 289                .word   _arm2_3_check_bugs
 290                .word   _arm2_proc_init
 291                .word   _arm2_proc_fin
 292                .word   _arm2_set_pgd
 293                .word   _arm2_xchg_1
 294                .word   _arm2_xchg_4
 295
 296cpu_arm2_info:
 297                .long   0
 298                .long   _arm2_name
 299
 300                .globl  SYMBOL_NAME(arm250_processor_functions)
 301SYMBOL_NAME(arm250_processor_functions):
 302                .word   _arm2_3_check_bugs
 303                .word   _arm2_proc_init
 304                .word   _arm2_proc_fin
 305                .word   _arm2_set_pgd
 306                .word   _arm3_xchg_1
 307                .word   _arm3_xchg_4
 308
 309cpu_arm250_info:
 310                .long   0
 311                .long   _arm250_name
 312
 313                .globl  SYMBOL_NAME(arm3_processor_functions)
 314SYMBOL_NAME(arm3_processor_functions):
 315                .word   _arm2_3_check_bugs
 316                .word   _arm3_proc_init
 317                .word   _arm3_proc_fin
 318                .word   _arm3_set_pgd
 319                .word   _arm3_xchg_1
 320                .word   _arm3_xchg_4
 321
 322cpu_arm3_info:
 323                .long   0
 324                .long   _arm3_name
 325
 326arm2_arch_name: .asciz  "armv1"
 327arm3_arch_name: .asciz  "armv2"
 328arm2_elf_name:  .asciz  "v1"
 329arm3_elf_name:  .asciz  "v2"
 330                .align
 331
 332                .section ".proc.info", #alloc, #execinstr
 333
 334                .long   0x41560200
 335                .long   0xfffffff0
 336                .long   0
 337                mov     pc, lr
 338                .long   arm2_arch_name
 339                .long   arm2_elf_name
 340                .long   0
 341                .long   cpu_arm2_info
 342                .long   SYMBOL_NAME(arm2_processor_functions)
 343
 344                .long   0x41560250
 345                .long   0xfffffff0
 346                .long   0
 347                mov     pc, lr
 348                .long   arm3_arch_name
 349                .long   arm3_elf_name
 350                .long   0
 351                .long   cpu_arm250_info
 352                .long   SYMBOL_NAME(arm250_processor_functions)
 353
 354                .long   0x41560300
 355                .long   0xfffffff0
 356                .long   0
 357                mov     pc, lr
 358                .long   arm3_arch_name
 359                .long   arm3_elf_name
 360                .long   0
 361                .long   cpu_arm3_info
 362                .long   SYMBOL_NAME(arm3_processor_functions)
 363
 364
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.