diff options
Diffstat (limited to 'arch/mips/mm/init.c')
-rw-r--r-- | arch/mips/mm/init.c | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 2de4d3c367a2..30245c09d025 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -90,9 +90,9 @@ unsigned long setup_zero_pages(void) | |||
90 | if (!empty_zero_page) | 90 | if (!empty_zero_page) |
91 | panic("Oh boy, that early out of memory?"); | 91 | panic("Oh boy, that early out of memory?"); |
92 | 92 | ||
93 | page = virt_to_page(empty_zero_page); | 93 | page = virt_to_page((void *)empty_zero_page); |
94 | split_page(page, order); | 94 | split_page(page, order); |
95 | while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) { | 95 | while (page < virt_to_page((void *)(empty_zero_page + (PAGE_SIZE << order)))) { |
96 | SetPageReserved(page); | 96 | SetPageReserved(page); |
97 | page++; | 97 | page++; |
98 | } | 98 | } |
@@ -203,6 +203,31 @@ static inline void kunmap_coherent(struct page *page) | |||
203 | preempt_check_resched(); | 203 | preempt_check_resched(); |
204 | } | 204 | } |
205 | 205 | ||
206 | void copy_user_highpage(struct page *to, struct page *from, | ||
207 | unsigned long vaddr, struct vm_area_struct *vma) | ||
208 | { | ||
209 | void *vfrom, *vto; | ||
210 | |||
211 | vto = kmap_atomic(to, KM_USER1); | ||
212 | if (cpu_has_dc_aliases) { | ||
213 | vfrom = kmap_coherent(from, vaddr); | ||
214 | copy_page(vto, vfrom); | ||
215 | kunmap_coherent(from); | ||
216 | } else { | ||
217 | vfrom = kmap_atomic(from, KM_USER0); | ||
218 | copy_page(vto, vfrom); | ||
219 | kunmap_atomic(vfrom, KM_USER0); | ||
220 | } | ||
221 | if (((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) || | ||
222 | pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) | ||
223 | flush_data_cache_page((unsigned long)vto); | ||
224 | kunmap_atomic(vto, KM_USER1); | ||
225 | /* Make sure this page is cleared on other CPU's too before using it */ | ||
226 | smp_wmb(); | ||
227 | } | ||
228 | |||
229 | EXPORT_SYMBOL(copy_user_highpage); | ||
230 | |||
206 | void copy_to_user_page(struct vm_area_struct *vma, | 231 | void copy_to_user_page(struct vm_area_struct *vma, |
207 | struct page *page, unsigned long vaddr, void *dst, const void *src, | 232 | struct page *page, unsigned long vaddr, void *dst, const void *src, |
208 | unsigned long len) | 233 | unsigned long len) |
@@ -316,7 +341,7 @@ static int __init page_is_ram(unsigned long pagenr) | |||
316 | void __init paging_init(void) | 341 | void __init paging_init(void) |
317 | { | 342 | { |
318 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; | 343 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; |
319 | unsigned long max_dma, high, low; | 344 | unsigned long max_dma, low; |
320 | #ifndef CONFIG_FLATMEM | 345 | #ifndef CONFIG_FLATMEM |
321 | unsigned long zholes_size[MAX_NR_ZONES] = { 0, }; | 346 | unsigned long zholes_size[MAX_NR_ZONES] = { 0, }; |
322 | unsigned long i, j, pfn; | 347 | unsigned long i, j, pfn; |
@@ -331,7 +356,6 @@ void __init paging_init(void) | |||
331 | 356 | ||
332 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 357 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
333 | low = max_low_pfn; | 358 | low = max_low_pfn; |
334 | high = highend_pfn; | ||
335 | 359 | ||
336 | #ifdef CONFIG_ISA | 360 | #ifdef CONFIG_ISA |
337 | if (low < max_dma) | 361 | if (low < max_dma) |
@@ -344,13 +368,13 @@ void __init paging_init(void) | |||
344 | zones_size[ZONE_DMA] = low; | 368 | zones_size[ZONE_DMA] = low; |
345 | #endif | 369 | #endif |
346 | #ifdef CONFIG_HIGHMEM | 370 | #ifdef CONFIG_HIGHMEM |
347 | if (cpu_has_dc_aliases) { | 371 | zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn; |
348 | printk(KERN_WARNING "This processor doesn't support highmem."); | 372 | |
349 | if (high - low) | 373 | if (cpu_has_dc_aliases && zones_size[ZONE_HIGHMEM]) { |
350 | printk(" %ldk highmem ignored", high - low); | 374 | printk(KERN_WARNING "This processor doesn't support highmem." |
351 | printk("\n"); | 375 | " %ldk highmem ignored\n", zones_size[ZONE_HIGHMEM]); |
352 | } else | 376 | zones_size[ZONE_HIGHMEM] = 0; |
353 | zones_size[ZONE_HIGHMEM] = high - low; | 377 | } |
354 | #endif | 378 | #endif |
355 | 379 | ||
356 | #ifdef CONFIG_FLATMEM | 380 | #ifdef CONFIG_FLATMEM |
@@ -443,15 +467,18 @@ void __init mem_init(void) | |||
443 | } | 467 | } |
444 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 468 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
445 | 469 | ||
446 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | 470 | static void free_init_pages(char *what, unsigned long begin, unsigned long end) |
447 | { | 471 | { |
448 | unsigned long addr; | 472 | unsigned long pfn; |
473 | |||
474 | for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) { | ||
475 | struct page *page = pfn_to_page(pfn); | ||
476 | void *addr = phys_to_virt(PFN_PHYS(pfn)); | ||
449 | 477 | ||
450 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | 478 | ClearPageReserved(page); |
451 | ClearPageReserved(virt_to_page(addr)); | 479 | init_page_count(page); |
452 | init_page_count(virt_to_page(addr)); | 480 | memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); |
453 | memset((void *)addr, 0xcc, PAGE_SIZE); | 481 | __free_page(page); |
454 | free_page(addr); | ||
455 | totalram_pages++; | 482 | totalram_pages++; |
456 | } | 483 | } |
457 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | 484 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); |
@@ -460,12 +487,9 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
460 | #ifdef CONFIG_BLK_DEV_INITRD | 487 | #ifdef CONFIG_BLK_DEV_INITRD |
461 | void free_initrd_mem(unsigned long start, unsigned long end) | 488 | void free_initrd_mem(unsigned long start, unsigned long end) |
462 | { | 489 | { |
463 | #ifdef CONFIG_64BIT | 490 | free_init_pages("initrd memory", |
464 | /* Switch from KSEG0 to XKPHYS addresses */ | 491 | virt_to_phys((void *)start), |
465 | start = (unsigned long)phys_to_virt(CPHYSADDR(start)); | 492 | virt_to_phys((void *)end)); |
466 | end = (unsigned long)phys_to_virt(CPHYSADDR(end)); | ||
467 | #endif | ||
468 | free_init_pages("initrd memory", start, end); | ||
469 | } | 493 | } |
470 | #endif | 494 | #endif |
471 | 495 | ||
@@ -473,17 +497,13 @@ extern unsigned long prom_free_prom_memory(void); | |||
473 | 497 | ||
474 | void free_initmem(void) | 498 | void free_initmem(void) |
475 | { | 499 | { |
476 | unsigned long start, end, freed; | 500 | unsigned long freed; |
477 | 501 | ||
478 | freed = prom_free_prom_memory(); | 502 | freed = prom_free_prom_memory(); |
479 | if (freed) | 503 | if (freed) |
480 | printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); | 504 | printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); |
481 | 505 | ||
482 | start = (unsigned long)(&__init_begin); | 506 | free_init_pages("unused kernel memory", |
483 | end = (unsigned long)(&__init_end); | 507 | __pa_symbol(&__init_begin), |
484 | #ifdef CONFIG_64BIT | 508 | __pa_symbol(&__init_end)); |
485 | start = PAGE_OFFSET | CPHYSADDR(start); | ||
486 | end = PAGE_OFFSET | CPHYSADDR(end); | ||
487 | #endif | ||
488 | free_init_pages("unused kernel memory", start, end); | ||
489 | } | 509 | } |