aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r--arch/arm/mm/mmu.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index c32f731d56d3..72ad3e1f56cf 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -14,7 +14,6 @@
14#include <linux/mman.h> 14#include <linux/mman.h>
15#include <linux/nodemask.h> 15#include <linux/nodemask.h>
16#include <linux/memblock.h> 16#include <linux/memblock.h>
17#include <linux/sort.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
19 18
20#include <asm/cputype.h> 19#include <asm/cputype.h>
@@ -265,17 +264,17 @@ static struct mem_type mem_types[] = {
265 .domain = DOMAIN_KERNEL, 264 .domain = DOMAIN_KERNEL,
266 }, 265 },
267 [MT_MEMORY_DTCM] = { 266 [MT_MEMORY_DTCM] = {
268 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | 267 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
269 L_PTE_DIRTY | L_PTE_WRITE, 268 L_PTE_WRITE,
270 .prot_l1 = PMD_TYPE_TABLE, 269 .prot_l1 = PMD_TYPE_TABLE,
271 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, 270 .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
272 .domain = DOMAIN_KERNEL, 271 .domain = DOMAIN_KERNEL,
273 }, 272 },
274 [MT_MEMORY_ITCM] = { 273 [MT_MEMORY_ITCM] = {
275 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | 274 .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
276 L_PTE_USER | L_PTE_EXEC, 275 L_PTE_WRITE | L_PTE_EXEC,
277 .prot_l1 = PMD_TYPE_TABLE, 276 .prot_l1 = PMD_TYPE_TABLE,
278 .domain = DOMAIN_IO, 277 .domain = DOMAIN_KERNEL,
279 }, 278 },
280}; 279};
281 280
@@ -745,13 +744,14 @@ static int __init early_vmalloc(char *arg)
745} 744}
746early_param("vmalloc", early_vmalloc); 745early_param("vmalloc", early_vmalloc);
747 746
748phys_addr_t lowmem_end_addr; 747static phys_addr_t lowmem_limit __initdata = 0;
749 748
750static void __init sanity_check_meminfo(void) 749static void __init sanity_check_meminfo(void)
751{ 750{
752 int i, j, highmem = 0; 751 int i, j, highmem = 0;
753 752
754 lowmem_end_addr = __pa(vmalloc_min - 1) + 1; 753 lowmem_limit = __pa(vmalloc_min - 1) + 1;
754 memblock_set_current_limit(lowmem_limit);
755 755
756 for (i = 0, j = 0; i < meminfo.nr_banks; i++) { 756 for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
757 struct membank *bank = &meminfo.bank[j]; 757 struct membank *bank = &meminfo.bank[j];
@@ -852,6 +852,7 @@ static void __init sanity_check_meminfo(void)
852static inline void prepare_page_table(void) 852static inline void prepare_page_table(void)
853{ 853{
854 unsigned long addr; 854 unsigned long addr;
855 phys_addr_t end;
855 856
856 /* 857 /*
857 * Clear out all the mappings below the kernel image. 858 * Clear out all the mappings below the kernel image.
@@ -867,10 +868,17 @@ static inline void prepare_page_table(void)
867 pmd_clear(pmd_off_k(addr)); 868 pmd_clear(pmd_off_k(addr));
868 869
869 /* 870 /*
871 * Find the end of the first block of lowmem.
872 */
873 end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
874 if (end >= lowmem_limit)
875 end = lowmem_limit;
876
877 /*
870 * Clear out all the kernel space mappings, except for the first 878 * Clear out all the kernel space mappings, except for the first
871 * memory bank, up to the end of the vmalloc region. 879 * memory bank, up to the end of the vmalloc region.
872 */ 880 */
873 for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0])); 881 for (addr = __phys_to_virt(end);
874 addr < VMALLOC_END; addr += PGDIR_SIZE) 882 addr < VMALLOC_END; addr += PGDIR_SIZE)
875 pmd_clear(pmd_off_k(addr)); 883 pmd_clear(pmd_off_k(addr));
876} 884}
@@ -987,37 +995,28 @@ static void __init kmap_init(void)
987#endif 995#endif
988} 996}
989 997
990static inline void map_memory_bank(struct membank *bank)
991{
992 struct map_desc map;
993
994 map.pfn = bank_pfn_start(bank);
995 map.virtual = __phys_to_virt(bank_phys_start(bank));
996 map.length = bank_phys_size(bank);
997 map.type = MT_MEMORY;
998
999 create_mapping(&map);
1000}
1001
1002static void __init map_lowmem(void) 998static void __init map_lowmem(void)
1003{ 999{
1004 struct meminfo *mi = &meminfo; 1000 struct memblock_region *reg;
1005 int i;
1006 1001
1007 /* Map all the lowmem memory banks. */ 1002 /* Map all the lowmem memory banks. */
1008 for (i = 0; i < mi->nr_banks; i++) { 1003 for_each_memblock(memory, reg) {
1009 struct membank *bank = &mi->bank[i]; 1004 phys_addr_t start = reg->base;
1005 phys_addr_t end = start + reg->size;
1006 struct map_desc map;
1007
1008 if (end > lowmem_limit)
1009 end = lowmem_limit;
1010 if (start >= end)
1011 break;
1010 1012
1011 if (!bank->highmem) 1013 map.pfn = __phys_to_pfn(start);
1012 map_memory_bank(bank); 1014 map.virtual = __phys_to_virt(start);
1013 } 1015 map.length = end - start;
1014} 1016 map.type = MT_MEMORY;
1015 1017
1016static int __init meminfo_cmp(const void *_a, const void *_b) 1018 create_mapping(&map);
1017{ 1019 }
1018 const struct membank *a = _a, *b = _b;
1019 long cmp = bank_pfn_start(a) - bank_pfn_start(b);
1020 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
1021} 1020}
1022 1021
1023/* 1022/*
@@ -1028,8 +1027,6 @@ void __init paging_init(struct machine_desc *mdesc)
1028{ 1027{
1029 void *zero_page; 1028 void *zero_page;
1030 1029
1031 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
1032
1033 build_mem_type_table(); 1030 build_mem_type_table();
1034 sanity_check_meminfo(); 1031 sanity_check_meminfo();
1035 prepare_page_table(); 1032 prepare_page_table();