diff options
Diffstat (limited to 'arch/arm/mm/init.c')
-rw-r--r-- | arch/arm/mm/init.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 82c4b4217989..34df4d9d03a6 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/initrd.h> | 17 | #include <linux/initrd.h> |
18 | 18 | ||
19 | #include <asm/mach-types.h> | 19 | #include <asm/mach-types.h> |
20 | #include <asm/sections.h> | ||
20 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
21 | #include <asm/sizes.h> | 22 | #include <asm/sizes.h> |
22 | #include <asm/tlb.h> | 23 | #include <asm/tlb.h> |
@@ -64,10 +65,11 @@ static int __init parse_tag_initrd2(const struct tag *tag) | |||
64 | __tagtable(ATAG_INITRD2, parse_tag_initrd2); | 65 | __tagtable(ATAG_INITRD2, parse_tag_initrd2); |
65 | 66 | ||
66 | /* | 67 | /* |
67 | * This is used to pass memory configuration data from paging_init | 68 | * This keeps memory configuration data used by a couple memory |
68 | * to mem_init, and by show_mem() to skip holes in the memory map. | 69 | * initialization functions, as well as show_mem() for the skipping |
70 | * of holes in the memory map. It is populated by arm_add_memory(). | ||
69 | */ | 71 | */ |
70 | static struct meminfo meminfo = { 0, }; | 72 | struct meminfo meminfo; |
71 | 73 | ||
72 | void show_mem(void) | 74 | void show_mem(void) |
73 | { | 75 | { |
@@ -128,7 +130,7 @@ find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages) | |||
128 | { | 130 | { |
129 | unsigned int start_pfn, i, bootmap_pfn; | 131 | unsigned int start_pfn, i, bootmap_pfn; |
130 | 132 | ||
131 | start_pfn = PAGE_ALIGN(__pa(&_end)) >> PAGE_SHIFT; | 133 | start_pfn = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT; |
132 | bootmap_pfn = 0; | 134 | bootmap_pfn = 0; |
133 | 135 | ||
134 | for_each_nodebank(i, mi, node) { | 136 | for_each_nodebank(i, mi, node) { |
@@ -331,13 +333,12 @@ static void __init bootmem_free_node(int node, struct meminfo *mi) | |||
331 | free_area_init_node(node, zone_size, start_pfn, zhole_size); | 333 | free_area_init_node(node, zone_size, start_pfn, zhole_size); |
332 | } | 334 | } |
333 | 335 | ||
334 | void __init bootmem_init(struct meminfo *mi) | 336 | void __init bootmem_init(void) |
335 | { | 337 | { |
338 | struct meminfo *mi = &meminfo; | ||
336 | unsigned long memend_pfn = 0; | 339 | unsigned long memend_pfn = 0; |
337 | int node, initrd_node; | 340 | int node, initrd_node; |
338 | 341 | ||
339 | memcpy(&meminfo, mi, sizeof(meminfo)); | ||
340 | |||
341 | /* | 342 | /* |
342 | * Locate which node contains the ramdisk image, if any. | 343 | * Locate which node contains the ramdisk image, if any. |
343 | */ | 344 | */ |
@@ -394,20 +395,22 @@ void __init bootmem_init(struct meminfo *mi) | |||
394 | max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; | 395 | max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; |
395 | } | 396 | } |
396 | 397 | ||
397 | static inline void free_area(unsigned long addr, unsigned long end, char *s) | 398 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) |
398 | { | 399 | { |
399 | unsigned int size = (end - addr) >> 10; | 400 | unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10); |
400 | 401 | ||
401 | for (; addr < end; addr += PAGE_SIZE) { | 402 | for (; pfn < end; pfn++) { |
402 | struct page *page = virt_to_page(addr); | 403 | struct page *page = pfn_to_page(pfn); |
403 | ClearPageReserved(page); | 404 | ClearPageReserved(page); |
404 | init_page_count(page); | 405 | init_page_count(page); |
405 | free_page(addr); | 406 | __free_page(page); |
406 | totalram_pages++; | 407 | pages++; |
407 | } | 408 | } |
408 | 409 | ||
409 | if (size && s) | 410 | if (size && s) |
410 | printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); | 411 | printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); |
412 | |||
413 | return pages; | ||
411 | } | 414 | } |
412 | 415 | ||
413 | static inline void | 416 | static inline void |
@@ -478,13 +481,9 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi) | |||
478 | */ | 481 | */ |
479 | void __init mem_init(void) | 482 | void __init mem_init(void) |
480 | { | 483 | { |
481 | unsigned int codepages, datapages, initpages; | 484 | unsigned int codesize, datasize, initsize; |
482 | int i, node; | 485 | int i, node; |
483 | 486 | ||
484 | codepages = &_etext - &_text; | ||
485 | datapages = &_end - &__data_start; | ||
486 | initpages = &__init_end - &__init_begin; | ||
487 | |||
488 | #ifndef CONFIG_DISCONTIGMEM | 487 | #ifndef CONFIG_DISCONTIGMEM |
489 | max_mapnr = virt_to_page(high_memory) - mem_map; | 488 | max_mapnr = virt_to_page(high_memory) - mem_map; |
490 | #endif | 489 | #endif |
@@ -501,7 +500,8 @@ void __init mem_init(void) | |||
501 | 500 | ||
502 | #ifdef CONFIG_SA1111 | 501 | #ifdef CONFIG_SA1111 |
503 | /* now that our DMA memory is actually so designated, we can free it */ | 502 | /* now that our DMA memory is actually so designated, we can free it */ |
504 | free_area(PAGE_OFFSET, (unsigned long)swapper_pg_dir, NULL); | 503 | totalram_pages += free_area(PHYS_PFN_OFFSET, |
504 | __phys_to_pfn(__pa(swapper_pg_dir)), NULL); | ||
505 | #endif | 505 | #endif |
506 | 506 | ||
507 | /* | 507 | /* |
@@ -509,18 +509,21 @@ void __init mem_init(void) | |||
509 | * real number of pages we have in this system | 509 | * real number of pages we have in this system |
510 | */ | 510 | */ |
511 | printk(KERN_INFO "Memory:"); | 511 | printk(KERN_INFO "Memory:"); |
512 | |||
513 | num_physpages = 0; | 512 | num_physpages = 0; |
514 | for (i = 0; i < meminfo.nr_banks; i++) { | 513 | for (i = 0; i < meminfo.nr_banks; i++) { |
515 | num_physpages += bank_pfn_size(&meminfo.bank[i]); | 514 | num_physpages += bank_pfn_size(&meminfo.bank[i]); |
516 | printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20); | 515 | printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20); |
517 | } | 516 | } |
518 | |||
519 | printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); | 517 | printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); |
518 | |||
519 | codesize = _etext - _text; | ||
520 | datasize = _end - _data; | ||
521 | initsize = __init_end - __init_begin; | ||
522 | |||
520 | printk(KERN_NOTICE "Memory: %luKB available (%dK code, " | 523 | printk(KERN_NOTICE "Memory: %luKB available (%dK code, " |
521 | "%dK data, %dK init)\n", | 524 | "%dK data, %dK init)\n", |
522 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), | 525 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), |
523 | codepages >> 10, datapages >> 10, initpages >> 10); | 526 | codesize >> 10, datasize >> 10, initsize >> 10); |
524 | 527 | ||
525 | if (PAGE_SIZE >= 16384 && num_physpages <= 128) { | 528 | if (PAGE_SIZE >= 16384 && num_physpages <= 128) { |
526 | extern int sysctl_overcommit_memory; | 529 | extern int sysctl_overcommit_memory; |
@@ -535,11 +538,10 @@ void __init mem_init(void) | |||
535 | 538 | ||
536 | void free_initmem(void) | 539 | void free_initmem(void) |
537 | { | 540 | { |
538 | if (!machine_is_integrator() && !machine_is_cintegrator()) { | 541 | if (!machine_is_integrator() && !machine_is_cintegrator()) |
539 | free_area((unsigned long)(&__init_begin), | 542 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), |
540 | (unsigned long)(&__init_end), | 543 | __phys_to_pfn(__pa(__init_end)), |
541 | "init"); | 544 | "init"); |
542 | } | ||
543 | } | 545 | } |
544 | 546 | ||
545 | #ifdef CONFIG_BLK_DEV_INITRD | 547 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -549,7 +551,9 @@ static int keep_initrd; | |||
549 | void free_initrd_mem(unsigned long start, unsigned long end) | 551 | void free_initrd_mem(unsigned long start, unsigned long end) |
550 | { | 552 | { |
551 | if (!keep_initrd) | 553 | if (!keep_initrd) |
552 | free_area(start, end, "initrd"); | 554 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), |
555 | __phys_to_pfn(__pa(end)), | ||
556 | "initrd"); | ||
553 | } | 557 | } |
554 | 558 | ||
555 | static int __init keepinitrd_setup(char *__unused) | 559 | static int __init keepinitrd_setup(char *__unused) |