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/suspend.h>
21 #include <linux/pfn.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 end_pfn
;
56 end_pfn
= find_max_pfn_with_active_regions();
58 if (end_pfn
> max_pfn_mapped
)
59 max_pfn_mapped
= end_pfn
;
60 if (max_pfn_mapped
> MAXMEM
>>PAGE_SHIFT
)
61 max_pfn_mapped
= MAXMEM
>>PAGE_SHIFT
;
62 if (end_pfn
> end_user_pfn
)
63 end_pfn
= end_user_pfn
;
64 if (end_pfn
> max_pfn_mapped
)
65 end_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 * Find the ranges of physical addresses that do not correspond to
97 * e820 RAM areas and mark the corresponding pages as nosave for software
98 * suspend and suspend to RAM.
100 * This function requires the e820 map to be sorted and without any
101 * overlapping entries and assumes the first e820 area to be RAM.
103 void __init
e820_mark_nosave_regions(void)
108 paddr
= round_down(e820
.map
[0].addr
+ e820
.map
[0].size
, PAGE_SIZE
);
109 for (i
= 1; i
< e820
.nr_map
; i
++) {
110 struct e820entry
*ei
= &e820
.map
[i
];
112 if (paddr
< ei
->addr
)
113 register_nosave_region(PFN_DOWN(paddr
),
116 paddr
= round_down(ei
->addr
+ ei
->size
, PAGE_SIZE
);
117 if (ei
->type
!= E820_RAM
)
118 register_nosave_region(PFN_UP(ei
->addr
),
121 if (paddr
>= (end_pfn
<< PAGE_SHIFT
))
127 * Finds an active region in the address range from start_pfn to end_pfn and
128 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
130 static int __init
e820_find_active_region(const struct e820entry
*ei
,
131 unsigned long start_pfn
,
132 unsigned long end_pfn
,
133 unsigned long *ei_startpfn
,
134 unsigned long *ei_endpfn
)
136 *ei_startpfn
= round_up(ei
->addr
, PAGE_SIZE
) >> PAGE_SHIFT
;
137 *ei_endpfn
= round_down(ei
->addr
+ ei
->size
, PAGE_SIZE
) >> PAGE_SHIFT
;
139 /* Skip map entries smaller than a page */
140 if (*ei_startpfn
>= *ei_endpfn
)
143 /* Check if max_pfn_mapped should be updated */
144 if (ei
->type
!= E820_RAM
&& *ei_endpfn
> max_pfn_mapped
)
145 max_pfn_mapped
= *ei_endpfn
;
147 /* Skip if map is outside the node */
148 if (ei
->type
!= E820_RAM
|| *ei_endpfn
<= start_pfn
||
149 *ei_startpfn
>= end_pfn
)
152 /* Check for overlaps */
153 if (*ei_startpfn
< start_pfn
)
154 *ei_startpfn
= start_pfn
;
155 if (*ei_endpfn
> end_pfn
)
156 *ei_endpfn
= end_pfn
;
158 /* Obey end_user_pfn to save on memmap */
159 if (*ei_startpfn
>= end_user_pfn
)
161 if (*ei_endpfn
> end_user_pfn
)
162 *ei_endpfn
= end_user_pfn
;
167 /* Walk the e820 map and register active regions within a node */
169 e820_register_active_regions(int nid
, unsigned long start_pfn
,
170 unsigned long end_pfn
)
172 unsigned long ei_startpfn
;
173 unsigned long ei_endpfn
;
176 for (i
= 0; i
< e820
.nr_map
; i
++)
177 if (e820_find_active_region(&e820
.map
[i
],
179 &ei_startpfn
, &ei_endpfn
))
180 add_active_range(nid
, ei_startpfn
, ei_endpfn
);
184 * Find the hole size (in bytes) in the memory range.
185 * @start: starting address of the memory range to scan
186 * @end: ending address of the memory range to scan
188 unsigned long __init
e820_hole_size(unsigned long start
, unsigned long end
)
190 unsigned long start_pfn
= start
>> PAGE_SHIFT
;
191 unsigned long end_pfn
= end
>> PAGE_SHIFT
;
192 unsigned long ei_startpfn
, ei_endpfn
, ram
= 0;
195 for (i
= 0; i
< e820
.nr_map
; i
++) {
196 if (e820_find_active_region(&e820
.map
[i
],
198 &ei_startpfn
, &ei_endpfn
))
199 ram
+= ei_endpfn
- ei_startpfn
;
201 return end
- start
- (ram
<< PAGE_SHIFT
);
204 static void early_panic(char *msg
)
210 /* We're not void only for x86 32-bit compat */
211 char *__init
machine_specific_memory_setup(void)
213 char *who
= "BIOS-e820";
216 * Try to copy the BIOS-supplied E820-map.
218 * Otherwise fake a memory map; one section from 0k->640k,
219 * the next section from 1mb->appropriate_mem_k
221 new_nr
= boot_params
.e820_entries
;
222 sanitize_e820_map(boot_params
.e820_map
,
223 ARRAY_SIZE(boot_params
.e820_map
),
225 boot_params
.e820_entries
= new_nr
;
226 if (copy_e820_map(boot_params
.e820_map
, boot_params
.e820_entries
) < 0)
227 early_panic("Cannot find a valid memory map");
228 printk(KERN_INFO
"BIOS-provided physical RAM map:\n");
231 /* In case someone cares... */
235 static int __init
parse_memopt(char *p
)
239 end_user_pfn
= memparse(p
, &p
);
240 end_user_pfn
>>= PAGE_SHIFT
;
243 early_param("mem", parse_memopt
);
245 static int userdef __initdata
;
247 static int __init
parse_memmap_opt(char *p
)
250 unsigned long long start_at
, mem_size
;
252 if (!strcmp(p
, "exactmap")) {
253 #ifdef CONFIG_CRASH_DUMP
255 * If we are doing a crash dump, we still need to know
256 * the real mem size before original memory map is
259 e820_register_active_regions(0, 0, -1UL);
260 saved_max_pfn
= e820_end_of_ram();
261 remove_all_active_ranges();
270 mem_size
= memparse(p
, &p
);
276 start_at
= memparse(p
+1, &p
);
277 add_memory_region(start_at
, mem_size
, E820_RAM
);
278 } else if (*p
== '#') {
279 start_at
= memparse(p
+1, &p
);
280 add_memory_region(start_at
, mem_size
, E820_ACPI
);
281 } else if (*p
== '$') {
282 start_at
= memparse(p
+1, &p
);
283 add_memory_region(start_at
, mem_size
, E820_RESERVED
);
285 end_user_pfn
= (mem_size
>> PAGE_SHIFT
);
287 return *p
== '\0' ? 0 : -EINVAL
;
289 early_param("memmap", parse_memmap_opt
);
291 void __init
finish_e820_parsing(void)
294 int nr
= e820
.nr_map
;
296 if (sanitize_e820_map(e820
.map
, ARRAY_SIZE(e820
.map
), &nr
) < 0)
297 early_panic("Invalid user supplied memory map");
300 printk(KERN_INFO
"user-defined physical RAM map:\n");
301 e820_print_map("user");
305 int __init
arch_get_ram_range(int slot
, u64
*addr
, u64
*size
)
309 if (slot
< 0 || slot
>= e820
.nr_map
)
311 for (i
= slot
; i
< e820
.nr_map
; i
++) {
312 if (e820
.map
[i
].type
!= E820_RAM
)
316 if (i
== e820
.nr_map
|| e820
.map
[i
].addr
> (max_pfn
<< PAGE_SHIFT
))
318 *addr
= e820
.map
[i
].addr
;
319 *size
= min_t(u64
, e820
.map
[i
].size
+ e820
.map
[i
].addr
,
320 max_pfn
<< PAGE_SHIFT
) - *addr
;
This page took 0.0424099999999999 seconds and 6 git commands to generate.