1 #include <linux/kernel.h>
3 #include <asm/cputype.h>
5 #include <asm/pgalloc.h>
6 #include <asm/pgtable.h>
7 #include <asm/sections.h>
11 static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
14 pmd_t *pmd = pmd_offset(pud, addr);
16 addr = (addr & PMD_MASK) | prot;
23 static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
26 pud_t *pud = pud_offset(pgd, addr);
30 next = pud_addr_end(addr, end);
31 idmap_add_pmd(pud, addr, next, prot);
32 } while (pud++, addr = next, addr != end);
35 void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
37 unsigned long prot, next;
39 prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
40 if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
43 pgd += pgd_index(addr);
45 next = pgd_addr_end(addr, end);
46 idmap_add_pud(pgd, addr, next, prot);
47 } while (pgd++, addr = next, addr != end);
51 static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
53 pmd_t *pmd = pmd_offset(pud, addr);
57 static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
59 pud_t *pud = pud_offset(pgd, addr);
63 next = pud_addr_end(addr, end);
64 idmap_del_pmd(pud, addr, next);
65 } while (pud++, addr = next, addr != end);
68 void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
72 pgd += pgd_index(addr);
74 next = pgd_addr_end(addr, end);
75 idmap_del_pud(pgd, addr, next);
76 } while (pgd++, addr = next, addr != end);
80 extern char __idmap_text_start[], __idmap_text_end[];
82 static int __init init_static_idmap(void)
84 phys_addr_t idmap_start, idmap_end;
86 idmap_pgd = pgd_alloc(&init_mm);
90 /* Add an identity mapping for the physical address of the section. */
91 idmap_start = virt_to_phys((void *)__idmap_text_start);
92 idmap_end = virt_to_phys((void *)__idmap_text_end);
94 pr_info("Setting up static identity map for 0x%llx - 0x%llx\n",
95 (long long)idmap_start, (long long)idmap_end);
96 identity_mapping_add(idmap_pgd, idmap_start, idmap_end);
100 arch_initcall(init_static_idmap);
103 * In order to soft-boot, we need to switch to a 1:1 mapping for the
104 * cpu_reset functions. This will then ensure that we have predictable
105 * results when turning off the mmu.
107 void setup_mm_for_reboot(char mode)
109 /* Clean and invalidate L1. */
112 /* Switch to the identity mapping. */
113 cpu_switch_mm(idmap_pgd, &init_mm);
116 local_flush_tlb_all();