diff options
Diffstat (limited to 'arch/powerpc/mm/mem.c')
-rw-r--r-- | arch/powerpc/mm/mem.c | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index be5c506779a7..d9e37f365b54 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -31,6 +31,7 @@ #include <linux/initrd.h> #include <linux/pagemap.h> #include <linux/suspend.h> +#include <linux/lmb.h> #include <asm/pgalloc.h> #include <asm/prom.h> @@ -42,9 +43,9 @@ #include <asm/machdep.h> #include <asm/btext.h> #include <asm/tlb.h> -#include <asm/lmb.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); @@ -95,15 +110,6 @@ EXPORT_SYMBOL(phys_mem_access_prot); #ifdef CONFIG_MEMORY_HOTPLUG -void online_page(struct page *page) -{ - ClearPageReserved(page); - init_page_count(page); - __free_page(page); - totalram_pages++; - num_physpages++; -} - #ifdef CONFIG_NUMA int memory_add_physaddr_to_nid(u64 start) { @@ -111,7 +117,7 @@ int memory_add_physaddr_to_nid(u64 start) } #endif -int __devinit arch_add_memory(int nid, u64 start, u64 size) +int arch_add_memory(int nid, u64 start, u64 size) { struct pglist_data *pgdata; struct zone *zone; @@ -175,7 +181,6 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_online_pgdat(pgdat) { unsigned long flags; pgdat_resize_lock(pgdat, &flags); @@ -217,9 +222,11 @@ void __init do_init_bootmem(void) unsigned long total_pages; int boot_mapsize; - max_pfn = total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT; + max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; + total_pages = (lmb_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT; #ifdef CONFIG_HIGHMEM total_pages = total_lowmem >> PAGE_SHIFT; + max_low_pfn = lowmem_end_addr >> PAGE_SHIFT; #endif /* @@ -231,7 +238,8 @@ void __init do_init_bootmem(void) start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE); - boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); + min_low_pfn = MEMORY_START >> PAGE_SHIFT; + boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn); /* Add active regions with valid PFNs */ for (i = 0; i < lmb.memory.cnt; i++) { @@ -245,18 +253,18 @@ void __init do_init_bootmem(void) * present. */ #ifdef CONFIG_HIGHMEM - free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT); + free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT); /* reserve the sections we're already using */ for (i = 0; i < lmb.reserved.cnt; i++) { unsigned long addr = lmb.reserved.region[i].base + lmb_size_bytes(&lmb.reserved, i) - 1; - if (addr < total_lowmem) + if (addr < lowmem_end_addr) reserve_bootmem(lmb.reserved.region[i].base, lmb_size_bytes(&lmb.reserved, i), BOOTMEM_DEFAULT); - else if (lmb.reserved.region[i].base < total_lowmem) { - unsigned long adjusted_size = total_lowmem - + else if (lmb.reserved.region[i].base < lowmem_end_addr) { + unsigned long adjusted_size = lowmem_end_addr - lmb.reserved.region[i].base; reserve_bootmem(lmb.reserved.region[i].base, adjusted_size, BOOTMEM_DEFAULT); @@ -309,14 +317,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 */ @@ -326,7 +339,7 @@ void __init paging_init(void) (top_of_ram - total_ram) >> 20); memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); #ifdef CONFIG_HIGHMEM - max_zone_pfns[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; + max_zone_pfns[ZONE_DMA] = lowmem_end_addr >> PAGE_SHIFT; max_zone_pfns[ZONE_HIGHMEM] = top_of_ram >> PAGE_SHIFT; #else max_zone_pfns[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; @@ -381,7 +394,7 @@ void __init mem_init(void) { unsigned long pfn, highmem_mapnr; - highmem_mapnr = total_lowmem >> PAGE_SHIFT; + highmem_mapnr = lowmem_end_addr >> PAGE_SHIFT; for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { struct page *page = pfn_to_page(pfn); if (lmb_is_reserved(pfn << PAGE_SHIFT)) |