summaryrefslogtreecommitdiffstats
path: root/arch/microblaze/mm/init.c
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2011-12-15 15:02:37 +0100
committerMichal Simek <monstr@monstr.eu>2012-03-23 09:28:13 +0100
commit2f2f371f8907d169650f594850ca6096e2f73b77 (patch)
tree053824b8bd18fdd71119510be569fa0ff7ec0c29 /arch/microblaze/mm/init.c
parentbaab8a828d2d6b5b073c192ebe777514bbf3c831 (diff)
downloadlinux-2f2f371f8907d169650f594850ca6096e2f73b77.tar.bz2
microblaze: Highmem support
The first highmem implementation. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/mm/init.c')
-rw-r--r--arch/microblaze/mm/init.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index 43b3f604bafe..95297b13dd9e 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -49,6 +49,53 @@ unsigned long memory_size;
EXPORT_SYMBOL(memory_size);
unsigned long lowmem_size;
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+EXPORT_SYMBOL(kmap_pte);
+pgprot_t kmap_prot;
+EXPORT_SYMBOL(kmap_prot);
+
+static inline pte_t *virt_to_kpte(unsigned long vaddr)
+{
+ return pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr),
+ vaddr), vaddr);
+}
+
+static void __init highmem_init(void)
+{
+ pr_debug("%x\n", (u32)PKMAP_BASE);
+ map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+ pkmap_page_table = virt_to_kpte(PKMAP_BASE);
+
+ kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
+ kmap_prot = PAGE_KERNEL;
+}
+
+static unsigned long highmem_setup(void)
+{
+ unsigned long pfn;
+ unsigned long reservedpages = 0;
+
+ for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) {
+ struct page *page = pfn_to_page(pfn);
+
+ /* FIXME not sure about */
+ if (memblock_is_reserved(pfn << PAGE_SHIFT))
+ continue;
+ ClearPageReserved(page);
+ init_page_count(page);
+ __free_page(page);
+ totalhigh_pages++;
+ reservedpages++;
+ }
+ totalram_pages += totalhigh_pages;
+ printk(KERN_INFO "High memory: %luk\n",
+ totalhigh_pages << (PAGE_SHIFT-10));
+
+ return reservedpages;
+}
+#endif /* CONFIG_HIGHMEM */
+
/*
* paging_init() sets up the page tables - in fact we've already done this.
*/
@@ -66,7 +113,14 @@ static void __init paging_init(void)
/* Clean every zones */
memset(zones_size, 0, sizeof(zones_size));
+#ifdef CONFIG_HIGHMEM
+ highmem_init();
+
+ zones_size[ZONE_DMA] = max_low_pfn;
+ zones_size[ZONE_HIGHMEM] = max_pfn;
+#else
zones_size[ZONE_DMA] = max_pfn;
+#endif
/* We don't have holes in memory map */
free_area_init_nodes(zones_size);
@@ -241,6 +295,10 @@ void __init mem_init(void)
}
}
+#ifdef CONFIG_HIGHMEM
+ reservedpages -= highmem_setup();
+#endif
+
codesize = (unsigned long)&_sdata - (unsigned long)&_stext;
datasize = (unsigned long)&_edata - (unsigned long)&_sdata;
initsize = (unsigned long)&__init_end - (unsigned long)&__init_begin;
@@ -259,6 +317,10 @@ void __init mem_init(void)
#ifdef CONFIG_MMU
pr_info("Kernel virtual memory layout:\n");
pr_info(" * 0x%08lx..0x%08lx : fixmap\n", FIXADDR_START, FIXADDR_TOP);
+#ifdef CONFIG_HIGHMEM
+ pr_info(" * 0x%08lx..0x%08lx : highmem PTEs\n",
+ PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
+#endif /* CONFIG_HIGHMEM */
pr_info(" * 0x%08lx..0x%08lx : early ioremap\n",
ioremap_bot, ioremap_base);
pr_info(" * 0x%08lx..0x%08lx : vmalloc & ioremap\n",
@@ -346,7 +408,9 @@ asmlinkage void __init mmu_init(void)
if (lowmem_size > CONFIG_LOWMEM_SIZE) {
lowmem_size = CONFIG_LOWMEM_SIZE;
+#ifndef CONFIG_HIGHMEM
memory_size = lowmem_size;
+#endif
}
mm_cmdline_setup(); /* FIXME parse args from command line - not used */
@@ -375,7 +439,11 @@ asmlinkage void __init mmu_init(void)
mapin_ram();
/* Extend vmalloc and ioremap area as big as possible */
+#ifdef CONFIG_HIGHMEM
+ ioremap_base = ioremap_bot = PKMAP_BASE;
+#else
ioremap_base = ioremap_bot = FIXADDR_START;
+#endif
/* Initialize the context management stuff */
mmu_context_init();