diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 08:10:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 08:10:12 -0700 |
commit | 24a77daf3d80bddcece044e6dc3675e427eef3f3 (patch) | |
tree | 2c5e0b0bea394d6fe62c5d5857c252e83e48ac48 /arch/powerpc/mm/pgtable_32.c | |
parent | e389f9aec689209724105ae80a6c91fd2e747bc9 (diff) | |
parent | f900e9777fc9b65140cb9570438597bc8fae56ab (diff) | |
download | linux-rt-24a77daf3d80bddcece044e6dc3675e427eef3f3.tar.gz |
Merge branch 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'for-2.6.22' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (255 commits)
[POWERPC] Remove dev_dbg redefinition in drivers/ps3/vuart.c
[POWERPC] remove kernel module option for booke wdt
[POWERPC] Avoid putting cpu node twice
[POWERPC] Spinlock initializer cleanup
[POWERPC] ppc4xx_sgdma needs dma-mapping.h
[POWERPC] arch/powerpc/sysdev/timer.c build fix
[POWERPC] get_property cleanups
[POWERPC] Remove the unused HTDMSOUND driver
[POWERPC] cell: cbe_cpufreq cleanup and crash fix
[POWERPC] Declare enable_kernel_spe in a header
[POWERPC] Add dt_xlate_addr() to bootwrapper
[POWERPC] bootwrapper: CONFIG_ -> CONFIG_DEVICE_TREE
[POWERPC] Don't define a custom bd_t for Xilixn Virtex based boards.
[POWERPC] Add sane defaults for Xilinx EDK generated xparameters files
[POWERPC] Add uartlite boot console driver for the zImage wrapper
[POWERPC] Stop using ppc_sys for Xilinx Virtex boards
[POWERPC] New registration for common Xilinx Virtex ppc405 platform devices
[POWERPC] Merge common virtex header files
[POWERPC] Rework Kconfig dependancies for Xilinx Virtex ppc405 platform
[POWERPC] Clean up cpufreq Kconfig dependencies
...
Diffstat (limited to 'arch/powerpc/mm/pgtable_32.c')
-rw-r--r-- | arch/powerpc/mm/pgtable_32.c | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index c284bdac9947..bca560374927 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -183,8 +183,8 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) * mem_init() sets high_memory so only do the check after that. */ if (mem_init_done && (p < virt_to_phys(high_memory))) { - printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p, - __builtin_return_address(0)); + printk("__ioremap(): phys addr 0x%llx is RAM lr %p\n", + (unsigned long long)p, __builtin_return_address(0)); return NULL; } @@ -266,9 +266,12 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) pg = pte_alloc_kernel(pd, va); if (pg != 0) { err = 0; - set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, __pgprot(flags))); - if (mem_init_done) - flush_HPTE(0, va, pmd_val(*pd)); + /* The PTE should never be already set nor present in the + * hash table + */ + BUG_ON(pte_val(*pg) & (_PAGE_PRESENT | _PAGE_HASHPTE)); + set_pte_at(&init_mm, va, pg, pfn_pte(pa >> PAGE_SHIFT, + __pgprot(flags))); } return err; } @@ -279,16 +282,19 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) void __init mapin_ram(void) { unsigned long v, p, s, f; + int ktext; s = mmu_mapin_ram(); v = KERNELBASE + s; p = PPC_MEMSTART + s; for (; s < total_lowmem; s += PAGE_SIZE) { - if ((char *) v >= _stext && (char *) v < etext) - f = _PAGE_RAM_TEXT; - else - f = _PAGE_RAM; + ktext = ((char *) v >= _stext && (char *) v < etext); + f = ktext ?_PAGE_RAM_TEXT : _PAGE_RAM; map_page(v, p, f); +#ifdef CONFIG_PPC_STD_MMU_32 + if (ktext) + hash_preload(&init_mm, v, 0, 0x300); +#endif v += PAGE_SIZE; p += PAGE_SIZE; } @@ -445,3 +451,55 @@ exit: return ret; } +#ifdef CONFIG_DEBUG_PAGEALLOC + +static int __change_page_attr(struct page *page, pgprot_t prot) +{ + pte_t *kpte; + pmd_t *kpmd; + unsigned long address; + + BUG_ON(PageHighMem(page)); + address = (unsigned long)page_address(page); + + if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) + return 0; + if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) + return -EINVAL; + set_pte_at(&init_mm, address, kpte, mk_pte(page, prot)); + wmb(); + flush_HPTE(0, address, pmd_val(*kpmd)); + pte_unmap(kpte); + + return 0; +} + +/* + * Change the page attributes of an page in the linear mapping. + * + * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY + */ +static int change_page_attr(struct page *page, int numpages, pgprot_t prot) +{ + int i, err = 0; + unsigned long flags; + + local_irq_save(flags); + for (i = 0; i < numpages; i++, page++) { + err = __change_page_attr(page, prot); + if (err) + break; + } + local_irq_restore(flags); + return err; +} + + +void kernel_map_pages(struct page *page, int numpages, int enable) +{ + if (PageHighMem(page)) + return; + + change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); +} +#endif /* CONFIG_DEBUG_PAGEALLOC */ |