diff options
Diffstat (limited to 'arch/mips/mm/init.c')
-rw-r--r-- | arch/mips/mm/init.c | 138 |
1 files changed, 60 insertions, 78 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index bf77a7998..cf74a6dd5 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -1,10 +1,11 @@ -/* $Id: init.c,v 1.19 1999/10/09 00:00:58 ralf Exp $ +/* $Id: init.c,v 1.20 2000/01/26 00:07:44 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 1998 by Ralf Baechle + * Copyright (C) 1994 - 2000 by Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. */ #include <linux/config.h> #include <linux/init.h> @@ -18,6 +19,7 @@ #include <linux/ptrace.h> #include <linux/mman.h> #include <linux/mm.h> +#include <linux/bootmem.h> #include <linux/swap.h> #include <linux/swapctl.h> #ifdef CONFIG_BLK_DEV_INITRD @@ -35,7 +37,7 @@ #endif #include <asm/mmu_context.h> -static unsigned long totalram = 0; +static unsigned long totalram_pages = 0; extern void show_net_buffers(void); extern void prom_fixup_mem_map(unsigned long start, unsigned long end); @@ -45,13 +47,13 @@ extern void prom_free_prom_memory(void); void __bad_pte_kernel(pmd_t *pmd) { printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = BAD_PAGETABLE; + pmd_set(pmd, BAD_PAGETABLE); } void __bad_pte(pmd_t *pmd) { printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = BAD_PAGETABLE; + pmd_set(pmd, BAD_PAGETABLE); } pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) @@ -61,11 +63,11 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) page = (pte_t *) __get_free_page(GFP_USER); if (pmd_none(*pmd)) { if (page) { - clear_page((unsigned long)page); + clear_page(page); pmd_val(*pmd) = (unsigned long)page; return page + offset; } - pmd_val(*pmd) = BAD_PAGETABLE; + pmd_set(pmd, BAD_PAGETABLE); return NULL; } free_page((unsigned long)page); @@ -83,11 +85,11 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) page = (pte_t *) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (page) { - clear_page((unsigned long)page); + clear_page(page); pmd_val(*pmd) = (unsigned long)page; return page + offset; } - pmd_val(*pmd) = BAD_PAGETABLE; + pmd_set(pmd, BAD_PAGETABLE); return NULL; } free_page((unsigned long)page); @@ -135,7 +137,7 @@ static inline unsigned long setup_zero_pages(void) panic("Oh boy, that early out of memory?"); pg = MAP_NR(empty_zero_page); - while(pg < MAP_NR(empty_zero_page) + (1 << order)) { + while (pg < MAP_NR(empty_zero_page) + (1 << order)) { set_bit(PG_reserved, &mem_map[pg].flags); set_page_count(mem_map + pg, 0); pg++; @@ -145,7 +147,7 @@ static inline unsigned long setup_zero_pages(void) zero_page_mask = (size - 1) & PAGE_MASK; memset((void *)empty_zero_page, 0, size); - return size; + return 1UL << order; } int do_check_pgt_cache(int low, int high) @@ -201,10 +203,10 @@ pte_t * __bad_pagetable(void) pte_t __bad_page(void) { extern char empty_bad_page[PAGE_SIZE]; - unsigned long page = (unsigned long)empty_bad_page; + unsigned long page = (unsigned long) empty_bad_page; - clear_page(page); - return pte_mkdirty(mk_pte(page, PAGE_SHARED)); + clear_page((void *)page); + return pte_mkdirty(mk_pte_phys(__pa(page), PAGE_SHARED)); } void show_mem(void) @@ -233,85 +235,61 @@ void show_mem(void) printk("%d pages swap cached\n",cached); printk("%ld pages in page table cache\n",pgtable_cache_size); printk("%d free pages\n", free); + show_buffers(); #ifdef CONFIG_NET show_net_buffers(); #endif } -extern unsigned long free_area_init(unsigned long, unsigned long); +/* References to section boundaries */ -unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem) +extern char _ftext, _etext, _fdata, _edata; +extern char __init_begin, __init_end; + +void __init paging_init(void) { /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2); - return free_area_init(start_mem, end_mem); + return free_area_init(max_low_pfn); } -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +extern int page_is_ram(unsigned long pagenr); + +void __init mem_init(void) { - int codepages = 0; - int datapages = 0; + unsigned long codesize, reservedpages, datasize, initsize; unsigned long tmp; - extern int _etext, _ftext; - -#ifdef CONFIG_MIPS_JAZZ - if (mips_machgroup == MACH_GROUP_JAZZ) - start_mem = vdma_init(start_mem, end_mem); -#endif - - end_mem &= PAGE_MASK; - max_mapnr = MAP_NR(end_mem); - high_memory = (void *)end_mem; - num_physpages = 0; - - /* mark usable pages in the mem_map[] */ - start_mem = PAGE_ALIGN(start_mem); - for(tmp = MAP_NR(start_mem);tmp < max_mapnr;tmp++) - clear_bit(PG_reserved, &mem_map[tmp].flags); + max_mapnr = num_physpages = max_low_pfn; + high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); - prom_fixup_mem_map(start_mem, (unsigned long)high_memory); + totalram_pages += free_all_bootmem(); + totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ - for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) { + reservedpages = 0; + for (tmp = 0; tmp < max_low_pfn; tmp++) /* - * This is only for PC-style DMA. The onboard DMA - * of Jazz and Tyne machines is completely different and - * not handled via a flag in mem_map_t. + * Only count resrved RAM pages */ - if (tmp >= MAX_DMA_ADDRESS) - clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); - if (PageReserved(mem_map+MAP_NR(tmp))) { - if ((tmp < (unsigned long) &_etext) && - (tmp >= (unsigned long) &_ftext)) - codepages++; - else if ((tmp < start_mem) && - (tmp > (unsigned long) &_etext)) - datapages++; - continue; - } - num_physpages++; - set_page_count(mem_map + MAP_NR(tmp), 1); - totalram += PAGE_SIZE; -#ifdef CONFIG_BLK_DEV_INITRD - if (!initrd_start || (tmp < initrd_start || tmp >= - initrd_end)) -#endif - free_page(tmp); - } - tmp = nr_free_pages << PAGE_SHIFT; - - /* Setup zeroed pages. */ - tmp -= setup_zero_pages(); - - printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n", - tmp >> 10, - max_mapnr << (PAGE_SHIFT-10), - codepages << (PAGE_SHIFT-10), - datapages << (PAGE_SHIFT-10)); + if (page_is_ram(tmp) && PageReserved(mem_map+tmp)) + reservedpages++; + + codesize = (unsigned long) &_etext - (unsigned long) &_ftext; + datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " + "%ldk data, %ldk init)\n", + (unsigned long) nr_free_pages << (PAGE_SHIFT-10), + max_mapnr << (PAGE_SHIFT-10), + codesize >> 10, + reservedpages << (PAGE_SHIFT-10), + datasize >> 10, + initsize >> 10); } extern char __init_begin, __init_end; +extern void prom_free_prom_memory(void); void free_initmem(void) { @@ -319,12 +297,13 @@ void free_initmem(void) prom_free_prom_memory (); - addr = (unsigned long)(&__init_begin); - for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { - mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + addr = (unsigned long) &__init_begin; + while (addr < (unsigned long) &__init_end) { + ClearPageReserved(mem_map + MAP_NR(addr)); set_page_count(mem_map + MAP_NR(addr), 1); free_page(addr); - totalram += PAGE_SIZE; + totalram_pages++; + addr += PAGE_SIZE; } printk("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); @@ -332,10 +311,13 @@ void free_initmem(void) void si_meminfo(struct sysinfo *val) { - val->totalram = totalram; + val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); + val->freeram = nr_free_pages; + val->bufferram = atomic_read(&buffermem_pages); + val->totalhigh = 0; + val->freehigh = 0; + val->mem_unit = PAGE_SIZE; return; } |