]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/e820_32.c
x86: make e820.c to have common functions
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / e820_32.c
1 #include <linux/kernel.h>
2 #include <linux/types.h>
3 #include <linux/init.h>
4 #include <linux/bootmem.h>
5 #include <linux/ioport.h>
6 #include <linux/string.h>
7 #include <linux/kexec.h>
8 #include <linux/module.h>
9 #include <linux/mm.h>
10 #include <linux/pfn.h>
11 #include <linux/uaccess.h>
12 #include <linux/suspend.h>
13
14 #include <asm/pgtable.h>
15 #include <asm/page.h>
16 #include <asm/e820.h>
17 #include <asm/setup.h>
18
19 static struct resource system_rom_resource = {
20         .name   = "System ROM",
21         .start  = 0xf0000,
22         .end    = 0xfffff,
23         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
24 };
25
26 static struct resource extension_rom_resource = {
27         .name   = "Extension ROM",
28         .start  = 0xe0000,
29         .end    = 0xeffff,
30         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
31 };
32
33 static struct resource adapter_rom_resources[] = { {
34         .name   = "Adapter ROM",
35         .start  = 0xc8000,
36         .end    = 0,
37         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
38 }, {
39         .name   = "Adapter ROM",
40         .start  = 0,
41         .end    = 0,
42         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
43 }, {
44         .name   = "Adapter ROM",
45         .start  = 0,
46         .end    = 0,
47         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
48 }, {
49         .name   = "Adapter ROM",
50         .start  = 0,
51         .end    = 0,
52         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
53 }, {
54         .name   = "Adapter ROM",
55         .start  = 0,
56         .end    = 0,
57         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
58 }, {
59         .name   = "Adapter ROM",
60         .start  = 0,
61         .end    = 0,
62         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
63 } };
64
65 static struct resource video_rom_resource = {
66         .name   = "Video ROM",
67         .start  = 0xc0000,
68         .end    = 0xc7fff,
69         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
70 };
71
72 #define ROMSIGNATURE 0xaa55
73
74 static int __init romsignature(const unsigned char *rom)
75 {
76         const unsigned short * const ptr = (const unsigned short *)rom;
77         unsigned short sig;
78
79         return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
80 }
81
82 static int __init romchecksum(const unsigned char *rom, unsigned long length)
83 {
84         unsigned char sum, c;
85
86         for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
87                 sum += c;
88         return !length && !sum;
89 }
90
91 static void __init probe_roms(void)
92 {
93         const unsigned char *rom;
94         unsigned long start, length, upper;
95         unsigned char c;
96         int i;
97
98         /* video rom */
99         upper = adapter_rom_resources[0].start;
100         for (start = video_rom_resource.start; start < upper; start += 2048) {
101                 rom = isa_bus_to_virt(start);
102                 if (!romsignature(rom))
103                         continue;
104
105                 video_rom_resource.start = start;
106
107                 if (probe_kernel_address(rom + 2, c) != 0)
108                         continue;
109
110                 /* 0 < length <= 0x7f * 512, historically */
111                 length = c * 512;
112
113                 /* if checksum okay, trust length byte */
114                 if (length && romchecksum(rom, length))
115                         video_rom_resource.end = start + length - 1;
116
117                 request_resource(&iomem_resource, &video_rom_resource);
118                 break;
119         }
120
121         start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
122         if (start < upper)
123                 start = upper;
124
125         /* system rom */
126         request_resource(&iomem_resource, &system_rom_resource);
127         upper = system_rom_resource.start;
128
129         /* check for extension rom (ignore length byte!) */
130         rom = isa_bus_to_virt(extension_rom_resource.start);
131         if (romsignature(rom)) {
132                 length = extension_rom_resource.end - extension_rom_resource.start + 1;
133                 if (romchecksum(rom, length)) {
134                         request_resource(&iomem_resource, &extension_rom_resource);
135                         upper = extension_rom_resource.start;
136                 }
137         }
138
139         /* check for adapter roms on 2k boundaries */
140         for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
141                 rom = isa_bus_to_virt(start);
142                 if (!romsignature(rom))
143                         continue;
144
145                 if (probe_kernel_address(rom + 2, c) != 0)
146                         continue;
147
148                 /* 0 < length <= 0x7f * 512, historically */
149                 length = c * 512;
150
151                 /* but accept any length that fits if checksum okay */
152                 if (!length || start + length > upper || !romchecksum(rom, length))
153                         continue;
154
155                 adapter_rom_resources[i].start = start;
156                 adapter_rom_resources[i].end = start + length - 1;
157                 request_resource(&iomem_resource, &adapter_rom_resources[i]);
158
159                 start = adapter_rom_resources[i++].end & ~2047UL;
160         }
161 }
162
163 /*
164  * Request address space for all standard RAM and ROM resources
165  * and also for regions reported as reserved by the e820.
166  */
167 void __init init_iomem_resources(struct resource *code_resource,
168                 struct resource *data_resource,
169                 struct resource *bss_resource)
170 {
171         int i;
172
173         probe_roms();
174         for (i = 0; i < e820.nr_map; i++) {
175                 struct resource *res;
176 #ifndef CONFIG_RESOURCES_64BIT
177                 if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
178                         continue;
179 #endif
180                 res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
181                 switch (e820.map[i].type) {
182                 case E820_RAM:  res->name = "System RAM"; break;
183                 case E820_ACPI: res->name = "ACPI Tables"; break;
184                 case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
185                 default:        res->name = "reserved";
186                 }
187                 res->start = e820.map[i].addr;
188                 res->end = res->start + e820.map[i].size - 1;
189                 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
190                 if (request_resource(&iomem_resource, res)) {
191                         kfree(res);
192                         continue;
193                 }
194                 if (e820.map[i].type == E820_RAM) {
195                         /*
196                          *  We don't know which RAM region contains kernel data,
197                          *  so we try it repeatedly and let the resource manager
198                          *  test it.
199                          */
200                         request_resource(res, code_resource);
201                         request_resource(res, data_resource);
202                         request_resource(res, bss_resource);
203 #ifdef CONFIG_KEXEC
204                         if (crashk_res.start != crashk_res.end)
205                                 request_resource(res, &crashk_res);
206 #endif
207                 }
208         }
209 }
210
211 #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION)
212 /**
213  * e820_mark_nosave_regions - Find the ranges of physical addresses that do not
214  * correspond to e820 RAM areas and mark the corresponding pages as nosave for
215  * hibernation.
216  *
217  * This function requires the e820 map to be sorted and without any
218  * overlapping entries and assumes the first e820 area to be RAM.
219  */
220 void __init e820_mark_nosave_regions(void)
221 {
222         int i;
223         unsigned long pfn;
224
225         pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size);
226         for (i = 1; i < e820.nr_map; i++) {
227                 struct e820entry *ei = &e820.map[i];
228
229                 if (pfn < PFN_UP(ei->addr))
230                         register_nosave_region(pfn, PFN_UP(ei->addr));
231
232                 pfn = PFN_DOWN(ei->addr + ei->size);
233                 if (ei->type != E820_RAM)
234                         register_nosave_region(PFN_UP(ei->addr), pfn);
235
236                 if (pfn >= max_low_pfn)
237                         break;
238         }
239 }
240 #endif
241
242 /*
243  * Find the highest page frame number we have available
244  */
245 void __init propagate_e820_map(void)
246 {
247         int i;
248
249         max_pfn = 0;
250
251         for (i = 0; i < e820.nr_map; i++) {
252                 unsigned long start, end;
253                 /* RAM? */
254                 if (e820.map[i].type != E820_RAM)
255                         continue;
256                 start = PFN_UP(e820.map[i].addr);
257                 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
258                 if (start >= end)
259                         continue;
260                 if (end > max_pfn)
261                         max_pfn = end;
262                 memory_present(0, start, end);
263         }
264 }
265
266 /*
267  * Register fully available low RAM pages with the bootmem allocator.
268  */
269 void __init register_bootmem_low_pages(unsigned long max_low_pfn)
270 {
271         int i;
272
273         for (i = 0; i < e820.nr_map; i++) {
274                 unsigned long curr_pfn, last_pfn, size;
275                 /*
276                  * Reserve usable low memory
277                  */
278                 if (e820.map[i].type != E820_RAM)
279                         continue;
280                 /*
281                  * We are rounding up the start address of usable memory:
282                  */
283                 curr_pfn = PFN_UP(e820.map[i].addr);
284                 if (curr_pfn >= max_low_pfn)
285                         continue;
286                 /*
287                  * ... and at the end of the usable range downwards:
288                  */
289                 last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
290
291                 if (last_pfn > max_low_pfn)
292                         last_pfn = max_low_pfn;
293
294                 /*
295                  * .. finally, did all the rounding and playing
296                  * around just make the area go away?
297                  */
298                 if (last_pfn <= curr_pfn)
299                         continue;
300
301                 size = last_pfn - curr_pfn;
302                 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
303         }
304 }
305
306 void __init limit_regions(unsigned long long size)
307 {
308         unsigned long long current_addr;
309         int i;
310
311         e820_print_map("limit_regions start");
312         for (i = 0; i < e820.nr_map; i++) {
313                 current_addr = e820.map[i].addr + e820.map[i].size;
314                 if (current_addr < size)
315                         continue;
316
317                 if (e820.map[i].type != E820_RAM)
318                         continue;
319
320                 if (e820.map[i].addr >= size) {
321                         /*
322                          * This region starts past the end of the
323                          * requested size, skip it completely.
324                          */
325                         e820.nr_map = i;
326                 } else {
327                         e820.nr_map = i + 1;
328                         e820.map[i].size -= current_addr - size;
329                 }
330                 e820_print_map("limit_regions endfor");
331                 return;
332         }
333         e820_print_map("limit_regions endfunc");
334 }
335
336 /* Overridden in paravirt.c if CONFIG_PARAVIRT */
337 char * __init __attribute__((weak)) memory_setup(void)
338 {
339         return machine_specific_memory_setup();
340 }
341
342 void __init setup_memory_map(void)
343 {
344         printk(KERN_INFO "BIOS-provided physical RAM map:\n");
345         e820_print_map(memory_setup());
346 }
347
348 static int __initdata user_defined_memmap;
349
350 /*
351  * "mem=nopentium" disables the 4MB page tables.
352  * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
353  * to <mem>, overriding the bios size.
354  * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
355  * <start> to <start>+<mem>, overriding the bios size.
356  *
357  * HPA tells me bootloaders need to parse mem=, so no new
358  * option should be mem=  [also see Documentation/i386/boot.txt]
359  */
360 static int __init parse_mem(char *arg)
361 {
362         if (!arg)
363                 return -EINVAL;
364
365         if (strcmp(arg, "nopentium") == 0) {
366                 setup_clear_cpu_cap(X86_FEATURE_PSE);
367         } else {
368                 /* If the user specifies memory size, we
369                  * limit the BIOS-provided memory map to
370                  * that size. exactmap can be used to specify
371                  * the exact map. mem=number can be used to
372                  * trim the existing memory map.
373                  */
374                 unsigned long long mem_size;
375
376                 mem_size = memparse(arg, &arg);
377                 limit_regions(mem_size);
378                 user_defined_memmap = 1;
379         }
380         return 0;
381 }
382 early_param("mem", parse_mem);
383
384 static int __init parse_memmap(char *arg)
385 {
386         if (!arg)
387                 return -EINVAL;
388
389         if (strcmp(arg, "exactmap") == 0) {
390 #ifdef CONFIG_CRASH_DUMP
391                 /* If we are doing a crash dump, we
392                  * still need to know the real mem
393                  * size before original memory map is
394                  * reset.
395                  */
396                 propagate_e820_map();
397                 saved_max_pfn = max_pfn;
398 #endif
399                 e820.nr_map = 0;
400                 user_defined_memmap = 1;
401         } else {
402                 /* If the user specifies memory size, we
403                  * limit the BIOS-provided memory map to
404                  * that size. exactmap can be used to specify
405                  * the exact map. mem=number can be used to
406                  * trim the existing memory map.
407                  */
408                 unsigned long long start_at, mem_size;
409
410                 mem_size = memparse(arg, &arg);
411                 if (*arg == '@') {
412                         start_at = memparse(arg+1, &arg);
413                         add_memory_region(start_at, mem_size, E820_RAM);
414                 } else if (*arg == '#') {
415                         start_at = memparse(arg+1, &arg);
416                         add_memory_region(start_at, mem_size, E820_ACPI);
417                 } else if (*arg == '$') {
418                         start_at = memparse(arg+1, &arg);
419                         add_memory_region(start_at, mem_size, E820_RESERVED);
420                 } else {
421                         limit_regions(mem_size);
422                         user_defined_memmap = 1;
423                 }
424         }
425         return 0;
426 }
427 early_param("memmap", parse_memmap);
428
429 void __init finish_e820_parsing(void)
430 {
431         if (user_defined_memmap) {
432                 printk(KERN_INFO "user-defined physical RAM map:\n");
433                 e820_print_map("user");
434         }
435 }
436