aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-04-23 09:05:20 -0400
committerPaul Mackerras <paulus@samba.org>2008-04-24 06:58:02 -0400
commit2c419bdeca1d958bb02228b5141695f312d8c633 (patch)
tree4553b9bf7b75025c5bbeb25528d97f5338673b0b /arch/powerpc
parent2fd53e02be9a73cc49d69e0ff8860daa7b5bf8ab (diff)
[POWERPC] Port fixmap from x86 and use for kmap_atomic
The fixmap code from x86 allows us to have compile time virtual addresses that we change the physical addresses of at run time. This is useful for applications like kmap_atomic, PCI config that is done via direct memory map, kexec/kdump. We got ride of CONFIG_HIGHMEM_START as we can now determine a more optimal location for PKMAP_BASE based on where the fixmap addresses start and working back from there. Additionally, the kmap code in asm-powerpc/highmem.h always had debug enabled. Moved to using CONFIG_DEBUG_HIGHMEM to determine if we should have the extra debug checking. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig14
-rw-r--r--arch/powerpc/mm/init_32.c8
-rw-r--r--arch/powerpc/mm/mem.c32
-rw-r--r--arch/powerpc/mm/pgtable_32.c23
4 files changed, 49 insertions, 28 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index fdc755a05f70..20f45a8b87e3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -626,20 +626,6 @@ config ADVANCED_OPTIONS
626comment "Default settings for advanced configuration options are used" 626comment "Default settings for advanced configuration options are used"
627 depends on !ADVANCED_OPTIONS 627 depends on !ADVANCED_OPTIONS
628 628
629config HIGHMEM_START_BOOL
630 bool "Set high memory pool address"
631 depends on ADVANCED_OPTIONS && HIGHMEM
632 help
633 This option allows you to set the base address of the kernel virtual
634 area used to map high memory pages. This can be useful in
635 optimizing the layout of kernel virtual memory.
636
637 Say N here unless you know what you are doing.
638
639config HIGHMEM_START
640 hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
641 default "0xfe000000"
642
643config LOWMEM_SIZE_BOOL 629config LOWMEM_SIZE_BOOL
644 bool "Set maximum low memory" 630 bool "Set maximum low memory"
645 depends on ADVANCED_OPTIONS 631 depends on ADVANCED_OPTIONS
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 578750e4ca88..1952b4d3fa7f 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -71,14 +71,6 @@ unsigned long agp_special_page;
71EXPORT_SYMBOL(agp_special_page); 71EXPORT_SYMBOL(agp_special_page);
72#endif 72#endif
73 73
74#ifdef CONFIG_HIGHMEM
75pte_t *kmap_pte;
76pgprot_t kmap_prot;
77
78EXPORT_SYMBOL(kmap_prot);
79EXPORT_SYMBOL(kmap_pte);
80#endif
81
82void MMU_init(void); 74void MMU_init(void);
83 75
84/* XXX should be in current.h -- paulus */ 76/* XXX should be in current.h -- paulus */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 0062e6b1c555..5ccb579b81e4 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -45,6 +45,7 @@
45#include <asm/tlb.h> 45#include <asm/tlb.h>
46#include <asm/sections.h> 46#include <asm/sections.h>
47#include <asm/vdso.h> 47#include <asm/vdso.h>
48#include <asm/fixmap.h>
48 49
49#include "mmu_decl.h" 50#include "mmu_decl.h"
50 51
@@ -57,6 +58,20 @@ int init_bootmem_done;
57int mem_init_done; 58int mem_init_done;
58unsigned long memory_limit; 59unsigned long memory_limit;
59 60
61#ifdef CONFIG_HIGHMEM
62pte_t *kmap_pte;
63pgprot_t kmap_prot;
64
65EXPORT_SYMBOL(kmap_prot);
66EXPORT_SYMBOL(kmap_pte);
67
68static inline pte_t *virt_to_kpte(unsigned long vaddr)
69{
70 return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
71 vaddr), vaddr), vaddr);
72}
73#endif
74
60int page_is_ram(unsigned long pfn) 75int page_is_ram(unsigned long pfn)
61{ 76{
62 unsigned long paddr = (pfn << PAGE_SHIFT); 77 unsigned long paddr = (pfn << PAGE_SHIFT);
@@ -311,14 +326,19 @@ void __init paging_init(void)
311 unsigned long top_of_ram = lmb_end_of_DRAM(); 326 unsigned long top_of_ram = lmb_end_of_DRAM();
312 unsigned long max_zone_pfns[MAX_NR_ZONES]; 327 unsigned long max_zone_pfns[MAX_NR_ZONES];
313 328
329#ifdef CONFIG_PPC32
330 unsigned long v = __fix_to_virt(__end_of_fixed_addresses - 1);
331 unsigned long end = __fix_to_virt(FIX_HOLE);
332
333 for (; v < end; v += PAGE_SIZE)
334 map_page(v, 0, 0); /* XXX gross */
335#endif
336
314#ifdef CONFIG_HIGHMEM 337#ifdef CONFIG_HIGHMEM
315 map_page(PKMAP_BASE, 0, 0); /* XXX gross */ 338 map_page(PKMAP_BASE, 0, 0); /* XXX gross */
316 pkmap_page_table = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k 339 pkmap_page_table = virt_to_kpte(PKMAP_BASE);
317 (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); 340
318 map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ 341 kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
319 kmap_pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
320 (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN),
321 KMAP_FIX_BEGIN);
322 kmap_prot = PAGE_KERNEL; 342 kmap_prot = PAGE_KERNEL;
323#endif /* CONFIG_HIGHMEM */ 343#endif /* CONFIG_HIGHMEM */
324 344
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 64c44bcc68de..80d1babb230d 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -29,6 +29,7 @@
29 29
30#include <asm/pgtable.h> 30#include <asm/pgtable.h>
31#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
32#include <asm/fixmap.h>
32#include <asm/io.h> 33#include <asm/io.h>
33 34
34#include "mmu_decl.h" 35#include "mmu_decl.h"
@@ -387,3 +388,25 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
387 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); 388 change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
388} 389}
389#endif /* CONFIG_DEBUG_PAGEALLOC */ 390#endif /* CONFIG_DEBUG_PAGEALLOC */
391
392static int fixmaps;
393unsigned long FIXADDR_TOP = 0xfffff000;
394EXPORT_SYMBOL(FIXADDR_TOP);
395
396void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
397{
398 unsigned long address = __fix_to_virt(idx);
399
400 if (idx >= __end_of_fixed_addresses) {
401 BUG();
402 return;
403 }
404
405 map_page(address, phys, flags);
406 fixmaps++;
407}
408
409void __this_fixmap_does_not_exist(void)
410{
411 WARN_ON(1);
412}