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 } else if (end
< sysmem
.bank
[i
].end
) {
80 sysmem
.bank
[i
].start
= end
;
85 sysmem
.bank
[i
].start
= sysmem
.bank
[sysmem
.nr_banks
].start
;
86 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 max_mapnr
= max_low_pfn
- ARCH_PFN_OFFSET
;
177 high_memory
= (void *) __va(max_low_pfn
<< PAGE_SHIFT
);
179 #ifdef CONFIG_HIGHMEM
180 #error HIGHGMEM not implemented in init.c
185 mem_init_print_info(NULL
);
188 #ifdef CONFIG_BLK_DEV_INITRD
189 extern int initrd_is_mapped
;
191 void free_initrd_mem(unsigned long start
, unsigned long end
)
193 if (initrd_is_mapped
)
194 free_reserved_area((void *)start
, (void *)end
, -1, "initrd");
198 void free_initmem(void)
200 free_initmem_default(-1);