diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/fault.c | 6 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 17 | ||||
-rw-r--r-- | arch/arm/mm/proc-v6.S | 22 | ||||
-rw-r--r-- | arch/arm/mm/proc-xscale.S | 136 |
4 files changed, 25 insertions, 156 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 65bfe84b6d67..0b6c4db44e08 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -238,9 +238,9 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
238 | up_read(&mm->mmap_sem); | 238 | up_read(&mm->mmap_sem); |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * Handle the "normal" case first | 241 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR |
242 | */ | 242 | */ |
243 | if (fault > 0) | 243 | if (fault >= VM_FAULT_MINOR) |
244 | return 0; | 244 | return 0; |
245 | 245 | ||
246 | /* | 246 | /* |
@@ -261,7 +261,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
261 | do_exit(SIGKILL); | 261 | do_exit(SIGKILL); |
262 | return 0; | 262 | return 0; |
263 | 263 | ||
264 | case 0: | 264 | case VM_FAULT_SIGBUS: |
265 | /* | 265 | /* |
266 | * We had some memory, but were unable to | 266 | * We had some memory, but were unable to |
267 | * successfully fix up this page fault. | 267 | * successfully fix up this page fault. |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index e33fe4229d05..3c655c54e231 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -383,6 +383,7 @@ static void __init build_mem_type_table(void) | |||
383 | { | 383 | { |
384 | struct cachepolicy *cp; | 384 | struct cachepolicy *cp; |
385 | unsigned int cr = get_cr(); | 385 | unsigned int cr = get_cr(); |
386 | unsigned int user_pgprot; | ||
386 | int cpu_arch = cpu_architecture(); | 387 | int cpu_arch = cpu_architecture(); |
387 | int i; | 388 | int i; |
388 | 389 | ||
@@ -408,6 +409,9 @@ static void __init build_mem_type_table(void) | |||
408 | } | 409 | } |
409 | } | 410 | } |
410 | 411 | ||
412 | cp = &cache_policies[cachepolicy]; | ||
413 | user_pgprot = cp->pte; | ||
414 | |||
411 | /* | 415 | /* |
412 | * ARMv6 and above have extended page tables. | 416 | * ARMv6 and above have extended page tables. |
413 | */ | 417 | */ |
@@ -426,11 +430,18 @@ static void __init build_mem_type_table(void) | |||
426 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 430 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
427 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 431 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
428 | 432 | ||
433 | /* | ||
434 | * Mark the device area as "shared device" | ||
435 | */ | ||
429 | mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; | 436 | mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; |
430 | mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; | 437 | mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; |
431 | } | ||
432 | 438 | ||
433 | cp = &cache_policies[cachepolicy]; | 439 | /* |
440 | * User pages need to be mapped with the ASID | ||
441 | * (iow, non-global) | ||
442 | */ | ||
443 | user_pgprot |= L_PTE_ASID; | ||
444 | } | ||
434 | 445 | ||
435 | if (cpu_arch >= CPU_ARCH_ARMv5) { | 446 | if (cpu_arch >= CPU_ARCH_ARMv5) { |
436 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; | 447 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; |
@@ -448,7 +459,7 @@ static void __init build_mem_type_table(void) | |||
448 | 459 | ||
449 | for (i = 0; i < 16; i++) { | 460 | for (i = 0; i < 16; i++) { |
450 | unsigned long v = pgprot_val(protection_map[i]); | 461 | unsigned long v = pgprot_val(protection_map[i]); |
451 | v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte; | 462 | v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot; |
452 | protection_map[i] = __pgprot(v); | 463 | protection_map[i] = __pgprot(v); |
453 | } | 464 | } |
454 | 465 | ||
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 352db98ee269..3429ddcf65d1 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -111,12 +111,6 @@ ENTRY(cpu_v6_switch_mm) | |||
111 | mcr p15, 0, r1, c13, c0, 1 @ set context ID | 111 | mcr p15, 0, r1, c13, c0, 1 @ set context ID |
112 | mov pc, lr | 112 | mov pc, lr |
113 | 113 | ||
114 | #define nG (1 << 11) | ||
115 | #define APX (1 << 9) | ||
116 | #define AP1 (1 << 5) | ||
117 | #define AP0 (1 << 4) | ||
118 | #define XN (1 << 0) | ||
119 | |||
120 | /* | 114 | /* |
121 | * cpu_v6_set_pte(ptep, pte) | 115 | * cpu_v6_set_pte(ptep, pte) |
122 | * | 116 | * |
@@ -139,24 +133,24 @@ ENTRY(cpu_v6_switch_mm) | |||
139 | ENTRY(cpu_v6_set_pte) | 133 | ENTRY(cpu_v6_set_pte) |
140 | str r1, [r0], #-2048 @ linux version | 134 | str r1, [r0], #-2048 @ linux version |
141 | 135 | ||
142 | bic r2, r1, #0x00000ff0 | 136 | bic r2, r1, #0x000007f0 |
143 | bic r2, r2, #0x00000003 | 137 | bic r2, r2, #0x00000003 |
144 | orr r2, r2, #AP0 | 2 | 138 | orr r2, r2, #PTE_EXT_AP0 | 2 |
145 | 139 | ||
146 | tst r1, #L_PTE_WRITE | 140 | tst r1, #L_PTE_WRITE |
147 | tstne r1, #L_PTE_DIRTY | 141 | tstne r1, #L_PTE_DIRTY |
148 | orreq r2, r2, #APX | 142 | orreq r2, r2, #PTE_EXT_APX |
149 | 143 | ||
150 | tst r1, #L_PTE_USER | 144 | tst r1, #L_PTE_USER |
151 | orrne r2, r2, #AP1 | nG | 145 | orrne r2, r2, #PTE_EXT_AP1 |
152 | tstne r2, #APX | 146 | tstne r2, #PTE_EXT_APX |
153 | bicne r2, r2, #APX | AP0 | 147 | bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0 |
154 | 148 | ||
155 | tst r1, #L_PTE_YOUNG | 149 | tst r1, #L_PTE_YOUNG |
156 | biceq r2, r2, #APX | AP1 | AP0 | 150 | biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK |
157 | 151 | ||
158 | @ tst r1, #L_PTE_EXEC | 152 | @ tst r1, #L_PTE_EXEC |
159 | @ orreq r2, r2, #XN | 153 | @ orreq r2, r2, #PTE_EXT_XN |
160 | 154 | ||
161 | tst r1, #L_PTE_PRESENT | 155 | tst r1, #L_PTE_PRESENT |
162 | moveq r2, #0 | 156 | moveq r2, #0 |
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 2d977b4eeeab..b88de2700146 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S | |||
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area) | |||
370 | bhi 1b | 370 | bhi 1b |
371 | mov pc, lr | 371 | mov pc, lr |
372 | 372 | ||
373 | /* ================================ CACHE LOCKING============================ | ||
374 | * | ||
375 | * The XScale MicroArchitecture implements support for locking entries into | ||
376 | * the data and instruction cache. The following functions implement the core | ||
377 | * low level instructions needed to accomplish the locking. The developer's | ||
378 | * manual states that the code that performs the locking must be in non-cached | ||
379 | * memory. To accomplish this, the code in xscale-cache-lock.c copies the | ||
380 | * following functions from the cache into a non-cached memory region that | ||
381 | * is allocated through consistent_alloc(). | ||
382 | * | ||
383 | */ | ||
384 | .align 5 | ||
385 | /* | ||
386 | * xscale_icache_lock | ||
387 | * | ||
388 | * r0: starting address to lock | ||
389 | * r1: end address to lock | ||
390 | */ | ||
391 | ENTRY(xscale_icache_lock) | ||
392 | |||
393 | iLockLoop: | ||
394 | bic r0, r0, #CACHELINESIZE - 1 | ||
395 | mcr p15, 0, r0, c9, c1, 0 @ lock into cache | ||
396 | cmp r0, r1 @ are we done? | ||
397 | add r0, r0, #CACHELINESIZE @ advance to next cache line | ||
398 | bls iLockLoop | ||
399 | mov pc, lr | ||
400 | |||
401 | /* | ||
402 | * xscale_icache_unlock | ||
403 | */ | ||
404 | ENTRY(xscale_icache_unlock) | ||
405 | mcr p15, 0, r0, c9, c1, 1 @ Unlock icache | ||
406 | mov pc, lr | ||
407 | |||
408 | /* | ||
409 | * xscale_dcache_lock | ||
410 | * | ||
411 | * r0: starting address to lock | ||
412 | * r1: end address to lock | ||
413 | */ | ||
414 | ENTRY(xscale_dcache_lock) | ||
415 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
416 | mov r2, #1 | ||
417 | mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode | ||
418 | cpwait ip @ Wait for completion | ||
419 | |||
420 | mrs r2, cpsr | ||
421 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
422 | dLockLoop: | ||
423 | msr cpsr_c, r3 | ||
424 | mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty | ||
425 | mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line | ||
426 | msr cpsr_c, r2 | ||
427 | ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from | ||
428 | @ location [r0]. Post-increment | ||
429 | @ r3 to next cache line | ||
430 | cmp r0, r1 @ Are we done? | ||
431 | bls dLockLoop | ||
432 | |||
433 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
434 | mov r2, #0 | ||
435 | mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode | ||
436 | cpwait_ret lr, ip | ||
437 | |||
438 | /* | ||
439 | * xscale_dcache_unlock | ||
440 | */ | ||
441 | ENTRY(xscale_dcache_unlock) | ||
442 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
443 | mcr p15, 0, ip, c9, c2, 1 @ Unlock cache | ||
444 | mov pc, lr | ||
445 | |||
446 | /* | ||
447 | * Needed to determine the length of the code that needs to be copied. | ||
448 | */ | ||
449 | .align 5 | ||
450 | ENTRY(xscale_cache_dummy) | ||
451 | mov pc, lr | ||
452 | |||
453 | /* ================================ TLB LOCKING============================== | ||
454 | * | ||
455 | * The XScale MicroArchitecture implements support for locking entries into | ||
456 | * the Instruction and Data TLBs. The following functions provide the | ||
457 | * low level support for supporting these under Linux. xscale-lock.c | ||
458 | * implements some higher level management code. Most of the following | ||
459 | * is taken straight out of the Developer's Manual. | ||
460 | */ | ||
461 | |||
462 | /* | ||
463 | * Lock I-TLB entry | ||
464 | * | ||
465 | * r0: Virtual address to translate and lock | ||
466 | */ | ||
467 | .align 5 | ||
468 | ENTRY(xscale_itlb_lock) | ||
469 | mrs r2, cpsr | ||
470 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
471 | msr cpsr_c, r3 @ Disable interrupts | ||
472 | mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry | ||
473 | mcr p15, 0, r0, c10, c4, 0 @ Translate and lock | ||
474 | msr cpsr_c, r2 @ Restore interrupts | ||
475 | cpwait_ret lr, ip | ||
476 | |||
477 | /* | ||
478 | * Lock D-TLB entry | ||
479 | * | ||
480 | * r0: Virtual address to translate and lock | ||
481 | */ | ||
482 | .align 5 | ||
483 | ENTRY(xscale_dtlb_lock) | ||
484 | mrs r2, cpsr | ||
485 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
486 | msr cpsr_c, r3 @ Disable interrupts | ||
487 | mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry | ||
488 | mcr p15, 0, r0, c10, c8, 0 @ Translate and lock | ||
489 | msr cpsr_c, r2 @ Restore interrupts | ||
490 | cpwait_ret lr, ip | ||
491 | |||
492 | /* | ||
493 | * Unlock all I-TLB entries | ||
494 | */ | ||
495 | .align 5 | ||
496 | ENTRY(xscale_itlb_unlock) | ||
497 | mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB | ||
498 | mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB | ||
499 | cpwait_ret lr, ip | ||
500 | |||
501 | /* | ||
502 | * Unlock all D-TLB entries | ||
503 | */ | ||
504 | ENTRY(xscale_dtlb_unlock) | ||
505 | mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL | ||
506 | mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB | ||
507 | cpwait_ret lr, ip | ||
508 | |||
509 | /* =============================== PageTable ============================== */ | 373 | /* =============================== PageTable ============================== */ |
510 | 374 | ||
511 | #define PTE_CACHE_WRITE_ALLOCATE 0 | 375 | #define PTE_CACHE_WRITE_ALLOCATE 0 |