diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/mach/map.h | 1 | ||||
-rw-r--r-- | arch/arm/mm/mmu.c | 23 |
2 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h index 39d949b63e80..58cf91f38e6f 100644 --- a/arch/arm/include/asm/mach/map.h +++ b/arch/arm/include/asm/mach/map.h @@ -26,6 +26,7 @@ struct map_desc { #define MT_HIGH_VECTORS 8 #define MT_MEMORY 9 #define MT_ROM 10 +#define MT_MEMORY_NONCACHED 11 #ifdef CONFIG_MMU extern void iotable_init(struct map_desc *, int); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9b36c5cb5e9f..aa424e1da8a1 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -243,6 +243,10 @@ static struct mem_type mem_types[] = { .prot_sect = PMD_TYPE_SECT, .domain = DOMAIN_KERNEL, }, + [MT_MEMORY_NONCACHED] = { + .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, + .domain = DOMAIN_KERNEL, + }, }; const struct mem_type *get_mem_type(unsigned int type) @@ -406,9 +410,28 @@ static void __init build_mem_type_table(void) kern_pgprot |= L_PTE_SHARED; vecs_pgprot |= L_PTE_SHARED; mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; #endif } + /* + * Non-cacheable Normal - intended for memory areas that must + * not cause dirty cache line writebacks when used + */ + if (cpu_arch >= CPU_ARCH_ARMv6) { + if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { + /* Non-cacheable Normal is XCB = 001 */ + mem_types[MT_MEMORY_NONCACHED].prot_sect |= + PMD_SECT_BUFFERED; + } else { + /* For both ARMv6 and non-TEX-remapping ARMv7 */ + mem_types[MT_MEMORY_NONCACHED].prot_sect |= + PMD_SECT_TEX(1); + } + } else { + mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE; + } + for (i = 0; i < 16; i++) { unsigned long v = pgprot_val(protection_map[i]); protection_map[i] = __pgprot(v | user_pgprot); |