diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-02-04 02:17:09 +0400 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-04-06 21:29:21 +0400 |
commit | 65559100655c6ed6ce2e17ffc8d4f3852bc2858a (patch) | |
tree | 71cf7391732414bce793d0ad7c5d39a03f60e76f /arch/xtensa/mm/mmu.c | |
parent | 04c6b3e2b5e5c1dbd99ad7620033eafd05ff4c26 (diff) | |
download | op-kernel-dev-65559100655c6ed6ce2e17ffc8d4f3852bc2858a.zip op-kernel-dev-65559100655c6ed6ce2e17ffc8d4f3852bc2858a.tar.gz |
xtensa: add HIGHMEM support
Introduce fixmap area just below the vmalloc region. Use it for atomic
mapping of high memory pages.
High memory on cores with cache aliasing is not supported and is still
to be implemented. Fail build for such configurations for now.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa/mm/mmu.c')
-rw-r--r-- | arch/xtensa/mm/mmu.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 861203e..3429b48 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c @@ -3,6 +3,7 @@ * * Extracted from init.c */ +#include <linux/bootmem.h> #include <linux/percpu.h> #include <linux/init.h> #include <linux/string.h> @@ -16,9 +17,44 @@ #include <asm/initialize_mmu.h> #include <asm/io.h> +#if defined(CONFIG_HIGHMEM) +static void * __init init_pmd(unsigned long vaddr) +{ + pgd_t *pgd = pgd_offset_k(vaddr); + pmd_t *pmd = pmd_offset(pgd, vaddr); + + if (pmd_none(*pmd)) { + unsigned i; + pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); + + for (i = 0; i < 1024; i++) + pte_clear(NULL, 0, pte + i); + + set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); + BUG_ON(pte != pte_offset_kernel(pmd, 0)); + pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", + __func__, vaddr, pmd, pte); + return pte; + } else { + return pte_offset_kernel(pmd, 0); + } +} + +static void __init fixedrange_init(void) +{ + BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); + init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); +} +#endif + void __init paging_init(void) { memset(swapper_pg_dir, 0, PAGE_SIZE); +#ifdef CONFIG_HIGHMEM + fixedrange_init(); + pkmap_page_table = init_pmd(PKMAP_BASE); + kmap_init(); +#endif } /* |