aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/mm/mmu.c')
-rw-r--r--arch/arm64/mm/mmu.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a6885d896ab6..f4dd585898c5 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -25,6 +25,7 @@
25#include <linux/nodemask.h> 25#include <linux/nodemask.h>
26#include <linux/memblock.h> 26#include <linux/memblock.h>
27#include <linux/fs.h> 27#include <linux/fs.h>
28#include <linux/io.h>
28 29
29#include <asm/cputype.h> 30#include <asm/cputype.h>
30#include <asm/sections.h> 31#include <asm/sections.h>
@@ -251,6 +252,47 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
251 } while (pgd++, addr = next, addr != end); 252 } while (pgd++, addr = next, addr != end);
252} 253}
253 254
255#ifdef CONFIG_EARLY_PRINTK
256/*
257 * Create an early I/O mapping using the pgd/pmd entries already populated
258 * in head.S as this function is called too early to allocated any memory. The
259 * mapping size is 2MB with 4KB pages or 64KB or 64KB pages.
260 */
261void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt)
262{
263 unsigned long size, mask;
264 bool page64k = IS_ENABLED(ARM64_64K_PAGES);
265 pgd_t *pgd;
266 pud_t *pud;
267 pmd_t *pmd;
268 pte_t *pte;
269
270 /*
271 * No early pte entries with !ARM64_64K_PAGES configuration, so using
272 * sections (pmd).
273 */
274 size = page64k ? PAGE_SIZE : SECTION_SIZE;
275 mask = ~(size - 1);
276
277 pgd = pgd_offset_k(virt);
278 pud = pud_offset(pgd, virt);
279 if (pud_none(*pud))
280 return NULL;
281 pmd = pmd_offset(pud, virt);
282
283 if (page64k) {
284 if (pmd_none(*pmd))
285 return NULL;
286 pte = pte_offset_kernel(pmd, virt);
287 set_pte(pte, __pte((phys & mask) | PROT_DEVICE_nGnRE));
288 } else {
289 set_pmd(pmd, __pmd((phys & mask) | PROT_SECT_DEVICE_nGnRE));
290 }
291
292 return (void __iomem *)((virt & mask) + (phys & ~mask));
293}
294#endif
295
254static void __init map_mem(void) 296static void __init map_mem(void)
255{ 297{
256 struct memblock_region *reg; 298 struct memblock_region *reg;