Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.9 216 lines 5.8 kB view raw
1/* 2 * linux/arch/m32r/mm/init.c 3 * 4 * Copyright (c) 2001, 2002 Hitoshi Yamamoto 5 * 6 * Some code taken from sh version. 7 * Copyright (C) 1999 Niibe Yutaka 8 * Based on linux/arch/i386/mm/init.c: 9 * Copyright (C) 1995 Linus Torvalds 10 */ 11 12#include <linux/init.h> 13#include <linux/kernel.h> 14#include <linux/mm.h> 15#include <linux/pagemap.h> 16#include <linux/bootmem.h> 17#include <linux/swap.h> 18#include <linux/highmem.h> 19#include <linux/bitops.h> 20#include <linux/nodemask.h> 21#include <linux/pfn.h> 22#include <linux/gfp.h> 23#include <asm/types.h> 24#include <asm/processor.h> 25#include <asm/page.h> 26#include <asm/pgtable.h> 27#include <asm/pgalloc.h> 28#include <asm/mmu_context.h> 29#include <asm/setup.h> 30#include <asm/tlb.h> 31 32/* References to section boundaries */ 33extern char _text, _etext, _edata; 34extern char __init_begin, __init_end; 35 36pgd_t swapper_pg_dir[1024]; 37 38/* 39 * Cache of MMU context last used. 40 */ 41#ifndef CONFIG_SMP 42unsigned long mmu_context_cache_dat; 43#else 44unsigned long mmu_context_cache_dat[NR_CPUS]; 45#endif 46static unsigned long hole_pages; 47 48/* 49 * function prototype 50 */ 51void __init paging_init(void); 52void __init mem_init(void); 53void free_initmem(void); 54#ifdef CONFIG_BLK_DEV_INITRD 55void free_initrd_mem(unsigned long, unsigned long); 56#endif 57 58/* It'd be good if these lines were in the standard header file. */ 59#define START_PFN(nid) (NODE_DATA(nid)->bdata->node_min_pfn) 60#define MAX_LOW_PFN(nid) (NODE_DATA(nid)->bdata->node_low_pfn) 61 62#ifndef CONFIG_DISCONTIGMEM 63unsigned long __init zone_sizes_init(void) 64{ 65 unsigned long zones_size[MAX_NR_ZONES] = {0, }; 66 unsigned long max_dma; 67 unsigned long low; 68 unsigned long start_pfn; 69 70#ifdef CONFIG_MMU 71 start_pfn = START_PFN(0); 72 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 73 low = MAX_LOW_PFN(0); 74 75 if (low < max_dma){ 76 zones_size[ZONE_DMA] = low - start_pfn; 77 zones_size[ZONE_NORMAL] = 0; 78 } else { 79 zones_size[ZONE_DMA] = low - start_pfn; 80 zones_size[ZONE_NORMAL] = low - max_dma; 81 } 82#else 83 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; 84 zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT; 85 start_pfn = __MEMORY_START >> PAGE_SHIFT; 86#endif /* CONFIG_MMU */ 87 88 free_area_init_node(0, zones_size, start_pfn, 0); 89 90 return 0; 91} 92#else /* CONFIG_DISCONTIGMEM */ 93extern unsigned long zone_sizes_init(void); 94#endif /* CONFIG_DISCONTIGMEM */ 95 96/*======================================================================* 97 * paging_init() : sets up the page tables 98 *======================================================================*/ 99void __init paging_init(void) 100{ 101#ifdef CONFIG_MMU 102 int i; 103 pgd_t *pg_dir; 104 105 /* We don't need kernel mapping as hardware support that. */ 106 pg_dir = swapper_pg_dir; 107 108 for (i = 0 ; i < USER_PTRS_PER_PGD * 2 ; i++) 109 pgd_val(pg_dir[i]) = 0; 110#endif /* CONFIG_MMU */ 111 hole_pages = zone_sizes_init(); 112} 113 114int __init reservedpages_count(void) 115{ 116 int reservedpages, nid, i; 117 118 reservedpages = 0; 119 for_each_online_node(nid) { 120 unsigned long flags; 121 pgdat_resize_lock(NODE_DATA(nid), &flags); 122 for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++) 123 if (PageReserved(nid_page_nr(nid, i))) 124 reservedpages++; 125 pgdat_resize_unlock(NODE_DATA(nid), &flags); 126 } 127 128 return reservedpages; 129} 130 131/*======================================================================* 132 * mem_init() : 133 * orig : arch/sh/mm/init.c 134 *======================================================================*/ 135void __init mem_init(void) 136{ 137 int codesize, reservedpages, datasize, initsize; 138 int nid; 139#ifndef CONFIG_MMU 140 extern unsigned long memory_end; 141#endif 142 143 num_physpages = 0; 144 for_each_online_node(nid) 145 num_physpages += MAX_LOW_PFN(nid) - START_PFN(nid) + 1; 146 147 num_physpages -= hole_pages; 148 149#ifndef CONFIG_DISCONTIGMEM 150 max_mapnr = num_physpages; 151#endif /* CONFIG_DISCONTIGMEM */ 152 153#ifdef CONFIG_MMU 154 high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0))); 155#else 156 high_memory = (void *)(memory_end & PAGE_MASK); 157#endif /* CONFIG_MMU */ 158 159 /* clear the zero-page */ 160 memset(empty_zero_page, 0, PAGE_SIZE); 161 162 /* this will put all low memory onto the freelists */ 163 for_each_online_node(nid) 164 totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); 165 166 reservedpages = reservedpages_count() - hole_pages; 167 codesize = (unsigned long) &_etext - (unsigned long)&_text; 168 datasize = (unsigned long) &_edata - (unsigned long)&_etext; 169 initsize = (unsigned long) &__init_end - (unsigned long)&__init_begin; 170 171 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " 172 "%dk reserved, %dk data, %dk init)\n", 173 nr_free_pages() << (PAGE_SHIFT-10), 174 num_physpages << (PAGE_SHIFT-10), 175 codesize >> 10, 176 reservedpages << (PAGE_SHIFT-10), 177 datasize >> 10, 178 initsize >> 10); 179} 180 181/*======================================================================* 182 * free_initmem() : 183 * orig : arch/sh/mm/init.c 184 *======================================================================*/ 185void free_initmem(void) 186{ 187 unsigned long addr; 188 189 addr = (unsigned long)(&__init_begin); 190 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { 191 ClearPageReserved(virt_to_page(addr)); 192 init_page_count(virt_to_page(addr)); 193 free_page(addr); 194 totalram_pages++; 195 } 196 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", \ 197 (int)(&__init_end - &__init_begin) >> 10); 198} 199 200#ifdef CONFIG_BLK_DEV_INITRD 201/*======================================================================* 202 * free_initrd_mem() : 203 * orig : arch/sh/mm/init.c 204 *======================================================================*/ 205void free_initrd_mem(unsigned long start, unsigned long end) 206{ 207 unsigned long p; 208 for (p = start; p < end; p += PAGE_SIZE) { 209 ClearPageReserved(virt_to_page(p)); 210 init_page_count(virt_to_page(p)); 211 free_page(p); 212 totalram_pages++; 213 } 214 printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 215} 216#endif