[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>
This commit is contained in:

committato da
Paul Mackerras

parent
2fd53e02be
commit
2c419bdeca
@@ -71,14 +71,6 @@ unsigned long agp_special_page;
|
||||
EXPORT_SYMBOL(agp_special_page);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
pte_t *kmap_pte;
|
||||
pgprot_t kmap_prot;
|
||||
|
||||
EXPORT_SYMBOL(kmap_prot);
|
||||
EXPORT_SYMBOL(kmap_pte);
|
||||
#endif
|
||||
|
||||
void MMU_init(void);
|
||||
|
||||
/* XXX should be in current.h -- paulus */
|
||||
|
@@ -45,6 +45,7 @@
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/vdso.h>
|
||||
#include <asm/fixmap.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
|
||||
@@ -57,6 +58,20 @@ int init_bootmem_done;
|
||||
int mem_init_done;
|
||||
unsigned long memory_limit;
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
pte_t *kmap_pte;
|
||||
pgprot_t kmap_prot;
|
||||
|
||||
EXPORT_SYMBOL(kmap_prot);
|
||||
EXPORT_SYMBOL(kmap_pte);
|
||||
|
||||
static inline pte_t *virt_to_kpte(unsigned long vaddr)
|
||||
{
|
||||
return pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr),
|
||||
vaddr), vaddr), vaddr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int page_is_ram(unsigned long pfn)
|
||||
{
|
||||
unsigned long paddr = (pfn << PAGE_SHIFT);
|
||||
@@ -311,14 +326,19 @@ void __init paging_init(void)
|
||||
unsigned long top_of_ram = lmb_end_of_DRAM();
|
||||
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
unsigned long v = __fix_to_virt(__end_of_fixed_addresses - 1);
|
||||
unsigned long end = __fix_to_virt(FIX_HOLE);
|
||||
|
||||
for (; v < end; v += PAGE_SIZE)
|
||||
map_page(v, 0, 0); /* XXX gross */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
map_page(PKMAP_BASE, 0, 0); /* XXX gross */
|
||||
pkmap_page_table = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
|
||||
(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
|
||||
map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
|
||||
kmap_pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k
|
||||
(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN),
|
||||
KMAP_FIX_BEGIN);
|
||||
pkmap_page_table = virt_to_kpte(PKMAP_BASE);
|
||||
|
||||
kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN));
|
||||
kmap_prot = PAGE_KERNEL;
|
||||
#endif /* CONFIG_HIGHMEM */
|
||||
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "mmu_decl.h"
|
||||
@@ -387,3 +388,25 @@ void kernel_map_pages(struct page *page, int numpages, int enable)
|
||||
change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_PAGEALLOC */
|
||||
|
||||
static int fixmaps;
|
||||
unsigned long FIXADDR_TOP = 0xfffff000;
|
||||
EXPORT_SYMBOL(FIXADDR_TOP);
|
||||
|
||||
void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
|
||||
{
|
||||
unsigned long address = __fix_to_virt(idx);
|
||||
|
||||
if (idx >= __end_of_fixed_addresses) {
|
||||
BUG();
|
||||
return;
|
||||
}
|
||||
|
||||
map_page(address, phys, flags);
|
||||
fixmaps++;
|
||||
}
|
||||
|
||||
void __this_fixmap_does_not_exist(void)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
Fai riferimento in un nuovo problema
Block a user