Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af3813d6 authored by Russell King's avatar Russell King
Browse files

ARM: pgtable: use conventional page table code for identity mappings



Remove some knowledge of our 2-level page table layout from the
identity mapping code - we assume that a step size of PGDIR_SIZE will
allow us to step over all entries.  While this is true today, it won't
be true in the near future.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 614dd058
Loading
Loading
Loading
Loading
+31 −15
Original line number Original line Diff line number Diff line
@@ -4,33 +4,49 @@
#include <asm/pgalloc.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>


static void idmap_add_pmd(pgd_t *pgd, unsigned long addr, unsigned long end,
	unsigned long prot)
{
	pmd_t *pmd = pmd_offset(pgd, addr);

	addr = (addr & PMD_MASK) | prot;
	pmd[0] = __pmd(addr);
	addr += SECTION_SIZE;
	pmd[1] = __pmd(addr);
	flush_pmd_entry(pmd);
}

void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
{
{
	unsigned long prot;
	unsigned long prot, next;


	prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
	prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
		prot |= PMD_BIT4;
		prot |= PMD_BIT4;


	for (addr &= PGDIR_MASK; addr < end;) {
	pgd += pgd_index(addr);
		pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr);
	do {
		pmd[0] = __pmd(addr | prot);
		next = pgd_addr_end(addr, end);
		addr += SECTION_SIZE;
		idmap_add_pmd(pgd, addr, next, prot);
		pmd[1] = __pmd(addr | prot);
	} while (pgd++, addr = next, addr != end);
		addr += SECTION_SIZE;
		flush_pmd_entry(pmd);
	}
}
}


#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
static void idmap_del_pmd(pgd_t *pgd, unsigned long addr, unsigned long end)
{
{
	for (addr &= PGDIR_MASK; addr < end; addr += PGDIR_SIZE) {
	pmd_t *pmd = pmd_offset(pgd, addr);
		pmd_t *pmd = pmd_offset(pgd + pgd_index(addr), addr);
	pmd_clear(pmd);
		pmd[0] = __pmd(0);
		pmd[1] = __pmd(0);
		clean_pmd_entry(pmd);
}
}

void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
{
	unsigned long next;

	pgd += pgd_index(addr);
	do {
		next = pgd_addr_end(addr, end);
		idmap_del_pmd(pgd, addr, next);
	} while (pgd++, addr = next, addr != end);
}
}
#endif
#endif