summaryrefslogtreecommitdiffstats
path: root/arch/xtensa/mm/mmu.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-02-04 02:17:09 +0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-04-06 21:29:21 +0400
commit65559100655c6ed6ce2e17ffc8d4f3852bc2858a (patch)
tree71cf7391732414bce793d0ad7c5d39a03f60e76f /arch/xtensa/mm/mmu.c
parent04c6b3e2b5e5c1dbd99ad7620033eafd05ff4c26 (diff)
downloadop-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.c36
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
}
/*
OpenPOWER on IntegriCloud