diff options
author | Stuart Menefy <stuart.menefy@st.com> | 2007-11-30 17:59:55 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-01-28 13:18:59 +0900 |
commit | 2adb4e10092ee1719539bcfe397b96dbdc863e2e (patch) | |
tree | 58bac034f7ab907b5159be0468eefcd201937b66 | |
parent | d02b08f6e8b184ffef349e395210a5e82ff4f4bc (diff) |
sh: Populate swapper_pg_dir with fixmap range.
This saves us from having to use kmalloc() for the fixmap entries,
which is needed early for the uncached fixmap.
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/mm/init.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 094225e0d722..2918c6b14659 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -130,6 +130,37 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } + +void __init page_table_range_init(unsigned long start, unsigned long end, + pgd_t *pgd_base) +{ + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + int pgd_idx; + unsigned long vaddr; + + vaddr = start & PMD_MASK; + end = (end + PMD_SIZE - 1) & PMD_MASK; + pgd_idx = pgd_index(vaddr); + pgd = pgd_base + pgd_idx; + + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { + BUG_ON(pgd_none(*pgd)); + pud = pud_offset(pgd, 0); + BUG_ON(pud_none(*pud)); + pmd = pmd_offset(pud, 0); + + if (!pmd_present(*pmd)) { + pte_t *pte_table; + pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE); + memset(pte_table, 0, PAGE_SIZE); + pmd_populate_kernel(&init_mm, pmd, pte_table); + } + + vaddr += PMD_SIZE; + } +} #endif /* CONFIG_MMU */ /* @@ -149,6 +180,11 @@ void __init paging_init(void) * check for a null value. */ set_TTB(swapper_pg_dir); + /* Populate the relevant portions of swapper_pg_dir so that + * we can use the fixmap entries without calling kmalloc. + * pte's will be filled in by __set_fixmap(). */ + page_table_range_init(FIXADDR_START, FIXADDR_TOP, swapper_pg_dir); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); for_each_online_node(nid) { |