1 /* 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include <linux/stddef.h> 7 #include <linux/module.h> 8 #include <linux/bootmem.h> 9 #include <linux/highmem.h> 10 #include <linux/mm.h> 11 #include <linux/swap.h> 12 #include <linux/slab.h> 13 #include <asm/fixmap.h> 14 #include <asm/page.h> 15 #include <as-layout.h> 16 #include <init.h> 17 #include <kern.h> 18 #include <kern_util.h> 19 #include <mem_user.h> 20 #include <os.h> 21 22 /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */ 23 unsigned long *empty_zero_page = NULL; 24 EXPORT_SYMBOL(empty_zero_page); 25 /* allocated in paging_init and unchanged thereafter */ 26 static unsigned long *empty_bad_page = NULL; 27 28 /* 29 * Initialized during boot, and readonly for initializing page tables 30 * afterwards 31 */ 32 pgd_t swapper_pg_dir[PTRS_PER_PGD]; 33 34 /* Initialized at boot time, and readonly after that */ 35 unsigned long long highmem; 36 int kmalloc_ok = 0; 37 38 /* Used during early boot */ 39 static unsigned long brk_end; 40 41 #ifdef CONFIG_HIGHMEM 42 static void setup_highmem(unsigned long highmem_start, 43 unsigned long highmem_len) 44 { 45 struct page *page; 46 unsigned long highmem_pfn; 47 int i; 48 49 highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; 50 for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) { 51 page = &mem_map[highmem_pfn + i]; 52 ClearPageReserved(page); 53 init_page_count(page); 54 __free_page(page); 55 } 56 } 57 #endif 58 59 void __init mem_init(void) 60 { 61 /* clear the zero-page */ 62 memset(empty_zero_page, 0, PAGE_SIZE); 63 64 /* Map in the area just after the brk now that kmalloc is about 65 * to be turned on. 66 */ 67 brk_end = (unsigned long) UML_ROUND_UP(sbrk(0)); 68 map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); 69 free_bootmem(__pa(brk_end), uml_reserved - brk_end); 70 uml_reserved = brk_end; 71 72 /* this will put all low memory onto the freelists */ 73 totalram_pages = free_all_bootmem(); 74 max_low_pfn = totalram_pages; 75 #ifdef CONFIG_HIGHMEM 76 totalhigh_pages = highmem >> PAGE_SHIFT; 77 totalram_pages += totalhigh_pages; 78 #endif 79 num_physpages = totalram_pages; 80 max_pfn = totalram_pages; 81 printk(KERN_INFO "Memory: %luk available\n", 82 nr_free_pages() << (PAGE_SHIFT-10)); 83 kmalloc_ok = 1; 84 85 #ifdef CONFIG_HIGHMEM 86 setup_highmem(end_iomem, highmem); 87 #endif 88 } 89 90 /* 91 * Create a page table and place a pointer to it in a middle page 92 * directory entry. 93 */ 94 static void __init one_page_table_init(pmd_t *pmd) 95 { 96 if (pmd_none(*pmd)) { 97 pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); 98 set_pmd(pmd, __pmd(_KERNPG_TABLE + 99 (unsigned long) __pa(pte))); 100 if (pte != pte_offset_kernel(pmd, 0)) 101 BUG(); 102 } 103 } 104 105 static void __init one_md_table_init(pud_t *pud) 106 { 107 #ifdef CONFIG_3_LEVEL_PGTABLES 108 pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); 109 set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); 110 if (pmd_table != pmd_offset(pud, 0)) 111 BUG(); 112 #endif 113 } 114 115 static void __init fixrange_init(unsigned long start, unsigned long end, 116 pgd_t *pgd_base) 117 { 118 pgd_t *pgd; 119 pud_t *pud; 120 pmd_t *pmd; 121 int i, j; 122 unsigned long vaddr; 123 124 vaddr = start; 125 i = pgd_index(vaddr); 126 j = pmd_index(vaddr); 127 pgd = pgd_base + i; 128 129 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { 130 pud = pud_offset(pgd, vaddr); 131 if (pud_none(*pud)) 132 one_md_table_init(pud); 133 pmd = pmd_offset(pud, vaddr); 134 for (; (j < PTRS_PER_PMD) && (vaddr < end); pmd++, j++) { 135 one_page_table_init(pmd); 136 vaddr += PMD_SIZE; 137 } 138 j = 0; 139 } 140 } 141 142 #ifdef CONFIG_HIGHMEM 143 pte_t *kmap_pte; 144 pgprot_t kmap_prot; 145 146 #define kmap_get_fixmap_pte(vaddr) \ 147 pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\ 148 (vaddr)), (vaddr)) 149 150 static void __init kmap_init(void) 151 { 152 unsigned long kmap_vstart; 153 154 /* cache the first kmap pte */ 155 kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); 156 kmap_pte = kmap_get_fixmap_pte(kmap_vstart); 157 158 kmap_prot = PAGE_KERNEL; 159 } 160 161 static void __init init_highmem(void) 162 { 163 pgd_t *pgd; 164 pud_t *pud; 165 pmd_t *pmd; 166 pte_t *pte; 167 unsigned long vaddr; 168 169 /* 170 * Permanent kmaps: 171 */ 172 vaddr = PKMAP_BASE; 173 fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir); 174 175 pgd = swapper_pg_dir + pgd_index(vaddr); 176 pud = pud_offset(pgd, vaddr); 177 pmd = pmd_offset(pud, vaddr); 178 pte = pte_offset_kernel(pmd, vaddr); 179 pkmap_page_table = pte; 180 181 kmap_init(); 182 } 183 #endif /* CONFIG_HIGHMEM */ 184 185 static void __init fixaddr_user_init( void) 186 { 187 #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA 188 long size = FIXADDR_USER_END - FIXADDR_USER_START; 189 pgd_t *pgd; 190 pud_t *pud; 191 pmd_t *pmd; 192 pte_t *pte; 193 phys_t p; 194 unsigned long v, vaddr = FIXADDR_USER_START; 195 196 if (!size) 197 return; 198 199 fixrange_init( FIXADDR_USER_START, FIXADDR_USER_END, swapper_pg_dir); 200 v = (unsigned long) alloc_bootmem_low_pages(size); 201 memcpy((void *) v , (void *) FIXADDR_USER_START, size); 202 p = __pa(v); 203 for ( ; size > 0; size -= PAGE_SIZE, vaddr += PAGE_SIZE, 204 p += PAGE_SIZE) { 205 pgd = swapper_pg_dir + pgd_index(vaddr); 206 pud = pud_offset(pgd, vaddr); 207 pmd = pmd_offset(pud, vaddr); 208 pte = pte_offset_kernel(pmd, vaddr); 209 pte_set_val(*pte, p, PAGE_READONLY); 210 } 211 #endif 212 } 213 214 void __init paging_init(void) 215 { 216 unsigned long zones_size[MAX_NR_ZONES], vaddr; 217 int i; 218 219 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 220 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 221 for (i = 0; i < ARRAY_SIZE(zones_size); i++) 222 zones_size[i] = 0; 223 224 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - 225 (uml_physmem >> PAGE_SHIFT); 226 #ifdef CONFIG_HIGHMEM 227 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT; 228 #endif 229 free_area_init(zones_size); 230 231 /* 232 * Fixed mappings, only the page table structure has to be 233 * created - mappings will be set by set_fixmap(): 234 */ 235 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; 236 fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); 237 238 fixaddr_user_init(); 239 240 #ifdef CONFIG_HIGHMEM 241 init_highmem(); 242 #endif 243 } 244 245 /* 246 * This can't do anything because nothing in the kernel image can be freed 247 * since it's not in kernel physical memory. 248 */ 249 250 void free_initmem(void) 251 { 252 } 253 254 #ifdef CONFIG_BLK_DEV_INITRD 255 void free_initrd_mem(unsigned long start, unsigned long end) 256 { 257 if (start < end) 258 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", 259 (end - start) >> 10); 260 for (; start < end; start += PAGE_SIZE) { 261 ClearPageReserved(virt_to_page(start)); 262 init_page_count(virt_to_page(start)); 263 free_page(start); 264 totalram_pages++; 265 } 266 } 267 #endif 268 269 /* Allocate and free page tables. */ 270 271 pgd_t *pgd_alloc(struct mm_struct *mm) 272 { 273 pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); 274 275 if (pgd) { 276 memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); 277 memcpy(pgd + USER_PTRS_PER_PGD, 278 swapper_pg_dir + USER_PTRS_PER_PGD, 279 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 280 } 281 return pgd; 282 } 283 284 void pgd_free(struct mm_struct *mm, pgd_t *pgd) 285 { 286 free_page((unsigned long) pgd); 287 } 288 289 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 290 { 291 pte_t *pte; 292 293 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 294 return pte; 295 } 296 297 pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) 298 { 299 struct page *pte; 300 301 pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); 302 if (pte) 303 pgtable_page_ctor(pte); 304 return pte; 305 } 306 307 #ifdef CONFIG_3_LEVEL_PGTABLES 308 pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) 309 { 310 pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL); 311 312 if (pmd) 313 memset(pmd, 0, PAGE_SIZE); 314 315 return pmd; 316 } 317 #endif 318 319 void *uml_kmalloc(int size, int flags) 320 { 321 return kmalloc(size, flags); 322 } 323