aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/init.c')
-rw-r--r--arch/arm/mm/init.c118
1 files changed, 99 insertions, 19 deletions
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 52c40d155672..0ed29bfeba1c 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,12 +17,14 @@
17#include <linux/initrd.h> 17#include <linux/initrd.h>
18#include <linux/sort.h> 18#include <linux/sort.h>
19#include <linux/highmem.h> 19#include <linux/highmem.h>
20#include <linux/gfp.h>
20 21
21#include <asm/mach-types.h> 22#include <asm/mach-types.h>
22#include <asm/sections.h> 23#include <asm/sections.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
24#include <asm/sizes.h> 25#include <asm/sizes.h>
25#include <asm/tlb.h> 26#include <asm/tlb.h>
27#include <asm/fixmap.h>
26 28
27#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
28#include <asm/mach/map.h> 30#include <asm/mach/map.h>
@@ -32,19 +34,21 @@
32static unsigned long phys_initrd_start __initdata = 0; 34static unsigned long phys_initrd_start __initdata = 0;
33static unsigned long phys_initrd_size __initdata = 0; 35static unsigned long phys_initrd_size __initdata = 0;
34 36
35static void __init early_initrd(char **p) 37static int __init early_initrd(char *p)
36{ 38{
37 unsigned long start, size; 39 unsigned long start, size;
40 char *endp;
38 41
39 start = memparse(*p, p); 42 start = memparse(p, &endp);
40 if (**p == ',') { 43 if (*endp == ',') {
41 size = memparse((*p) + 1, p); 44 size = memparse(endp + 1, NULL);
42 45
43 phys_initrd_start = start; 46 phys_initrd_start = start;
44 phys_initrd_size = size; 47 phys_initrd_size = size;
45 } 48 }
49 return 0;
46} 50}
47__early_param("initrd=", early_initrd); 51early_param("initrd", early_initrd);
48 52
49static int __init parse_tag_initrd(const struct tag *tag) 53static int __init parse_tag_initrd(const struct tag *tag)
50{ 54{
@@ -82,9 +86,6 @@ void show_mem(void)
82 printk("Mem-info:\n"); 86 printk("Mem-info:\n");
83 show_free_areas(); 87 show_free_areas();
84 for_each_online_node(node) { 88 for_each_online_node(node) {
85 pg_data_t *n = NODE_DATA(node);
86 struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
87
88 for_each_nodebank (i,mi,node) { 89 for_each_nodebank (i,mi,node) {
89 struct membank *bank = &mi->bank[i]; 90 struct membank *bank = &mi->bank[i];
90 unsigned int pfn1, pfn2; 91 unsigned int pfn1, pfn2;
@@ -93,8 +94,8 @@ void show_mem(void)
93 pfn1 = bank_pfn_start(bank); 94 pfn1 = bank_pfn_start(bank);
94 pfn2 = bank_pfn_end(bank); 95 pfn2 = bank_pfn_end(bank);
95 96
96 page = map + pfn1; 97 page = pfn_to_page(pfn1);
97 end = map + pfn2; 98 end = pfn_to_page(pfn2 - 1) + 1;
98 99
99 do { 100 do {
100 total++; 101 total++;
@@ -560,7 +561,7 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi)
560 */ 561 */
561void __init mem_init(void) 562void __init mem_init(void)
562{ 563{
563 unsigned int codesize, datasize, initsize; 564 unsigned long reserved_pages, free_pages;
564 int i, node; 565 int i, node;
565 566
566#ifndef CONFIG_DISCONTIGMEM 567#ifndef CONFIG_DISCONTIGMEM
@@ -596,6 +597,30 @@ void __init mem_init(void)
596 totalram_pages += totalhigh_pages; 597 totalram_pages += totalhigh_pages;
597#endif 598#endif
598 599
600 reserved_pages = free_pages = 0;
601
602 for_each_online_node(node) {
603 for_each_nodebank(i, &meminfo, node) {
604 struct membank *bank = &meminfo.bank[i];
605 unsigned int pfn1, pfn2;
606 struct page *page, *end;
607
608 pfn1 = bank_pfn_start(bank);
609 pfn2 = bank_pfn_end(bank);
610
611 page = pfn_to_page(pfn1);
612 end = pfn_to_page(pfn2 - 1) + 1;
613
614 do {
615 if (PageReserved(page))
616 reserved_pages++;
617 else if (!page_count(page))
618 free_pages++;
619 page++;
620 } while (page < end);
621 }
622 }
623
599 /* 624 /*
600 * Since our memory may not be contiguous, calculate the 625 * Since our memory may not be contiguous, calculate the
601 * real number of pages we have in this system 626 * real number of pages we have in this system
@@ -608,15 +633,70 @@ void __init mem_init(void)
608 } 633 }
609 printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); 634 printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
610 635
611 codesize = _etext - _text; 636 printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
612 datasize = _end - _data; 637 nr_free_pages() << (PAGE_SHIFT-10),
613 initsize = __init_end - __init_begin; 638 free_pages << (PAGE_SHIFT-10),
639 reserved_pages << (PAGE_SHIFT-10),
640 totalhigh_pages << (PAGE_SHIFT-10));
641
642#define MLK(b, t) b, t, ((t) - (b)) >> 10
643#define MLM(b, t) b, t, ((t) - (b)) >> 20
644#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
614 645
615 printk(KERN_NOTICE "Memory: %luKB available (%dK code, " 646 printk(KERN_NOTICE "Virtual kernel memory layout:\n"
616 "%dK data, %dK init, %luK highmem)\n", 647 " vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
617 nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10, 648 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
618 datasize >> 10, initsize >> 10, 649#ifdef CONFIG_MMU
619 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); 650 " DMA : 0x%08lx - 0x%08lx (%4ld MB)\n"
651#endif
652 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
653 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
654#ifdef CONFIG_HIGHMEM
655 " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
656#endif
657 " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
658 " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
659 " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
660 " .data : 0x%p" " - 0x%p" " (%4d kB)\n",
661
662 MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
663 (PAGE_SIZE)),
664 MLK(FIXADDR_START, FIXADDR_TOP),
665#ifdef CONFIG_MMU
666 MLM(CONSISTENT_BASE, CONSISTENT_END),
667#endif
668 MLM(VMALLOC_START, VMALLOC_END),
669 MLM(PAGE_OFFSET, (unsigned long)high_memory),
670#ifdef CONFIG_HIGHMEM
671 MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
672 (PAGE_SIZE)),
673#endif
674 MLM(MODULES_VADDR, MODULES_END),
675
676 MLK_ROUNDUP(__init_begin, __init_end),
677 MLK_ROUNDUP(_text, _etext),
678 MLK_ROUNDUP(_data, _edata));
679
680#undef MLK
681#undef MLM
682#undef MLK_ROUNDUP
683
684 /*
685 * Check boundaries twice: Some fundamental inconsistencies can
686 * be detected at build time already.
687 */
688#ifdef CONFIG_MMU
689 BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);
690 BUG_ON(VMALLOC_END > CONSISTENT_BASE);
691
692 BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
693 BUG_ON(TASK_SIZE > MODULES_VADDR);
694#endif
695
696#ifdef CONFIG_HIGHMEM
697 BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
698 BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
699#endif
620 700
621 if (PAGE_SIZE >= 16384 && num_physpages <= 128) { 701 if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
622 extern int sysctl_overcommit_memory; 702 extern int sysctl_overcommit_memory;