2 * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
3 * Copyright (C) 2006 Atmark Techno, Inc.
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
10 #include <linux/bootmem.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/lmb.h>
14 #include <linux/mm.h> /* mem_init */
15 #include <linux/initrd.h>
16 #include <linux/pagemap.h>
17 #include <linux/pfn.h>
18 #include <linux/swap.h>
21 #include <asm/mmu_context.h>
22 #include <asm/pgalloc.h>
23 #include <asm/sections.h>
26 unsigned int __page_offset
;
27 /* EXPORT_SYMBOL(__page_offset); */
32 * Initialize the bootmem system and give it all the memory we
35 unsigned int memory_start
;
36 unsigned int memory_end
; /* due to mm/nommu.c */
37 unsigned int memory_size
;
40 * paging_init() sets up the page tables - in fact we've already done this.
42 static void __init
paging_init(void)
45 unsigned long zones_size
[MAX_NR_ZONES
];
48 * old: we can DMA to/from any address.put all page into ZONE_DMA
49 * We use only ZONE_NORMAL
51 zones_size
[ZONE_NORMAL
] = max_mapnr
;
53 /* every other zones are empty */
54 for (i
= 1; i
< MAX_NR_ZONES
; i
++)
57 free_area_init(zones_size
);
60 void __init
setup_memory(void)
63 unsigned long map_size
;
64 u32 kernel_align_start
, kernel_align_size
;
66 /* Find main memory where is the kernel */
67 for (i
= 0; i
< lmb
.memory
.cnt
; i
++) {
68 memory_start
= (u32
) lmb
.memory
.region
[i
].base
;
69 memory_end
= (u32
) lmb
.memory
.region
[i
].base
70 + (u32
) lmb
.memory
.region
[i
].size
;
71 if ((memory_start
<= (u32
)_text
) &&
72 ((u32
)_text
<= memory_end
)) {
73 memory_size
= memory_end
- memory_start
;
74 PAGE_OFFSET
= memory_start
;
75 printk(KERN_INFO
"%s: Main mem: 0x%x-0x%x, "
76 "size 0x%08x\n", __func__
, memory_start
,
77 memory_end
, memory_size
);
82 if (!memory_start
|| !memory_end
) {
83 panic("%s: Missing memory setting 0x%08x-0x%08x\n",
84 __func__
, memory_start
, memory_end
);
87 /* reservation of region where is the kernel */
88 kernel_align_start
= PAGE_DOWN((u32
)_text
);
89 /* ALIGN can be remove because _end in vmlinux.lds.S is align */
90 kernel_align_size
= PAGE_UP((u32
)klimit
) - kernel_align_start
;
91 lmb_reserve(kernel_align_start
, kernel_align_size
);
92 printk(KERN_INFO
"%s: kernel addr=0x%08x-0x%08x size=0x%08x\n",
93 __func__
, kernel_align_start
, kernel_align_start
94 + kernel_align_size
, kernel_align_size
);
98 * start: base phys address of kernel - page align
99 * end: base phys address of kernel - page align
101 * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
103 * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
104 * num_physpages - number of all pages
107 /* memory start is from the kernel end (aligned) to higher addr */
108 min_low_pfn
= memory_start
>> PAGE_SHIFT
; /* minimum for allocation */
109 /* RAM is assumed contiguous */
110 num_physpages
= max_mapnr
= memory_size
>> PAGE_SHIFT
;
111 max_pfn
= max_low_pfn
= memory_end
>> PAGE_SHIFT
;
113 printk(KERN_INFO
"%s: max_mapnr: %#lx\n", __func__
, max_mapnr
);
114 printk(KERN_INFO
"%s: min_low_pfn: %#lx\n", __func__
, min_low_pfn
);
115 printk(KERN_INFO
"%s: max_low_pfn: %#lx\n", __func__
, max_low_pfn
);
118 * Find an area to use for the bootmem bitmap.
119 * We look for the first area which is at least
120 * 128kB in length (128kB is enough for a bitmap
121 * for 4GB of memory, using 4kB pages), plus 1 page
122 * (in case the address isn't page-aligned).
124 map_size
= init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32
)_end
)),
125 min_low_pfn
, max_low_pfn
);
127 lmb_reserve(PFN_UP(TOPHYS((u32
)_end
)) << PAGE_SHIFT
, map_size
);
129 /* free bootmem is whole main memory */
130 free_bootmem(memory_start
, memory_size
);
132 /* reserve allocate blocks */
133 for (i
= 0; i
< lmb
.reserved
.cnt
; i
++) {
134 pr_debug("reserved %d - 0x%08x-0x%08x\n", i
,
135 (u32
) lmb
.reserved
.region
[i
].base
,
136 (u32
) lmb_size_bytes(&lmb
.reserved
, i
));
137 reserve_bootmem(lmb
.reserved
.region
[i
].base
,
138 lmb_size_bytes(&lmb
.reserved
, i
) - 1, BOOTMEM_DEFAULT
);
143 void free_init_pages(char *what
, unsigned long begin
, unsigned long end
)
147 for (addr
= begin
; addr
< end
; addr
+= PAGE_SIZE
) {
148 ClearPageReserved(virt_to_page(addr
));
149 init_page_count(virt_to_page(addr
));
150 memset((void *)addr
, 0xcc, PAGE_SIZE
);
154 printk(KERN_INFO
"Freeing %s: %ldk freed\n", what
, (end
- begin
) >> 10);
157 #ifdef CONFIG_BLK_DEV_INITRD
158 void free_initrd_mem(unsigned long start
, unsigned long end
)
161 for (; start
< end
; start
+= PAGE_SIZE
) {
162 ClearPageReserved(virt_to_page(start
));
163 init_page_count(virt_to_page(start
));
168 printk(KERN_NOTICE
"Freeing initrd memory: %dk freed\n", pages
);
172 void free_initmem(void)
174 free_init_pages("unused kernel memory",
175 (unsigned long)(&__init_begin
),
176 (unsigned long)(&__init_end
));
179 /* FIXME from arch/powerpc/mm/mem.c*/
182 printk(KERN_NOTICE
"%s\n", __func__
);
185 void __init
mem_init(void)
187 high_memory
= (void *)__va(memory_end
);
188 /* this will put all memory onto the freelists */
189 totalram_pages
+= free_all_bootmem();
191 printk(KERN_INFO
"Memory: %luk/%luk available\n",
192 (unsigned long) nr_free_pages() << (PAGE_SHIFT
-10),
193 num_physpages
<< (PAGE_SHIFT
-10));
196 /* Check against bounds of physical memory */
197 int ___range_ok(unsigned long addr
, unsigned long size
)
199 return ((addr
< memory_start
) ||
200 ((addr
+ size
) > memory_end
));