arm64: add early_ioremap support
Add support for early IO or memory mappings which are needed before the normal ioremap() is usable. This also adds fixmap support for permanent fixed mappings such as that used by the earlyprintk device register region. Signed-off-by: Mark Salter <msalter@redhat.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Borislav Petkov <borislav.petkov@amd.com> Cc: Dave Young <dyoung@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Will Deacon <will.deacon@arm.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
0bf757c73d
commit
bf4b558eba
@@ -260,47 +260,6 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
|
||||
} while (pgd++, addr = next, addr != end);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
/*
|
||||
* Create an early I/O mapping using the pgd/pmd entries already populated
|
||||
* in head.S as this function is called too early to allocated any memory. The
|
||||
* mapping size is 2MB with 4KB pages or 64KB or 64KB pages.
|
||||
*/
|
||||
void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt)
|
||||
{
|
||||
unsigned long size, mask;
|
||||
bool page64k = IS_ENABLED(CONFIG_ARM64_64K_PAGES);
|
||||
pgd_t *pgd;
|
||||
pud_t *pud;
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
|
||||
/*
|
||||
* No early pte entries with !ARM64_64K_PAGES configuration, so using
|
||||
* sections (pmd).
|
||||
*/
|
||||
size = page64k ? PAGE_SIZE : SECTION_SIZE;
|
||||
mask = ~(size - 1);
|
||||
|
||||
pgd = pgd_offset_k(virt);
|
||||
pud = pud_offset(pgd, virt);
|
||||
if (pud_none(*pud))
|
||||
return NULL;
|
||||
pmd = pmd_offset(pud, virt);
|
||||
|
||||
if (page64k) {
|
||||
if (pmd_none(*pmd))
|
||||
return NULL;
|
||||
pte = pte_offset_kernel(pmd, virt);
|
||||
set_pte(pte, __pte((phys & mask) | PROT_DEVICE_nGnRE));
|
||||
} else {
|
||||
set_pmd(pmd, __pmd((phys & mask) | PROT_SECT_DEVICE_nGnRE));
|
||||
}
|
||||
|
||||
return (void __iomem *)((virt & mask) + (phys & ~mask));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __init map_mem(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
|
Reference in New Issue
Block a user