]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/i386/kernel/e820.c
[PATCH] i386: Move find_max_pfn function to e820.c
[karo-tx-linux.git] / arch / i386 / kernel / e820.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/efi.h>
11 #include <linux/pfn.h>
12
13 #include <asm/pgtable.h>
14 #include <asm/page.h>
15 #include <asm/e820.h>
16
17 #ifdef CONFIG_EFI
18 int efi_enabled = 0;
19 EXPORT_SYMBOL(efi_enabled);
20 #endif
21
22 struct e820map e820;
23 struct change_member {
24         struct e820entry *pbios; /* pointer to original bios entry */
25         unsigned long long addr; /* address for this change point */
26 };
27 static struct change_member change_point_list[2*E820MAX] __initdata;
28 static struct change_member *change_point[2*E820MAX] __initdata;
29 static struct e820entry *overlap_list[E820MAX] __initdata;
30 static struct e820entry new_bios[E820MAX] __initdata;
31 struct resource data_resource = {
32         .name   = "Kernel data",
33         .start  = 0,
34         .end    = 0,
35         .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
36 };
37
38 struct resource code_resource = {
39         .name   = "Kernel code",
40         .start  = 0,
41         .end    = 0,
42         .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
43 };
44
45 static struct resource system_rom_resource = {
46         .name   = "System ROM",
47         .start  = 0xf0000,
48         .end    = 0xfffff,
49         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
50 };
51
52 static struct resource extension_rom_resource = {
53         .name   = "Extension ROM",
54         .start  = 0xe0000,
55         .end    = 0xeffff,
56         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
57 };
58
59 static struct resource adapter_rom_resources[] = { {
60         .name   = "Adapter ROM",
61         .start  = 0xc8000,
62         .end    = 0,
63         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
64 }, {
65         .name   = "Adapter ROM",
66         .start  = 0,
67         .end    = 0,
68         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
69 }, {
70         .name   = "Adapter ROM",
71         .start  = 0,
72         .end    = 0,
73         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
74 }, {
75         .name   = "Adapter ROM",
76         .start  = 0,
77         .end    = 0,
78         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
79 }, {
80         .name   = "Adapter ROM",
81         .start  = 0,
82         .end    = 0,
83         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
84 }, {
85         .name   = "Adapter ROM",
86         .start  = 0,
87         .end    = 0,
88         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
89 } };
90
91 static struct resource video_rom_resource = {
92         .name   = "Video ROM",
93         .start  = 0xc0000,
94         .end    = 0xc7fff,
95         .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
96 };
97
98 static struct resource video_ram_resource = {
99         .name   = "Video RAM area",
100         .start  = 0xa0000,
101         .end    = 0xbffff,
102         .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
103 };
104
105 static struct resource standard_io_resources[] = { {
106         .name   = "dma1",
107         .start  = 0x0000,
108         .end    = 0x001f,
109         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
110 }, {
111         .name   = "pic1",
112         .start  = 0x0020,
113         .end    = 0x0021,
114         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
115 }, {
116         .name   = "timer0",
117         .start  = 0x0040,
118         .end    = 0x0043,
119         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
120 }, {
121         .name   = "timer1",
122         .start  = 0x0050,
123         .end    = 0x0053,
124         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
125 }, {
126         .name   = "keyboard",
127         .start  = 0x0060,
128         .end    = 0x006f,
129         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
130 }, {
131         .name   = "dma page reg",
132         .start  = 0x0080,
133         .end    = 0x008f,
134         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
135 }, {
136         .name   = "pic2",
137         .start  = 0x00a0,
138         .end    = 0x00a1,
139         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
140 }, {
141         .name   = "dma2",
142         .start  = 0x00c0,
143         .end    = 0x00df,
144         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
145 }, {
146         .name   = "fpu",
147         .start  = 0x00f0,
148         .end    = 0x00ff,
149         .flags  = IORESOURCE_BUSY | IORESOURCE_IO
150 } };
151
152 #define romsignature(x) (*(unsigned short *)(x) == 0xaa55)
153
154 static int __init romchecksum(unsigned char *rom, unsigned long length)
155 {
156         unsigned char *p, sum = 0;
157
158         for (p = rom; p < rom + length; p++)
159                 sum += *p;
160         return sum == 0;
161 }
162
163 static void __init probe_roms(void)
164 {
165         unsigned long start, length, upper;
166         unsigned char *rom;
167         int           i;
168
169         /* video rom */
170         upper = adapter_rom_resources[0].start;
171         for (start = video_rom_resource.start; start < upper; start += 2048) {
172                 rom = isa_bus_to_virt(start);
173                 if (!romsignature(rom))
174                         continue;
175
176                 video_rom_resource.start = start;
177
178                 /* 0 < length <= 0x7f * 512, historically */
179                 length = rom[2] * 512;
180
181                 /* if checksum okay, trust length byte */
182                 if (length && romchecksum(rom, length))
183                         video_rom_resource.end = start + length - 1;
184
185                 request_resource(&iomem_resource, &video_rom_resource);
186                 break;
187         }
188
189         start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
190         if (start < upper)
191                 start = upper;
192
193         /* system rom */
194         request_resource(&iomem_resource, &system_rom_resource);
195         upper = system_rom_resource.start;
196
197         /* check for extension rom (ignore length byte!) */
198         rom = isa_bus_to_virt(extension_rom_resource.start);
199         if (romsignature(rom)) {
200                 length = extension_rom_resource.end - extension_rom_resource.start + 1;
201                 if (romchecksum(rom, length)) {
202                         request_resource(&iomem_resource, &extension_rom_resource);
203                         upper = extension_rom_resource.start;
204                 }
205         }
206
207         /* check for adapter roms on 2k boundaries */
208         for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
209                 rom = isa_bus_to_virt(start);
210                 if (!romsignature(rom))
211                         continue;
212
213                 /* 0 < length <= 0x7f * 512, historically */
214                 length = rom[2] * 512;
215
216                 /* but accept any length that fits if checksum okay */
217                 if (!length || start + length > upper || !romchecksum(rom, length))
218                         continue;
219
220                 adapter_rom_resources[i].start = start;
221                 adapter_rom_resources[i].end = start + length - 1;
222                 request_resource(&iomem_resource, &adapter_rom_resources[i]);
223
224                 start = adapter_rom_resources[i++].end & ~2047UL;
225         }
226 }
227
228 /*
229  * Request address space for all standard RAM and ROM resources
230  * and also for regions reported as reserved by the e820.
231  */
232 static void __init
233 legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
234 {
235         int i;
236
237         probe_roms();
238         for (i = 0; i < e820.nr_map; i++) {
239                 struct resource *res;
240 #ifndef CONFIG_RESOURCES_64BIT
241                 if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
242                         continue;
243 #endif
244                 res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
245                 switch (e820.map[i].type) {
246                 case E820_RAM:  res->name = "System RAM"; break;
247                 case E820_ACPI: res->name = "ACPI Tables"; break;
248                 case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
249                 default:        res->name = "reserved";
250                 }
251                 res->start = e820.map[i].addr;
252                 res->end = res->start + e820.map[i].size - 1;
253                 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
254                 if (request_resource(&iomem_resource, res)) {
255                         kfree(res);
256                         continue;
257                 }
258                 if (e820.map[i].type == E820_RAM) {
259                         /*
260                          *  We don't know which RAM region contains kernel data,
261                          *  so we try it repeatedly and let the resource manager
262                          *  test it.
263                          */
264                         request_resource(res, code_resource);
265                         request_resource(res, data_resource);
266 #ifdef CONFIG_KEXEC
267                         request_resource(res, &crashk_res);
268 #endif
269                 }
270         }
271 }
272
273 /*
274  * Request address space for all standard resources
275  *
276  * This is called just before pcibios_init(), which is also a
277  * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
278  */
279 static int __init request_standard_resources(void)
280 {
281         int i;
282
283         printk("Setting up standard PCI resources\n");
284         if (efi_enabled)
285                 efi_initialize_iomem_resources(&code_resource, &data_resource);
286         else
287                 legacy_init_iomem_resources(&code_resource, &data_resource);
288
289         /* EFI systems may still have VGA */
290         request_resource(&iomem_resource, &video_ram_resource);
291
292         /* request I/O space for devices used on all i[345]86 PCs */
293         for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
294                 request_resource(&ioport_resource, &standard_io_resources[i]);
295         return 0;
296 }
297
298 subsys_initcall(request_standard_resources);
299
300 void __init add_memory_region(unsigned long long start,
301                               unsigned long long size, int type)
302 {
303         int x;
304
305         if (!efi_enabled) {
306                 x = e820.nr_map;
307
308                 if (x == E820MAX) {
309                     printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
310                     return;
311                 }
312
313                 e820.map[x].addr = start;
314                 e820.map[x].size = size;
315                 e820.map[x].type = type;
316                 e820.nr_map++;
317         }
318 } /* add_memory_region */
319
320 /*
321  * Sanitize the BIOS e820 map.
322  *
323  * Some e820 responses include overlapping entries.  The following
324  * replaces the original e820 map with a new one, removing overlaps.
325  *
326  */
327 int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
328 {
329         struct change_member *change_tmp;
330         unsigned long current_type, last_type;
331         unsigned long long last_addr;
332         int chgidx, still_changing;
333         int overlap_entries;
334         int new_bios_entry;
335         int old_nr, new_nr, chg_nr;
336         int i;
337
338         /*
339                 Visually we're performing the following (1,2,3,4 = memory types)...
340
341                 Sample memory map (w/overlaps):
342                    ____22__________________
343                    ______________________4_
344                    ____1111________________
345                    _44_____________________
346                    11111111________________
347                    ____________________33__
348                    ___________44___________
349                    __________33333_________
350                    ______________22________
351                    ___________________2222_
352                    _________111111111______
353                    _____________________11_
354                    _________________4______
355
356                 Sanitized equivalent (no overlap):
357                    1_______________________
358                    _44_____________________
359                    ___1____________________
360                    ____22__________________
361                    ______11________________
362                    _________1______________
363                    __________3_____________
364                    ___________44___________
365                    _____________33_________
366                    _______________2________
367                    ________________1_______
368                    _________________4______
369                    ___________________2____
370                    ____________________33__
371                    ______________________4_
372         */
373         printk("sanitize start\n");
374         /* if there's only one memory region, don't bother */
375         if (*pnr_map < 2) {
376                 printk("sanitize bail 0\n");
377                 return -1;
378         }
379
380         old_nr = *pnr_map;
381
382         /* bail out if we find any unreasonable addresses in bios map */
383         for (i=0; i<old_nr; i++)
384                 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) {
385                         printk("sanitize bail 1\n");
386                         return -1;
387                 }
388
389         /* create pointers for initial change-point information (for sorting) */
390         for (i=0; i < 2*old_nr; i++)
391                 change_point[i] = &change_point_list[i];
392
393         /* record all known change-points (starting and ending addresses),
394            omitting those that are for empty memory regions */
395         chgidx = 0;
396         for (i=0; i < old_nr; i++)      {
397                 if (biosmap[i].size != 0) {
398                         change_point[chgidx]->addr = biosmap[i].addr;
399                         change_point[chgidx++]->pbios = &biosmap[i];
400                         change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
401                         change_point[chgidx++]->pbios = &biosmap[i];
402                 }
403         }
404         chg_nr = chgidx;        /* true number of change-points */
405
406         /* sort change-point list by memory addresses (low -> high) */
407         still_changing = 1;
408         while (still_changing)  {
409                 still_changing = 0;
410                 for (i=1; i < chg_nr; i++)  {
411                         /* if <current_addr> > <last_addr>, swap */
412                         /* or, if current=<start_addr> & last=<end_addr>, swap */
413                         if ((change_point[i]->addr < change_point[i-1]->addr) ||
414                                 ((change_point[i]->addr == change_point[i-1]->addr) &&
415                                  (change_point[i]->addr == change_point[i]->pbios->addr) &&
416                                  (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
417                            )
418                         {
419                                 change_tmp = change_point[i];
420                                 change_point[i] = change_point[i-1];
421                                 change_point[i-1] = change_tmp;
422                                 still_changing=1;
423                         }
424                 }
425         }
426
427         /* create a new bios memory map, removing overlaps */
428         overlap_entries=0;       /* number of entries in the overlap table */
429         new_bios_entry=0;        /* index for creating new bios map entries */
430         last_type = 0;           /* start with undefined memory type */
431         last_addr = 0;           /* start with 0 as last starting address */
432         /* loop through change-points, determining affect on the new bios map */
433         for (chgidx=0; chgidx < chg_nr; chgidx++)
434         {
435                 /* keep track of all overlapping bios entries */
436                 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
437                 {
438                         /* add map entry to overlap list (> 1 entry implies an overlap) */
439                         overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
440                 }
441                 else
442                 {
443                         /* remove entry from list (order independent, so swap with last) */
444                         for (i=0; i<overlap_entries; i++)
445                         {
446                                 if (overlap_list[i] == change_point[chgidx]->pbios)
447                                         overlap_list[i] = overlap_list[overlap_entries-1];
448                         }
449                         overlap_entries--;
450                 }
451                 /* if there are overlapping entries, decide which "type" to use */
452                 /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
453                 current_type = 0;
454                 for (i=0; i<overlap_entries; i++)
455                         if (overlap_list[i]->type > current_type)
456                                 current_type = overlap_list[i]->type;
457                 /* continue building up new bios map based on this information */
458                 if (current_type != last_type)  {
459                         if (last_type != 0)      {
460                                 new_bios[new_bios_entry].size =
461                                         change_point[chgidx]->addr - last_addr;
462                                 /* move forward only if the new size was non-zero */
463                                 if (new_bios[new_bios_entry].size != 0)
464                                         if (++new_bios_entry >= E820MAX)
465                                                 break;  /* no more space left for new bios entries */
466                         }
467                         if (current_type != 0)  {
468                                 new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
469                                 new_bios[new_bios_entry].type = current_type;
470                                 last_addr=change_point[chgidx]->addr;
471                         }
472                         last_type = current_type;
473                 }
474         }
475         new_nr = new_bios_entry;   /* retain count for new bios entries */
476
477         /* copy new bios mapping into original location */
478         memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
479         *pnr_map = new_nr;
480
481         printk("sanitize end\n");
482         return 0;
483 }
484
485 /*
486  * Copy the BIOS e820 map into a safe place.
487  *
488  * Sanity-check it while we're at it..
489  *
490  * If we're lucky and live on a modern system, the setup code
491  * will have given us a memory map that we can use to properly
492  * set up memory.  If we aren't, we'll fake a memory map.
493  *
494  * We check to see that the memory map contains at least 2 elements
495  * before we'll use it, because the detection code in setup.S may
496  * not be perfect and most every PC known to man has two memory
497  * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
498  * thinkpad 560x, for example, does not cooperate with the memory
499  * detection code.)
500  */
501 int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
502 {
503         /* Only one memory region (or negative)? Ignore it */
504         if (nr_map < 2)
505                 return -1;
506
507         do {
508                 unsigned long long start = biosmap->addr;
509                 unsigned long long size = biosmap->size;
510                 unsigned long long end = start + size;
511                 unsigned long type = biosmap->type;
512                 printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type);
513
514                 /* Overflow in 64 bits? Ignore the memory map. */
515                 if (start > end)
516                         return -1;
517
518                 /*
519                  * Some BIOSes claim RAM in the 640k - 1M region.
520                  * Not right. Fix it up.
521                  */
522                 if (type == E820_RAM) {
523                         printk("copy_e820_map() type is E820_RAM\n");
524                         if (start < 0x100000ULL && end > 0xA0000ULL) {
525                                 printk("copy_e820_map() lies in range...\n");
526                                 if (start < 0xA0000ULL) {
527                                         printk("copy_e820_map() start < 0xA0000ULL\n");
528                                         add_memory_region(start, 0xA0000ULL-start, type);
529                                 }
530                                 if (end <= 0x100000ULL) {
531                                         printk("copy_e820_map() end <= 0x100000ULL\n");
532                                         continue;
533                                 }
534                                 start = 0x100000ULL;
535                                 size = end - start;
536                         }
537                 }
538                 add_memory_region(start, size, type);
539         } while (biosmap++,--nr_map);
540         return 0;
541 }
542
543 /*
544  * Callback for efi_memory_walk.
545  */
546 static int __init
547 efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
548 {
549         unsigned long *max_pfn = arg, pfn;
550
551         if (start < end) {
552                 pfn = PFN_UP(end -1);
553                 if (pfn > *max_pfn)
554                         *max_pfn = pfn;
555         }
556         return 0;
557 }
558
559 static int __init
560 efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
561 {
562         memory_present(0, PFN_UP(start), PFN_DOWN(end));
563         return 0;
564 }
565
566 /*
567  * Find the highest page frame number we have available
568  */
569 void __init find_max_pfn(void)
570 {
571         int i;
572
573         max_pfn = 0;
574         if (efi_enabled) {
575                 efi_memmap_walk(efi_find_max_pfn, &max_pfn);
576                 efi_memmap_walk(efi_memory_present_wrapper, NULL);
577                 return;
578         }
579
580         for (i = 0; i < e820.nr_map; i++) {
581                 unsigned long start, end;
582                 /* RAM? */
583                 if (e820.map[i].type != E820_RAM)
584                         continue;
585                 start = PFN_UP(e820.map[i].addr);
586                 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
587                 if (start >= end)
588                         continue;
589                 if (end > max_pfn)
590                         max_pfn = end;
591                 memory_present(0, start, end);
592         }
593 }