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
> MAXMEM
>>PAGE_SHIFT
)
59 last_pfn
= MAXMEM
>>PAGE_SHIFT
;
60 if (last_pfn
> end_user_pfn
)
61 last_pfn
= end_user_pfn
;
63 printk(KERN_INFO
"last_pfn = %lu\n", last_pfn
);
68 * Mark e820 reserved areas as busy for the resource manager.
70 void __init
e820_reserve_resources(void)
75 res
= alloc_bootmem_low(sizeof(struct resource
) * e820
.nr_map
);
76 for (i
= 0; i
< e820
.nr_map
; i
++) {
77 switch (e820
.map
[i
].type
) {
78 case E820_RAM
: res
->name
= "System RAM"; break;
79 case E820_ACPI
: res
->name
= "ACPI Tables"; break;
80 case E820_NVS
: res
->name
= "ACPI Non-volatile Storage"; break;
81 default: res
->name
= "reserved";
83 res
->start
= e820
.map
[i
].addr
;
84 res
->end
= res
->start
+ e820
.map
[i
].size
- 1;
85 res
->flags
= IORESOURCE_MEM
| IORESOURCE_BUSY
;
86 insert_resource(&iomem_resource
, res
);
92 * Finds an active region in the address range from start_pfn to last_pfn and
93 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
95 static int __init
e820_find_active_region(const struct e820entry
*ei
,
96 unsigned long start_pfn
,
97 unsigned long last_pfn
,
98 unsigned long *ei_startpfn
,
99 unsigned long *ei_endpfn
)
101 *ei_startpfn
= round_up(ei
->addr
, PAGE_SIZE
) >> PAGE_SHIFT
;
102 *ei_endpfn
= round_down(ei
->addr
+ ei
->size
, PAGE_SIZE
) >> PAGE_SHIFT
;
104 /* Skip map entries smaller than a page */
105 if (*ei_startpfn
>= *ei_endpfn
)
108 /* Skip if map is outside the node */
109 if (ei
->type
!= E820_RAM
|| *ei_endpfn
<= start_pfn
||
110 *ei_startpfn
>= last_pfn
)
113 /* Check for overlaps */
114 if (*ei_startpfn
< start_pfn
)
115 *ei_startpfn
= start_pfn
;
116 if (*ei_endpfn
> last_pfn
)
117 *ei_endpfn
= last_pfn
;
119 /* Obey end_user_pfn to save on memmap */
120 if (*ei_startpfn
>= end_user_pfn
)
122 if (*ei_endpfn
> end_user_pfn
)
123 *ei_endpfn
= end_user_pfn
;
128 /* Walk the e820 map and register active regions within a node */
130 e820_register_active_regions(int nid
, unsigned long start_pfn
,
131 unsigned long last_pfn
)
133 unsigned long ei_startpfn
;
134 unsigned long ei_endpfn
;
137 for (i
= 0; i
< e820
.nr_map
; i
++)
138 if (e820_find_active_region(&e820
.map
[i
],
140 &ei_startpfn
, &ei_endpfn
))
141 add_active_range(nid
, ei_startpfn
, ei_endpfn
);
145 * Find the hole size (in bytes) in the memory range.
146 * @start: starting address of the memory range to scan
147 * @end: ending address of the memory range to scan
149 unsigned long __init
e820_hole_size(unsigned long start
, unsigned long end
)
151 unsigned long start_pfn
= start
>> PAGE_SHIFT
;
152 unsigned long last_pfn
= end
>> PAGE_SHIFT
;
153 unsigned long ei_startpfn
, ei_endpfn
, ram
= 0;
156 for (i
= 0; i
< e820
.nr_map
; i
++) {
157 if (e820_find_active_region(&e820
.map
[i
],
159 &ei_startpfn
, &ei_endpfn
))
160 ram
+= ei_endpfn
- ei_startpfn
;
162 return end
- start
- (ram
<< PAGE_SHIFT
);
165 static void early_panic(char *msg
)
171 /* We're not void only for x86 32-bit compat */
172 char *__init
machine_specific_memory_setup(void)
174 char *who
= "BIOS-e820";
177 * Try to copy the BIOS-supplied E820-map.
179 * Otherwise fake a memory map; one section from 0k->640k,
180 * the next section from 1mb->appropriate_mem_k
182 new_nr
= boot_params
.e820_entries
;
183 sanitize_e820_map(boot_params
.e820_map
,
184 ARRAY_SIZE(boot_params
.e820_map
),
186 boot_params
.e820_entries
= new_nr
;
187 if (copy_e820_map(boot_params
.e820_map
, boot_params
.e820_entries
) < 0)
188 early_panic("Cannot find a valid memory map");
189 printk(KERN_INFO
"BIOS-provided physical RAM map:\n");
192 /* In case someone cares... */
196 static int __init
parse_memopt(char *p
)
200 end_user_pfn
= memparse(p
, &p
);
201 end_user_pfn
>>= PAGE_SHIFT
;
204 early_param("mem", parse_memopt
);
206 static int userdef __initdata
;
208 static int __init
parse_memmap_opt(char *p
)
211 unsigned long long start_at
, mem_size
;
213 if (!strcmp(p
, "exactmap")) {
214 #ifdef CONFIG_CRASH_DUMP
216 * If we are doing a crash dump, we still need to know
217 * the real mem size before original memory map is
220 e820_register_active_regions(0, 0, -1UL);
221 saved_max_pfn
= e820_end_of_ram();
222 remove_all_active_ranges();
230 mem_size
= memparse(p
, &p
);
236 start_at
= memparse(p
+1, &p
);
237 add_memory_region(start_at
, mem_size
, E820_RAM
);
238 } else if (*p
== '#') {
239 start_at
= memparse(p
+1, &p
);
240 add_memory_region(start_at
, mem_size
, E820_ACPI
);
241 } else if (*p
== '$') {
242 start_at
= memparse(p
+1, &p
);
243 add_memory_region(start_at
, mem_size
, E820_RESERVED
);
245 end_user_pfn
= (mem_size
>> PAGE_SHIFT
);
247 return *p
== '\0' ? 0 : -EINVAL
;
249 early_param("memmap", parse_memmap_opt
);
251 void __init
finish_e820_parsing(void)
254 int nr
= e820
.nr_map
;
256 if (sanitize_e820_map(e820
.map
, ARRAY_SIZE(e820
.map
), &nr
) < 0)
257 early_panic("Invalid user supplied memory map");
260 printk(KERN_INFO
"user-defined physical RAM map:\n");
261 e820_print_map("user");
265 int __init
arch_get_ram_range(int slot
, u64
*addr
, u64
*size
)
269 if (slot
< 0 || slot
>= e820
.nr_map
)
271 for (i
= slot
; i
< e820
.nr_map
; i
++) {
272 if (e820
.map
[i
].type
!= E820_RAM
)
276 if (i
== e820
.nr_map
|| e820
.map
[i
].addr
> (max_pfn
<< PAGE_SHIFT
))
278 *addr
= e820
.map
[i
].addr
;
279 *size
= min_t(u64
, e820
.map
[i
].size
+ e820
.map
[i
].addr
,
280 max_pfn
<< PAGE_SHIFT
) - *addr
;