2 * arch/xtensa/mm/init.c
4 * Derived from MIPS, PPC.
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
12 * Chris Zankel <chris@zankel.net>
13 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/bootmem.h>
21 #include <linux/gfp.h>
22 #include <linux/swap.h>
23 #include <linux/mman.h>
24 #include <linux/nodemask.h>
27 #include <asm/bootparam.h>
29 #include <asm/sections.h>
32 * mem_reserve(start, end, must_exist)
34 * Reserve some memory from the memory pool.
37 * start Start of region,
39 * must_exist Must exist in memory pool.
42 * 0 (memory area couldn't be mapped)
46 int __init
mem_reserve(unsigned long start
, unsigned long end
, int must_exist
)
53 start
= start
& PAGE_MASK
;
54 end
= PAGE_ALIGN(end
);
56 for (i
= 0; i
< sysmem
.nr_banks
; i
++)
57 if (start
< sysmem
.bank
[i
].end
58 && end
>= sysmem
.bank
[i
].start
)
61 if (i
== sysmem
.nr_banks
) {
63 printk (KERN_WARNING
"mem_reserve: [0x%0lx, 0x%0lx) "
64 "not in any region!\n", start
, end
);
68 if (start
> sysmem
.bank
[i
].start
) {
69 if (end
< sysmem
.bank
[i
].end
) {
71 if (sysmem
.nr_banks
>= SYSMEM_BANKS_MAX
)
72 panic("meminfo overflow\n");
73 sysmem
.bank
[sysmem
.nr_banks
].start
= end
;
74 sysmem
.bank
[sysmem
.nr_banks
].end
= sysmem
.bank
[i
].end
;
77 sysmem
.bank
[i
].end
= start
;
79 if (end
< sysmem
.bank
[i
].end
)
80 sysmem
.bank
[i
].start
= end
;
84 sysmem
.bank
[i
].start
= sysmem
.bank
[sysmem
.nr_banks
].start
;
85 sysmem
.bank
[i
].end
= sysmem
.bank
[sysmem
.nr_banks
].end
;
93 * Initialize the bootmem system and give it all the memory we have available.
96 void __init
bootmem_init(void)
99 unsigned long bootmap_start
, bootmap_size
;
102 max_low_pfn
= max_pfn
= 0;
105 for (i
=0; i
< sysmem
.nr_banks
; i
++) {
106 pfn
= PAGE_ALIGN(sysmem
.bank
[i
].start
) >> PAGE_SHIFT
;
107 if (pfn
< min_low_pfn
)
109 pfn
= PAGE_ALIGN(sysmem
.bank
[i
].end
- 1) >> PAGE_SHIFT
;
114 if (min_low_pfn
> max_pfn
)
115 panic("No memory found!\n");
117 max_low_pfn
= max_pfn
< MAX_MEM_PFN
>> PAGE_SHIFT
?
118 max_pfn
: MAX_MEM_PFN
>> PAGE_SHIFT
;
120 /* Find an area to use for the bootmem bitmap. */
122 bootmap_size
= bootmem_bootmap_pages(max_low_pfn
- min_low_pfn
);
123 bootmap_size
<<= PAGE_SHIFT
;
126 for (i
=0; i
<sysmem
.nr_banks
; i
++)
127 if (sysmem
.bank
[i
].end
- sysmem
.bank
[i
].start
>= bootmap_size
) {
128 bootmap_start
= sysmem
.bank
[i
].start
;
132 if (bootmap_start
== ~0UL)
133 panic("Cannot find %ld bytes for bootmap\n", bootmap_size
);
135 /* Reserve the bootmem bitmap area */
137 mem_reserve(bootmap_start
, bootmap_start
+ bootmap_size
, 1);
138 bootmap_size
= init_bootmem_node(NODE_DATA(0),
139 bootmap_start
>> PAGE_SHIFT
,
143 /* Add all remaining memory pieces into the bootmem map */
145 for (i
=0; i
<sysmem
.nr_banks
; i
++)
146 free_bootmem(sysmem
.bank
[i
].start
,
147 sysmem
.bank
[i
].end
- sysmem
.bank
[i
].start
);
152 void __init
zones_init(void)
154 unsigned long zones_size
[MAX_NR_ZONES
];
157 /* All pages are DMA-able, so we put them all in the DMA zone. */
159 zones_size
[ZONE_DMA
] = max_low_pfn
- ARCH_PFN_OFFSET
;
160 for (i
= 1; i
< MAX_NR_ZONES
; i
++)
163 #ifdef CONFIG_HIGHMEM
164 zones_size
[ZONE_HIGHMEM
] = max_pfn
- max_low_pfn
;
167 free_area_init_node(0, zones_size
, ARCH_PFN_OFFSET
, NULL
);
171 * Initialize memory pages.
174 void __init
mem_init(void)
176 unsigned long codesize
, reservedpages
, datasize
, initsize
;
177 unsigned long highmemsize
, tmp
, ram
;
179 max_mapnr
= num_physpages
= max_low_pfn
- ARCH_PFN_OFFSET
;
180 high_memory
= (void *) __va(max_low_pfn
<< PAGE_SHIFT
);
183 #ifdef CONFIG_HIGHMEM
184 #error HIGHGMEM not implemented in init.c
187 totalram_pages
+= free_all_bootmem();
189 reservedpages
= ram
= 0;
190 for (tmp
= 0; tmp
< max_mapnr
; tmp
++) {
192 if (PageReserved(mem_map
+tmp
))
196 codesize
= (unsigned long) _etext
- (unsigned long) _stext
;
197 datasize
= (unsigned long) _edata
- (unsigned long) _sdata
;
198 initsize
= (unsigned long) __init_end
- (unsigned long) __init_begin
;
200 printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
201 "%ldk data, %ldk init %ldk highmem)\n",
202 nr_free_pages() << (PAGE_SHIFT
-10),
203 ram
<< (PAGE_SHIFT
-10),
205 reservedpages
<< (PAGE_SHIFT
-10),
212 free_reserved_mem(void *start
, void *end
)
214 for (; start
< end
; start
+= PAGE_SIZE
) {
215 ClearPageReserved(virt_to_page(start
));
216 init_page_count(virt_to_page(start
));
217 free_page((unsigned long)start
);
222 #ifdef CONFIG_BLK_DEV_INITRD
223 extern int initrd_is_mapped
;
225 void free_initrd_mem(unsigned long start
, unsigned long end
)
227 if (initrd_is_mapped
) {
228 free_reserved_mem((void*)start
, (void*)end
);
229 printk ("Freeing initrd memory: %ldk freed\n",(end
-start
)>>10);
234 void free_initmem(void)
236 free_reserved_mem(__init_begin
, __init_end
);
237 printk("Freeing unused kernel memory: %zuk freed\n",
238 (__init_end
- __init_begin
) >> 10);