X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fmips%2Fmm%2Finit.c;fp=arch%2Fmips%2Fmm%2Finit.c;h=33f6e1cdfd5b409341488e4e2f15424f82451c3b;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=b027ce7efbc67c2246a6cc21c0ecb56b4d01ae7e;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index b027ce7ef..33f6e1cdf 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -53,7 +55,8 @@ unsigned long empty_zero_page, zero_page_mask; */ unsigned long setup_zero_pages(void) { - unsigned long order, size; + unsigned int order; + unsigned long size; struct page *page; if (cpu_has_vce) @@ -66,9 +69,9 @@ unsigned long setup_zero_pages(void) panic("Oh boy, that early out of memory?"); page = virt_to_page(empty_zero_page); + split_page(page, order); while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) { - set_bit(PG_reserved, &page->flags); - set_page_count(page, 0); + SetPageReserved(page); page++; } @@ -83,7 +86,7 @@ pte_t *kmap_pte; pgprot_t kmap_prot; #define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) static void __init kmap_init(void) { @@ -96,39 +99,45 @@ static void __init kmap_init(void) kmap_prot = PAGE_KERNEL; } -#ifdef CONFIG_MIPS64 -static void __init fixrange_init(unsigned long start, unsigned long end, +#ifdef CONFIG_32BIT +void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; - int i, j; + int i, j, k; unsigned long vaddr; vaddr = start; i = __pgd_offset(vaddr); - j = __pmd_offset(vaddr); + j = __pud_offset(vaddr); + k = __pmd_offset(vaddr); pgd = pgd_base + i; for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { - pmd = (pmd_t *)pgd; - for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { - if (pmd_none(*pmd)) { - pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pmd(pmd, __pmd(pte)); - if (pte != pte_offset_kernel(pmd, 0)) - BUG(); + pud = (pud_t *)pgd; + for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) { + pmd = (pmd_t *)pud; + for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + set_pmd(pmd, __pmd(pte)); + if (pte != pte_offset_kernel(pmd, 0)) + BUG(); + } + vaddr += PMD_SIZE; } - vaddr += PMD_SIZE; + k = 0; } j = 0; } } -#endif /* CONFIG_MIPS64 */ +#endif /* CONFIG_32BIT */ #endif /* CONFIG_HIGHMEM */ -#ifndef CONFIG_DISCONTIGMEM +#ifndef CONFIG_NEED_MULTIPLE_NODES extern void pagetable_init(void); void __init paging_init(void) @@ -169,9 +178,6 @@ void __init paging_init(void) free_area_init(zones_size); } -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) - static inline int page_is_ram(unsigned long pagenr) { int i; @@ -194,6 +200,11 @@ static inline int page_is_ram(unsigned long pagenr) return 0; } +static struct kcore_list kcore_mem, kcore_vmalloc; +#ifdef CONFIG_64BIT +static struct kcore_list kcore_kseg0; +#endif + void __init mem_init(void) { unsigned long codesize, reservedpages, datasize, initsize; @@ -216,7 +227,7 @@ void __init mem_init(void) for (tmp = 0; tmp < max_low_pfn; tmp++) if (page_is_ram(tmp)) { ram++; - if (PageReserved(mem_map+tmp)) + if (PageReserved(pfn_to_page(tmp))) reservedpages++; } @@ -232,8 +243,7 @@ void __init mem_init(void) #ifdef CONFIG_LIMITED_DMA set_page_address(page, lowmem_page_address(page)); #endif - set_bit(PG_highmem, &page->flags); - set_page_count(page, 1); + init_page_count(page); __free_page(page); totalhigh_pages++; } @@ -244,6 +254,16 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; +#ifdef CONFIG_64BIT + if ((unsigned long) &_text > (unsigned long) CKSEG0) + /* The -4 is a hack so that user tools don't have to handle + the overflow. */ + kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4); +#endif + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); + kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, + VMALLOC_END-VMALLOC_START); + printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), @@ -254,26 +274,31 @@ void __init mem_init(void) initsize >> 10, (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); } -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* !CONFIG_NEED_MULTIPLE_NODES */ + +void free_init_pages(char *what, unsigned long begin, unsigned long end) +{ + unsigned long addr; + + for (addr = begin; addr < end; addr += PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + init_page_count(virt_to_page(addr)); + memset((void *)addr, 0xcc, PAGE_SIZE); + free_page(addr); + totalram_pages++; + } + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); +} #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { -#ifdef CONFIG_MIPS64 +#ifdef CONFIG_64BIT /* Switch from KSEG0 to XKPHYS addresses */ start = (unsigned long)phys_to_virt(CPHYSADDR(start)); end = (unsigned long)phys_to_virt(CPHYSADDR(end)); #endif - if (start < end) - printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", - (end - start) >> 10); - - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(virt_to_page(start)); - set_page_count(virt_to_page(start), 1); - free_page(start); - totalram_pages++; - } + free_init_pages("initrd memory", start, end); } #endif @@ -281,24 +306,17 @@ extern unsigned long prom_free_prom_memory(void); void free_initmem(void) { - unsigned long addr, page, freed; + unsigned long start, end, freed; freed = prom_free_prom_memory(); - - addr = (unsigned long) &__init_begin; - while (addr < (unsigned long) &__init_end) { -#ifdef CONFIG_MIPS64 - page = PAGE_OFFSET | CPHYSADDR(addr); -#else - page = addr; + if (freed) + printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); + + start = (unsigned long)(&__init_begin); + end = (unsigned long)(&__init_end); +#ifdef CONFIG_64BIT + start = PAGE_OFFSET | CPHYSADDR(start); + end = PAGE_OFFSET | CPHYSADDR(end); #endif - ClearPageReserved(virt_to_page(page)); - set_page_count(virt_to_page(page), 1); - free_page(page); - totalram_pages++; - freed += PAGE_SIZE; - addr += PAGE_SIZE; - } - printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", - freed >> 10); + free_init_pages("unused kernel memory", start, end); }