diff options
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r-- | arch/arm/mm/mmu.c | 73 |
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 | } |
746 | early_param("vmalloc", early_vmalloc); | 745 | early_param("vmalloc", early_vmalloc); |
747 | 746 | ||
748 | phys_addr_t lowmem_end_addr; | 747 | static phys_addr_t lowmem_limit __initdata = 0; |
749 | 748 | ||
750 | static void __init sanity_check_meminfo(void) | 749 | static 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) | |||
852 | static inline void prepare_page_table(void) | 852 | static 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 | ||
990 | static 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 | |||
1002 | static void __init map_lowmem(void) | 998 | static 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 | ||
1016 | static 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(); |