aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mm-armv.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/mm-armv.c')
-rw-r--r--arch/arm/mm/mm-armv.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index fb5b40289de2..9e50127be635 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -354,7 +354,7 @@ void __init build_mem_type_table(void)
354{ 354{
355 struct cachepolicy *cp; 355 struct cachepolicy *cp;
356 unsigned int cr = get_cr(); 356 unsigned int cr = get_cr();
357 unsigned int user_pgprot; 357 unsigned int user_pgprot, kern_pgprot;
358 int cpu_arch = cpu_architecture(); 358 int cpu_arch = cpu_architecture();
359 int i; 359 int i;
360 360
@@ -381,7 +381,7 @@ void __init build_mem_type_table(void)
381 } 381 }
382 382
383 cp = &cache_policies[cachepolicy]; 383 cp = &cache_policies[cachepolicy];
384 user_pgprot = cp->pte; 384 kern_pgprot = user_pgprot = cp->pte;
385 385
386 /* 386 /*
387 * ARMv6 and above have extended page tables. 387 * ARMv6 and above have extended page tables.
@@ -393,6 +393,7 @@ void __init build_mem_type_table(void)
393 */ 393 */
394 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; 394 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
395 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; 395 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
396
396 /* 397 /*
397 * Mark cache clean areas and XIP ROM read only 398 * Mark cache clean areas and XIP ROM read only
398 * from SVC mode and no access from userspace. 399 * from SVC mode and no access from userspace.
@@ -412,32 +413,47 @@ void __init build_mem_type_table(void)
412 * (iow, non-global) 413 * (iow, non-global)
413 */ 414 */
414 user_pgprot |= L_PTE_ASID; 415 user_pgprot |= L_PTE_ASID;
416
417#ifdef CONFIG_SMP
418 /*
419 * Mark memory with the "shared" attribute for SMP systems
420 */
421 user_pgprot |= L_PTE_SHARED;
422 kern_pgprot |= L_PTE_SHARED;
423 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
424#endif
415 } 425 }
416 426
427 for (i = 0; i < 16; i++) {
428 unsigned long v = pgprot_val(protection_map[i]);
429 v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
430 protection_map[i] = __pgprot(v);
431 }
432
433 mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
434 mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
435
417 if (cpu_arch >= CPU_ARCH_ARMv5) { 436 if (cpu_arch >= CPU_ARCH_ARMv5) {
418 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 437#ifndef CONFIG_SMP
419 mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 438 /*
439 * Only use write-through for non-SMP systems
440 */
441 mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
442 mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
443#endif
420 } else { 444 } else {
421 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
422 mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
423 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); 445 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
424 } 446 }
425 447
448 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
449 L_PTE_DIRTY | L_PTE_WRITE |
450 L_PTE_EXEC | kern_pgprot);
451
426 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; 452 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
427 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; 453 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
428 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; 454 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
429 mem_types[MT_ROM].prot_sect |= cp->pmd; 455 mem_types[MT_ROM].prot_sect |= cp->pmd;
430 456
431 for (i = 0; i < 16; i++) {
432 unsigned long v = pgprot_val(protection_map[i]);
433 v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
434 protection_map[i] = __pgprot(v);
435 }
436
437 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
438 L_PTE_DIRTY | L_PTE_WRITE |
439 L_PTE_EXEC | cp->pte);
440
441 switch (cp->pmd) { 457 switch (cp->pmd) {
442 case PMD_SECT_WT: 458 case PMD_SECT_WT:
443 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; 459 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;