5e063e72b24a10c38b2c627bd1e8a9129da9810c
2 * Handle the memory map.
3 * The functions here do the job until bootmem takes over.
5 * Getting sanitize_e820_map() in sync with i386 version by applying change:
6 * - Provisions for empty E820 memory regions (reported by certain BIOSes).
7 * Alex Achenbach <xela@slit.de>, December 2002.
8 * Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/init.h>
14 #include <linux/bootmem.h>
15 #include <linux/ioport.h>
16 #include <linux/string.h>
17 #include <linux/kexec.h>
18 #include <linux/module.h>
20 #include <linux/pfn.h>
21 #include <linux/pci.h>
23 #include <asm/pgtable.h>
26 #include <asm/proto.h>
27 #include <asm/setup.h>
28 #include <asm/sections.h>
29 #include <asm/kdebug.h>
30 #include <asm/trampoline.h>
33 * PFN of last memory page.
35 unsigned long end_pfn
;
38 * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
39 * The direct mapping extends to max_pfn_mapped, so that we can directly access
40 * apertures, ACPI and other tables without having to play with fixmaps.
42 unsigned long max_pfn_mapped
;
45 * Last pfn which the user wants to use.
47 static unsigned long __initdata end_user_pfn
= MAXMEM
>>PAGE_SHIFT
;
50 * Find the highest page frame number we have available
52 unsigned long __init
e820_end_of_ram(void)
54 unsigned long last_pfn
;
56 last_pfn
= find_max_pfn_with_active_regions();
58 if (last_pfn
> max_pfn_mapped
)
59 max_pfn_mapped
= last_pfn
;
60 if (max_pfn_mapped
> MAXMEM
>>PAGE_SHIFT
)
61 max_pfn_mapped
= MAXMEM
>>PAGE_SHIFT
;
62 if (last_pfn
> end_user_pfn
)
63 last_pfn
= end_user_pfn
;
64 if (last_pfn
> max_pfn_mapped
)
65 last_pfn
= max_pfn_mapped
;
67 printk(KERN_INFO
"max_pfn_mapped = %lu\n", max_pfn_mapped
);
72 * Mark e820 reserved areas as busy for the resource manager.
74 void __init
e820_reserve_resources(void)
79 res
= alloc_bootmem_low(sizeof(struct resource
) * e820
.nr_map
);
80 for (i
= 0; i
< e820
.nr_map
; i
++) {
81 switch (e820
.map
[i
].type
) {
82 case E820_RAM
: res
->name
= "System RAM"; break;
83 case E820_ACPI
: res
->name
= "ACPI Tables"; break;
84 case E820_NVS
: res
->name
= "ACPI Non-volatile Storage"; break;
85 default: res
->name
= "reserved";
87 res
->start
= e820
.map
[i
].addr
;
88 res
->end
= res
->start
+ e820
.map
[i
].size
- 1;
89 res
->flags
= IORESOURCE_MEM
| IORESOURCE_BUSY
;
90 insert_resource(&iomem_resource
, res
);
96 * Finds an active region in the address range from start_pfn to last_pfn and
97 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
99 static int __init
e820_find_active_region(const struct e820entry
*ei
,
100 unsigned long start_pfn
,
101 unsigned long last_pfn
,
102 unsigned long *ei_startpfn
,
103 unsigned long *ei_endpfn
)
105 *ei_startpfn
= round_up(ei
->addr
, PAGE_SIZE
) >> PAGE_SHIFT
;
106 *ei_endpfn
= round_down(ei
->addr
+ ei
->size
, PAGE_SIZE
) >> PAGE_SHIFT
;
108 /* Skip map entries smaller than a page */
109 if (*ei_startpfn
>= *ei_endpfn
)
112 /* Check if max_pfn_mapped should be updated */
113 if (ei
->type
!= E820_RAM
&& *ei_endpfn
> max_pfn_mapped
)
114 max_pfn_mapped
= *ei_endpfn
;
116 /* Skip if map is outside the node */
117 if (ei
->type
!= E820_RAM
|| *ei_endpfn
<= start_pfn
||
118 *ei_startpfn
>= last_pfn
)
121 /* Check for overlaps */
122 if (*ei_startpfn
< start_pfn
)
123 *ei_startpfn
= start_pfn
;
124 if (*ei_endpfn
> last_pfn
)
125 *ei_endpfn
= last_pfn
;
127 /* Obey end_user_pfn to save on memmap */
128 if (*ei_startpfn
>= end_user_pfn
)
130 if (*ei_endpfn
> end_user_pfn
)
131 *ei_endpfn
= end_user_pfn
;
136 /* Walk the e820 map and register active regions within a node */
138 e820_register_active_regions(int nid
, unsigned long start_pfn
,
139 unsigned long last_pfn
)
141 unsigned long ei_startpfn
;
142 unsigned long ei_endpfn
;
145 for (i
= 0; i
< e820
.nr_map
; i
++)
146 if (e820_find_active_region(&e820
.map
[i
],
148 &ei_startpfn
, &ei_endpfn
))
149 add_active_range(nid
, ei_startpfn
, ei_endpfn
);
153 * Find the hole size (in bytes) in the memory range.
154 * @start: starting address of the memory range to scan
155 * @end: ending address of the memory range to scan
157 unsigned long __init
e820_hole_size(unsigned long start
, unsigned long end
)
159 unsigned long start_pfn
= start
>> PAGE_SHIFT
;
160 unsigned long last_pfn
= end
>> PAGE_SHIFT
;
161 unsigned long ei_startpfn
, ei_endpfn
, ram
= 0;
164 for (i
= 0; i
< e820
.nr_map
; i
++) {
165 if (e820_find_active_region(&e820
.map
[i
],
167 &ei_startpfn
, &ei_endpfn
))
168 ram
+= ei_endpfn
- ei_startpfn
;
170 return end
- start
- (ram
<< PAGE_SHIFT
);
173 static void early_panic(char *msg
)
179 /* We're not void only for x86 32-bit compat */
180 char *__init
machine_specific_memory_setup(void)
182 char *who
= "BIOS-e820";
185 * Try to copy the BIOS-supplied E820-map.
187 * Otherwise fake a memory map; one section from 0k->640k,
188 * the next section from 1mb->appropriate_mem_k
190 new_nr
= boot_params
.e820_entries
;
191 sanitize_e820_map(boot_params
.e820_map
,
192 ARRAY_SIZE(boot_params
.e820_map
),
194 boot_params
.e820_entries
= new_nr
;
195 if (copy_e820_map(boot_params
.e820_map
, boot_params
.e820_entries
) < 0)
196 early_panic("Cannot find a valid memory map");
197 printk(KERN_INFO
"BIOS-provided physical RAM map:\n");
200 /* In case someone cares... */
204 static int __init
parse_memopt(char *p
)
208 end_user_pfn
= memparse(p
, &p
);
209 end_user_pfn
>>= PAGE_SHIFT
;
212 early_param("mem", parse_memopt
);
214 static int userdef __initdata
;
216 static int __init
parse_memmap_opt(char *p
)
219 unsigned long long start_at
, mem_size
;
221 if (!strcmp(p
, "exactmap")) {
222 #ifdef CONFIG_CRASH_DUMP
224 * If we are doing a crash dump, we still need to know
225 * the real mem size before original memory map is
228 e820_register_active_regions(0, 0, -1UL);
229 saved_max_pfn
= e820_end_of_ram();
230 remove_all_active_ranges();
239 mem_size
= memparse(p
, &p
);
245 start_at
= memparse(p
+1, &p
);
246 add_memory_region(start_at
, mem_size
, E820_RAM
);
247 } else if (*p
== '#') {
248 start_at
= memparse(p
+1, &p
);
249 add_memory_region(start_at
, mem_size
, E820_ACPI
);
250 } else if (*p
== '$') {
251 start_at
= memparse(p
+1, &p
);
252 add_memory_region(start_at
, mem_size
, E820_RESERVED
);
254 end_user_pfn
= (mem_size
>> PAGE_SHIFT
);
256 return *p
== '\0' ? 0 : -EINVAL
;
258 early_param("memmap", parse_memmap_opt
);
260 void __init
finish_e820_parsing(void)
263 int nr
= e820
.nr_map
;
265 if (sanitize_e820_map(e820
.map
, ARRAY_SIZE(e820
.map
), &nr
) < 0)
266 early_panic("Invalid user supplied memory map");
269 printk(KERN_INFO
"user-defined physical RAM map:\n");
270 e820_print_map("user");
274 int __init
arch_get_ram_range(int slot
, u64
*addr
, u64
*size
)
278 if (slot
< 0 || slot
>= e820
.nr_map
)
280 for (i
= slot
; i
< e820
.nr_map
; i
++) {
281 if (e820
.map
[i
].type
!= E820_RAM
)
285 if (i
== e820
.nr_map
|| e820
.map
[i
].addr
> (max_pfn
<< PAGE_SHIFT
))
287 *addr
= e820
.map
[i
].addr
;
288 *size
= min_t(u64
, e820
.map
[i
].size
+ e820
.map
[i
].addr
,
289 max_pfn
<< PAGE_SHIFT
) - *addr
;