root/arch/xtensa/mm/misc.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * arch/xtensa/mm/misc.S
   3  *
   4  * Miscellaneous assembly functions.
   5  *
   6  * This file is subject to the terms and conditions of the GNU General Public
   7  * License.  See the file "COPYING" in the main directory of this archive
   8  * for more details.
   9  *
  10  * Copyright (C) 2001 - 2007 Tensilica Inc.
  11  *
  12  * Chris Zankel <chris@zankel.net>
  13  */
  14 
  15 
  16 #include <linux/linkage.h>
  17 #include <asm/page.h>
  18 #include <asm/pgtable.h>
  19 #include <asm/asmmacro.h>
  20 #include <asm/cacheasm.h>
  21 #include <asm/tlbflush.h>
  22 
  23 
  24 /*
  25  * clear_page and clear_user_page are the same for non-cache-aliased configs.
  26  *
  27  * clear_page (unsigned long page)
  28  *                    a2
  29  */
  30 
  31 ENTRY(clear_page)
  32 
  33         abi_entry_default
  34 
  35         movi    a3, 0
  36         __loopi a2, a7, PAGE_SIZE, 32
  37         s32i    a3, a2, 0
  38         s32i    a3, a2, 4
  39         s32i    a3, a2, 8
  40         s32i    a3, a2, 12
  41         s32i    a3, a2, 16
  42         s32i    a3, a2, 20
  43         s32i    a3, a2, 24
  44         s32i    a3, a2, 28
  45         __endla a2, a7, 32
  46 
  47         abi_ret_default
  48 
  49 ENDPROC(clear_page)
  50 
  51 /*
  52  * copy_page and copy_user_page are the same for non-cache-aliased configs.
  53  *
  54  * copy_page (void *to, void *from)
  55  *               a2          a3
  56  */
  57 
  58 ENTRY(copy_page)
  59 
  60         abi_entry_default
  61 
  62         __loopi a2, a4, PAGE_SIZE, 32
  63 
  64         l32i    a8, a3, 0
  65         l32i    a9, a3, 4
  66         s32i    a8, a2, 0
  67         s32i    a9, a2, 4
  68 
  69         l32i    a8, a3, 8
  70         l32i    a9, a3, 12
  71         s32i    a8, a2, 8
  72         s32i    a9, a2, 12
  73 
  74         l32i    a8, a3, 16
  75         l32i    a9, a3, 20
  76         s32i    a8, a2, 16
  77         s32i    a9, a2, 20
  78 
  79         l32i    a8, a3, 24
  80         l32i    a9, a3, 28
  81         s32i    a8, a2, 24
  82         s32i    a9, a2, 28
  83 
  84         addi    a2, a2, 32
  85         addi    a3, a3, 32
  86 
  87         __endl  a2, a4
  88 
  89         abi_ret_default
  90 
  91 ENDPROC(copy_page)
  92 
  93 #ifdef CONFIG_MMU
  94 /*
  95  * If we have to deal with cache aliasing, we use temporary memory mappings
  96  * to ensure that the source and destination pages have the same color as
  97  * the virtual address. We use way 0 and 1 for temporary mappings in such cases.
  98  *
  99  * The temporary DTLB entries shouldn't be flushed by interrupts, but are
 100  * flushed by preemptive task switches. Special code in the 
 101  * fast_second_level_miss handler re-established the temporary mapping. 
 102  * It requires that the PPNs for the destination and source addresses are
 103  * in a6, and a7, respectively.
 104  */
 105 
 106 /* TLB miss exceptions are treated special in the following region */
 107 
 108 ENTRY(__tlbtemp_mapping_start)
 109 
 110 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
 111 
 112 /*
 113  * clear_page_alias(void *addr, unsigned long paddr)
 114  *                     a2              a3
 115  */
 116 
 117 ENTRY(clear_page_alias)
 118 
 119         abi_entry_default
 120 
 121         /* Skip setting up a temporary DTLB if not aliased low page. */
 122 
 123         movi    a5, PAGE_OFFSET
 124         movi    a6, 0
 125         beqz    a3, 1f
 126 
 127         /* Setup a temporary DTLB for the addr. */
 128 
 129         addi    a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
 130         mov     a4, a2
 131         wdtlb   a6, a2
 132         dsync
 133 
 134 1:      movi    a3, 0
 135         __loopi a2, a7, PAGE_SIZE, 32
 136         s32i    a3, a2, 0
 137         s32i    a3, a2, 4
 138         s32i    a3, a2, 8
 139         s32i    a3, a2, 12
 140         s32i    a3, a2, 16
 141         s32i    a3, a2, 20
 142         s32i    a3, a2, 24
 143         s32i    a3, a2, 28
 144         __endla a2, a7, 32
 145 
 146         bnez    a6, 1f
 147         abi_ret_default
 148 
 149         /* We need to invalidate the temporary idtlb entry, if any. */
 150 
 151 1:      idtlb   a4
 152         dsync
 153 
 154         abi_ret_default
 155 
 156 ENDPROC(clear_page_alias)
 157 
 158 /*
 159  * copy_page_alias(void *to, void *from,
 160  *                      a2        a3
 161  *                 unsigned long to_paddr, unsigned long from_paddr)
 162  *                               a4                      a5
 163  */
 164 
 165 ENTRY(copy_page_alias)
 166 
 167         abi_entry_default
 168 
 169         /* Skip setting up a temporary DTLB for destination if not aliased. */
 170 
 171         movi    a6, 0
 172         movi    a7, 0
 173         beqz    a4, 1f
 174 
 175         /* Setup a temporary DTLB for destination. */
 176 
 177         addi    a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
 178         wdtlb   a6, a2
 179         dsync
 180 
 181         /* Skip setting up a temporary DTLB for source if not aliased. */
 182 
 183 1:      beqz    a5, 1f
 184 
 185         /* Setup a temporary DTLB for source. */
 186 
 187         addi    a7, a5, PAGE_KERNEL
 188         addi    a8, a3, 1                               # way1
 189 
 190         wdtlb   a7, a8
 191         dsync
 192 
 193 1:      __loopi a2, a4, PAGE_SIZE, 32
 194 
 195         l32i    a8, a3, 0
 196         l32i    a9, a3, 4
 197         s32i    a8, a2, 0
 198         s32i    a9, a2, 4
 199 
 200         l32i    a8, a3, 8
 201         l32i    a9, a3, 12
 202         s32i    a8, a2, 8
 203         s32i    a9, a2, 12
 204 
 205         l32i    a8, a3, 16
 206         l32i    a9, a3, 20
 207         s32i    a8, a2, 16
 208         s32i    a9, a2, 20
 209 
 210         l32i    a8, a3, 24
 211         l32i    a9, a3, 28
 212         s32i    a8, a2, 24
 213         s32i    a9, a2, 28
 214 
 215         addi    a2, a2, 32
 216         addi    a3, a3, 32
 217 
 218         __endl  a2, a4
 219 
 220         /* We need to invalidate any temporary mapping! */
 221 
 222         bnez    a6, 1f
 223         bnez    a7, 2f
 224         abi_ret_default
 225 
 226 1:      addi    a2, a2, -PAGE_SIZE
 227         idtlb   a2
 228         dsync
 229         bnez    a7, 2f
 230         abi_ret_default
 231 
 232 2:      addi    a3, a3, -PAGE_SIZE+1
 233         idtlb   a3
 234         dsync
 235 
 236         abi_ret_default
 237 
 238 ENDPROC(copy_page_alias)
 239 
 240 #endif
 241 
 242 #if (DCACHE_WAY_SIZE > PAGE_SIZE)
 243 
 244 /*
 245  * void __flush_invalidate_dcache_page_alias (addr, phys)
 246  *                                             a2    a3
 247  */
 248 
 249 ENTRY(__flush_invalidate_dcache_page_alias)
 250 
 251         abi_entry_default
 252 
 253         movi    a7, 0                   # required for exception handler
 254         addi    a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
 255         mov     a4, a2
 256         wdtlb   a6, a2
 257         dsync
 258 
 259         ___flush_invalidate_dcache_page a2 a3
 260 
 261         idtlb   a4
 262         dsync
 263 
 264         abi_ret_default
 265 
 266 ENDPROC(__flush_invalidate_dcache_page_alias)
 267 
 268 /*
 269  * void __invalidate_dcache_page_alias (addr, phys)
 270  *                                       a2    a3
 271  */
 272 
 273 ENTRY(__invalidate_dcache_page_alias)
 274 
 275         abi_entry_default
 276 
 277         movi    a7, 0                   # required for exception handler
 278         addi    a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
 279         mov     a4, a2
 280         wdtlb   a6, a2
 281         dsync
 282 
 283         ___invalidate_dcache_page a2 a3
 284 
 285         idtlb   a4
 286         dsync
 287 
 288         abi_ret_default
 289 
 290 ENDPROC(__invalidate_dcache_page_alias)
 291 #endif
 292 
 293 ENTRY(__tlbtemp_mapping_itlb)
 294 
 295 #if (ICACHE_WAY_SIZE > PAGE_SIZE)
 296         
 297 ENTRY(__invalidate_icache_page_alias)
 298 
 299         abi_entry_default
 300 
 301         addi    a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
 302         mov     a4, a2
 303         witlb   a6, a2
 304         isync
 305 
 306         ___invalidate_icache_page a2 a3
 307 
 308         iitlb   a4
 309         isync
 310         abi_ret_default
 311 
 312 ENDPROC(__invalidate_icache_page_alias)
 313 
 314 #endif
 315 
 316 /* End of special treatment in tlb miss exception */
 317 
 318 ENTRY(__tlbtemp_mapping_end)
 319 
 320 #endif /* CONFIG_MMU
 321 
 322 /*
 323  * void __invalidate_icache_page(ulong start)
 324  */
 325 
 326 ENTRY(__invalidate_icache_page)
 327 
 328         abi_entry_default
 329 
 330         ___invalidate_icache_page a2 a3
 331         isync
 332 
 333         abi_ret_default
 334 
 335 ENDPROC(__invalidate_icache_page)
 336 
 337 /*
 338  * void __invalidate_dcache_page(ulong start)
 339  */
 340 
 341 ENTRY(__invalidate_dcache_page)
 342 
 343         abi_entry_default
 344 
 345         ___invalidate_dcache_page a2 a3
 346         dsync
 347 
 348         abi_ret_default
 349 
 350 ENDPROC(__invalidate_dcache_page)
 351 
 352 /*
 353  * void __flush_invalidate_dcache_page(ulong start)
 354  */
 355 
 356 ENTRY(__flush_invalidate_dcache_page)
 357 
 358         abi_entry_default
 359 
 360         ___flush_invalidate_dcache_page a2 a3
 361 
 362         dsync
 363         abi_ret_default
 364 
 365 ENDPROC(__flush_invalidate_dcache_page)
 366 
 367 /*
 368  * void __flush_dcache_page(ulong start)
 369  */
 370 
 371 ENTRY(__flush_dcache_page)
 372 
 373         abi_entry_default
 374 
 375         ___flush_dcache_page a2 a3
 376 
 377         dsync
 378         abi_ret_default
 379 
 380 ENDPROC(__flush_dcache_page)
 381 
 382 /*
 383  * void __invalidate_icache_range(ulong start, ulong size)
 384  */
 385 
 386 ENTRY(__invalidate_icache_range)
 387 
 388         abi_entry_default
 389 
 390         ___invalidate_icache_range a2 a3 a4
 391         isync
 392 
 393         abi_ret_default
 394 
 395 ENDPROC(__invalidate_icache_range)
 396 
 397 /*
 398  * void __flush_invalidate_dcache_range(ulong start, ulong size)
 399  */
 400 
 401 ENTRY(__flush_invalidate_dcache_range)
 402 
 403         abi_entry_default
 404 
 405         ___flush_invalidate_dcache_range a2 a3 a4
 406         dsync
 407 
 408         abi_ret_default
 409 
 410 ENDPROC(__flush_invalidate_dcache_range)
 411 
 412 /*
 413  * void _flush_dcache_range(ulong start, ulong size)
 414  */
 415 
 416 ENTRY(__flush_dcache_range)
 417 
 418         abi_entry_default
 419 
 420         ___flush_dcache_range a2 a3 a4
 421         dsync
 422 
 423         abi_ret_default
 424 
 425 ENDPROC(__flush_dcache_range)
 426 
 427 /*
 428  * void _invalidate_dcache_range(ulong start, ulong size)
 429  */
 430 
 431 ENTRY(__invalidate_dcache_range)
 432 
 433         abi_entry_default
 434 
 435         ___invalidate_dcache_range a2 a3 a4
 436 
 437         abi_ret_default
 438 
 439 ENDPROC(__invalidate_dcache_range)
 440 
 441 /*
 442  * void _invalidate_icache_all(void)
 443  */
 444 
 445 ENTRY(__invalidate_icache_all)
 446 
 447         abi_entry_default
 448 
 449         ___invalidate_icache_all a2 a3
 450         isync
 451 
 452         abi_ret_default
 453 
 454 ENDPROC(__invalidate_icache_all)
 455 
 456 /*
 457  * void _flush_invalidate_dcache_all(void)
 458  */
 459 
 460 ENTRY(__flush_invalidate_dcache_all)
 461 
 462         abi_entry_default
 463 
 464         ___flush_invalidate_dcache_all a2 a3
 465         dsync
 466 
 467         abi_ret_default
 468 
 469 ENDPROC(__flush_invalidate_dcache_all)
 470 
 471 /*
 472  * void _invalidate_dcache_all(void)
 473  */
 474 
 475 ENTRY(__invalidate_dcache_all)
 476 
 477         abi_entry_default
 478 
 479         ___invalidate_dcache_all a2 a3
 480         dsync
 481 
 482         abi_ret_default
 483 
 484 ENDPROC(__invalidate_dcache_all)

/* [<][>][^][v][top][bottom][index][help] */