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 <asm/types.h> 23#include <asm/processor.h> 24#include <asm/page.h> 25#include <asm/pgtable.h> 26#include <asm/pgalloc.h> 27#include <asm/mmu_context.h> 28#include <asm/setup.h> 29#include <asm/tlb.h> 30 31/* References to section boundaries */ 32extern char _text, _etext, _edata; 33extern char __init_begin, __init_end; 34 35pgd_t swapper_pg_dir[1024]; 36 37DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 38 39void show_mem(void) 40{ 41 int total = 0, reserved = 0; 42 int shared = 0, cached = 0; 43 int highmem = 0; 44 struct page *page; 45 pg_data_t *pgdat; 46 unsigned long i; 47 48 printk("Mem-info:\n"); 49 show_free_areas(); 50 printk("Free swap: %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); 51 for_each_online_pgdat(pgdat) { 52 unsigned long flags; 53 pgdat_resize_lock(pgdat, &flags); 54 for (i = 0; i < pgdat->node_spanned_pages; ++i) { 55 page = pgdat_page_nr(pgdat, i); 56 total++; 57 if (PageHighMem(page)) 58 highmem++; 59 if (PageReserved(page)) 60 reserved++; 61 else if (PageSwapCache(page)) 62 cached++; 63 else if (page_count(page)) 64 shared += page_count(page) - 1; 65 } 66 pgdat_resize_unlock(pgdat, &flags); 67 } 68 printk("%d pages of RAM\n", total); 69 printk("%d pages of HIGHMEM\n",highmem); 70 printk("%d reserved pages\n",reserved); 71 printk("%d pages shared\n",shared); 72 printk("%d pages swap cached\n",cached); 73} 74 75/* 76 * Cache of MMU context last used. 77 */ 78#ifndef CONFIG_SMP 79unsigned long mmu_context_cache_dat; 80#else 81unsigned long mmu_context_cache_dat[NR_CPUS]; 82#endif 83static unsigned long hole_pages; 84 85/* 86 * function prototype 87 */ 88void __init paging_init(void); 89void __init mem_init(void); 90void free_initmem(void); 91#ifdef CONFIG_BLK_DEV_INITRD 92void free_initrd_mem(unsigned long, unsigned long); 93#endif 94 95/* It'd be good if these lines were in the standard header file. */ 96#define START_PFN(nid) \ 97 (NODE_DATA(nid)->bdata->node_boot_start >> PAGE_SHIFT) 98#define MAX_LOW_PFN(nid) (NODE_DATA(nid)->bdata->node_low_pfn) 99 100#ifndef CONFIG_DISCONTIGMEM 101unsigned long __init zone_sizes_init(void) 102{ 103 unsigned long zones_size[MAX_NR_ZONES] = {0, }; 104 unsigned long max_dma; 105 unsigned long low; 106 unsigned long start_pfn; 107 108#ifdef CONFIG_MMU 109 start_pfn = START_PFN(0); 110 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 111 low = MAX_LOW_PFN(0); 112 113 if (low < max_dma){ 114 zones_size[ZONE_DMA] = low - start_pfn; 115 zones_size[ZONE_NORMAL] = 0; 116 } else { 117 zones_size[ZONE_DMA] = low - start_pfn; 118 zones_size[ZONE_NORMAL] = low - max_dma; 119 } 120#else 121 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; 122 zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT; 123 start_pfn = __MEMORY_START >> PAGE_SHIFT; 124#endif /* CONFIG_MMU */ 125 126 free_area_init_node(0, NODE_DATA(0), zones_size, start_pfn, 0); 127 128 return 0; 129} 130#else /* CONFIG_DISCONTIGMEM */ 131extern unsigned long zone_sizes_init(void); 132#endif /* CONFIG_DISCONTIGMEM */ 133 134/*======================================================================* 135 * paging_init() : sets up the page tables 136 *======================================================================*/ 137void __init paging_init(void) 138{ 139#ifdef CONFIG_MMU 140 int i; 141 pgd_t *pg_dir; 142 143 /* We don't need kernel mapping as hardware support that. */ 144 pg_dir = swapper_pg_dir; 145 146 for (i = 0 ; i < USER_PTRS_PER_PGD * 2 ; i++) 147 pgd_val(pg_dir[i]) = 0; 148#endif /* CONFIG_MMU */ 149 hole_pages = zone_sizes_init(); 150} 151 152int __init reservedpages_count(void) 153{ 154 int reservedpages, nid, i; 155 156 reservedpages = 0; 157 for_each_online_node(nid) { 158 unsigned long flags; 159 pgdat_resize_lock(NODE_DATA(nid), &flags); 160 for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++) 161 if (PageReserved(nid_page_nr(nid, i))) 162 reservedpages++; 163 pgdat_resize_unlock(NODE_DATA(nid), &flags); 164 } 165 166 return reservedpages; 167} 168 169/*======================================================================* 170 * mem_init() : 171 * orig : arch/sh/mm/init.c 172 *======================================================================*/ 173void __init mem_init(void) 174{ 175 int codesize, reservedpages, datasize, initsize; 176 int nid; 177#ifndef CONFIG_MMU 178 extern unsigned long memory_end; 179#endif 180 181 num_physpages = 0; 182 for_each_online_node(nid) 183 num_physpages += MAX_LOW_PFN(nid) - START_PFN(nid) + 1; 184 185 num_physpages -= hole_pages; 186 187#ifndef CONFIG_DISCONTIGMEM 188 max_mapnr = num_physpages; 189#endif /* CONFIG_DISCONTIGMEM */ 190 191#ifdef CONFIG_MMU 192 high_memory = (void *)__va(PFN_PHYS(MAX_LOW_PFN(0))); 193#else 194 high_memory = (void *)(memory_end & PAGE_MASK); 195#endif /* CONFIG_MMU */ 196 197 /* clear the zero-page */ 198 memset(empty_zero_page, 0, PAGE_SIZE); 199 200 /* this will put all low memory onto the freelists */ 201 for_each_online_node(nid) 202 totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); 203 204 reservedpages = reservedpages_count() - hole_pages; 205 codesize = (unsigned long) &_etext - (unsigned long)&_text; 206 datasize = (unsigned long) &_edata - (unsigned long)&_etext; 207 initsize = (unsigned long) &__init_end - (unsigned long)&__init_begin; 208 209 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " 210 "%dk reserved, %dk data, %dk init)\n", 211 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), 212 num_physpages << (PAGE_SHIFT-10), 213 codesize >> 10, 214 reservedpages << (PAGE_SHIFT-10), 215 datasize >> 10, 216 initsize >> 10); 217} 218 219/*======================================================================* 220 * free_initmem() : 221 * orig : arch/sh/mm/init.c 222 *======================================================================*/ 223void free_initmem(void) 224{ 225 unsigned long addr; 226 227 addr = (unsigned long)(&__init_begin); 228 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { 229 ClearPageReserved(virt_to_page(addr)); 230 init_page_count(virt_to_page(addr)); 231 free_page(addr); 232 totalram_pages++; 233 } 234 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", \ 235 (int)(&__init_end - &__init_begin) >> 10); 236} 237 238#ifdef CONFIG_BLK_DEV_INITRD 239/*======================================================================* 240 * free_initrd_mem() : 241 * orig : arch/sh/mm/init.c 242 *======================================================================*/ 243void free_initrd_mem(unsigned long start, unsigned long end) 244{ 245 unsigned long p; 246 for (p = start; p < end; p += PAGE_SIZE) { 247 ClearPageReserved(virt_to_page(p)); 248 init_page_count(virt_to_page(p)); 249 free_page(p); 250 totalram_pages++; 251 } 252 printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 253} 254#endif 255