mmu.c (068a17a5805dfbca4bbf03e664ca6b19709cc7a8) | mmu.c (132233a759580f5ce9b1bfaac9073e47d03c460d) |
---|---|
1/* 2 * Based on arch/arm/mm/mmu.c 3 * 4 * Copyright (C) 1995-2005 Russell King 5 * Copyright (C) 2012 ARM Ltd. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 102 unchanged lines hidden (view full) --- 111static void alloc_init_pte(pmd_t *pmd, unsigned long addr, 112 unsigned long end, unsigned long pfn, 113 pgprot_t prot, 114 phys_addr_t (*pgtable_alloc)(void)) 115{ 116 pte_t *pte; 117 118 if (pmd_none(*pmd) || pmd_sect(*pmd)) { | 1/* 2 * Based on arch/arm/mm/mmu.c 3 * 4 * Copyright (C) 1995-2005 Russell King 5 * Copyright (C) 2012 ARM Ltd. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as --- 102 unchanged lines hidden (view full) --- 111static void alloc_init_pte(pmd_t *pmd, unsigned long addr, 112 unsigned long end, unsigned long pfn, 113 pgprot_t prot, 114 phys_addr_t (*pgtable_alloc)(void)) 115{ 116 pte_t *pte; 117 118 if (pmd_none(*pmd) || pmd_sect(*pmd)) { |
119 phys_addr_t pte_phys = pgtable_alloc(); | 119 phys_addr_t pte_phys; 120 BUG_ON(!pgtable_alloc); 121 pte_phys = pgtable_alloc(); |
120 pte = pte_set_fixmap(pte_phys); 121 if (pmd_sect(*pmd)) 122 split_pmd(pmd, pte); 123 __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); 124 flush_tlb_all(); 125 pte_clear_fixmap(); 126 } 127 BUG_ON(pmd_bad(*pmd)); --- 25 unchanged lines hidden (view full) --- 153{ 154 pmd_t *pmd; 155 unsigned long next; 156 157 /* 158 * Check for initial section mappings in the pgd/pud and remove them. 159 */ 160 if (pud_none(*pud) || pud_sect(*pud)) { | 122 pte = pte_set_fixmap(pte_phys); 123 if (pmd_sect(*pmd)) 124 split_pmd(pmd, pte); 125 __pmd_populate(pmd, pte_phys, PMD_TYPE_TABLE); 126 flush_tlb_all(); 127 pte_clear_fixmap(); 128 } 129 BUG_ON(pmd_bad(*pmd)); --- 25 unchanged lines hidden (view full) --- 155{ 156 pmd_t *pmd; 157 unsigned long next; 158 159 /* 160 * Check for initial section mappings in the pgd/pud and remove them. 161 */ 162 if (pud_none(*pud) || pud_sect(*pud)) { |
161 phys_addr_t pmd_phys = pgtable_alloc(); | 163 phys_addr_t pmd_phys; 164 BUG_ON(!pgtable_alloc); 165 pmd_phys = pgtable_alloc(); |
162 pmd = pmd_set_fixmap(pmd_phys); 163 if (pud_sect(*pud)) { 164 /* 165 * need to have the 1G of mappings continue to be 166 * present 167 */ 168 split_pud(pud, pmd); 169 } --- 48 unchanged lines hidden (view full) --- 218static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, 219 phys_addr_t phys, pgprot_t prot, 220 phys_addr_t (*pgtable_alloc)(void)) 221{ 222 pud_t *pud; 223 unsigned long next; 224 225 if (pgd_none(*pgd)) { | 166 pmd = pmd_set_fixmap(pmd_phys); 167 if (pud_sect(*pud)) { 168 /* 169 * need to have the 1G of mappings continue to be 170 * present 171 */ 172 split_pud(pud, pmd); 173 } --- 48 unchanged lines hidden (view full) --- 222static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, 223 phys_addr_t phys, pgprot_t prot, 224 phys_addr_t (*pgtable_alloc)(void)) 225{ 226 pud_t *pud; 227 unsigned long next; 228 229 if (pgd_none(*pgd)) { |
226 phys_addr_t pud_phys = pgtable_alloc(); | 230 phys_addr_t pud_phys; 231 BUG_ON(!pgtable_alloc); 232 pud_phys = pgtable_alloc(); |
227 __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE); 228 } 229 BUG_ON(pgd_bad(*pgd)); 230 231 pud = pud_set_fixmap_offset(pgd, addr); 232 do { 233 next = pud_addr_end(addr, end); 234 --- 72 unchanged lines hidden (view full) --- 307static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, 308 unsigned long virt, phys_addr_t size, 309 pgprot_t prot, 310 phys_addr_t (*alloc)(void)) 311{ 312 init_pgd(pgd_offset_raw(pgdir, virt), phys, virt, size, prot, alloc); 313} 314 | 233 __pgd_populate(pgd, pud_phys, PUD_TYPE_TABLE); 234 } 235 BUG_ON(pgd_bad(*pgd)); 236 237 pud = pud_set_fixmap_offset(pgd, addr); 238 do { 239 next = pud_addr_end(addr, end); 240 --- 72 unchanged lines hidden (view full) --- 313static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, 314 unsigned long virt, phys_addr_t size, 315 pgprot_t prot, 316 phys_addr_t (*alloc)(void)) 317{ 318 init_pgd(pgd_offset_raw(pgdir, virt), phys, virt, size, prot, alloc); 319} 320 |
315static void __init create_mapping(phys_addr_t phys, unsigned long virt, | 321/* 322 * This function can only be used to modify existing table entries, 323 * without allocating new levels of table. Note that this permits the 324 * creation of new section or page entries. 325 */ 326static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, |
316 phys_addr_t size, pgprot_t prot) 317{ 318 if (virt < VMALLOC_START) { 319 pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", 320 &phys, virt); 321 return; 322 } 323 __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, | 327 phys_addr_t size, pgprot_t prot) 328{ 329 if (virt < VMALLOC_START) { 330 pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", 331 &phys, virt); 332 return; 333 } 334 __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, |
324 early_pgtable_alloc); | 335 NULL); |
325} 326 327void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, 328 unsigned long virt, phys_addr_t size, 329 pgprot_t prot) 330{ 331 __create_pgd_mapping(mm->pgd, phys, virt, size, prot, 332 late_pgtable_alloc); --- 342 unchanged lines hidden (view full) --- 675 */ 676 BUILD_BUG_ON(MIN_FDT_ALIGN < 8); 677 if (!dt_phys || dt_phys % MIN_FDT_ALIGN) 678 return NULL; 679 680 /* 681 * Make sure that the FDT region can be mapped without the need to 682 * allocate additional translation table pages, so that it is safe | 336} 337 338void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, 339 unsigned long virt, phys_addr_t size, 340 pgprot_t prot) 341{ 342 __create_pgd_mapping(mm->pgd, phys, virt, size, prot, 343 late_pgtable_alloc); --- 342 unchanged lines hidden (view full) --- 686 */ 687 BUILD_BUG_ON(MIN_FDT_ALIGN < 8); 688 if (!dt_phys || dt_phys % MIN_FDT_ALIGN) 689 return NULL; 690 691 /* 692 * Make sure that the FDT region can be mapped without the need to 693 * allocate additional translation table pages, so that it is safe |
683 * to call create_mapping() this early. | 694 * to call create_mapping_noalloc() this early. |
684 * 685 * On 64k pages, the FDT will be mapped using PTEs, so we need to 686 * be in the same PMD as the rest of the fixmap. 687 * On 4k pages, we'll use section mappings for the FDT so we only 688 * have to be in the same PUD. 689 */ 690 BUILD_BUG_ON(dt_virt_base % SZ_2M); 691 692 BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT != 693 __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT); 694 695 offset = dt_phys % SWAPPER_BLOCK_SIZE; 696 dt_virt = (void *)dt_virt_base + offset; 697 698 /* map the first chunk so we can read the size from the header */ | 695 * 696 * On 64k pages, the FDT will be mapped using PTEs, so we need to 697 * be in the same PMD as the rest of the fixmap. 698 * On 4k pages, we'll use section mappings for the FDT so we only 699 * have to be in the same PUD. 700 */ 701 BUILD_BUG_ON(dt_virt_base % SZ_2M); 702 703 BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT != 704 __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT); 705 706 offset = dt_phys % SWAPPER_BLOCK_SIZE; 707 dt_virt = (void *)dt_virt_base + offset; 708 709 /* map the first chunk so we can read the size from the header */ |
699 create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, 700 SWAPPER_BLOCK_SIZE, prot); | 710 create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE), 711 dt_virt_base, SWAPPER_BLOCK_SIZE, prot); |
701 702 if (fdt_check_header(dt_virt) != 0) 703 return NULL; 704 705 size = fdt_totalsize(dt_virt); 706 if (size > MAX_FDT_SIZE) 707 return NULL; 708 709 if (offset + size > SWAPPER_BLOCK_SIZE) | 712 713 if (fdt_check_header(dt_virt) != 0) 714 return NULL; 715 716 size = fdt_totalsize(dt_virt); 717 if (size > MAX_FDT_SIZE) 718 return NULL; 719 720 if (offset + size > SWAPPER_BLOCK_SIZE) |
710 create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, | 721 create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base, |
711 round_up(offset + size, SWAPPER_BLOCK_SIZE), prot); 712 713 memblock_reserve(dt_phys, size); 714 715 return dt_virt; 716} | 722 round_up(offset + size, SWAPPER_BLOCK_SIZE), prot); 723 724 memblock_reserve(dt_phys, size); 725 726 return dt_virt; 727} |