Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


b0073563d3abe9e4d1a99268a15d1f0f28fb18d1
[palacios-OLD.git] / kitten / arch / x86_64 / kernel / e820.c
1 /* 
2  * Handle the memory map.
3  * The functions here do the job until bootmem takes over.
4  * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
5  *
6  *  Getting sanitize_e820_map() in sync with i386 version by applying change:
7  *  -  Provisions for empty E820 memory regions (reported by certain BIOSes).
8  *     Alex Achenbach <xela@slit.de>, December 2002.
9  *  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
10  *
11  */
12 #include <lwk/kernel.h>
13 #include <lwk/types.h>
14 #include <lwk/init.h>
15 #include <lwk/bootmem.h>
16 #include <lwk/resource.h>
17 #include <lwk/string.h>
18 #include <lwk/linux_compat.h>
19
20 #include <arch/page.h>
21 #include <arch/pgtable.h>
22 #include <arch/e820.h>
23 #include <arch/proto.h>
24 #include <arch/bootsetup.h>
25 #include <arch/sections.h>
26
27 /**
28  * The BIOS "e820" map of memory.
29  */
30 struct e820map e820;
31
32 /* 
33  * PFN of last memory page.
34  */
35 unsigned long end_pfn; 
36 EXPORT_SYMBOL(end_pfn);
37
38 /* 
39  * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
40  * The direct mapping extends to end_pfn_map, so that we can directly access
41  * apertures, ACPI and other tables without having to play with fixmaps.
42  */ 
43 unsigned long end_pfn_map; 
44
45 /* 
46  * Last pfn which the user wants to use.
47  */
48 unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT;  
49
50 extern struct resource code_resource, data_resource;
51
52 /* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
53 static inline int bad_addr(unsigned long *addrp, unsigned long size)
54
55         unsigned long addr = *addrp, last = addr + size; 
56
57         /* various gunk below that needed for SMP startup */
58         if (addr < 0x8000) { 
59                 *addrp = 0x8000;
60                 return 1; 
61         }
62
63         /* direct mapping tables of the kernel */
64         if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
65                 *addrp = table_end << PAGE_SHIFT; 
66                 return 1;
67         } 
68
69         /* initrd image */ 
70         if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
71             addr < INITRD_START+INITRD_SIZE) { 
72                 *addrp = INITRD_START + INITRD_SIZE; 
73                 return 1;
74         } 
75
76         /* kernel code + 640k memory hole (later should not be needed, but 
77            be paranoid for now) */
78         if (last >= 640*1024 && addr < __pa_symbol(&_end)) { 
79                 *addrp = __pa_symbol(&_end);
80                 return 1;
81         }
82
83         if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
84                 *addrp = ebda_addr + ebda_size;
85                 return 1;
86         }
87
88         /* XXX ramdisk image here? */ 
89         return 0;
90
91
92 /*
93  * This function checks if any part of the range <start,end> is mapped
94  * with type.
95  */
96 int __init
97 e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
98
99         int i;
100         for (i = 0; i < e820.nr_map; i++) { 
101                 struct e820entry *ei = &e820.map[i]; 
102                 if (type && ei->type != type) 
103                         continue;
104                 if (ei->addr >= end || ei->addr + ei->size <= start)
105                         continue; 
106                 return 1; 
107         } 
108         return 0;
109 }
110
111 /*
112  * This function checks if the entire range <start,end> is mapped with type.
113  *
114  * Note: this function only works correct if the e820 table is sorted and
115  * not-overlapping, which is the case
116  */
117 int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
118 {
119         int i;
120         for (i = 0; i < e820.nr_map; i++) {
121                 struct e820entry *ei = &e820.map[i];
122                 if (type && ei->type != type)
123                         continue;
124                 /* is the region (part) in overlap with the current region ?*/
125                 if (ei->addr >= end || ei->addr + ei->size <= start)
126                         continue;
127
128                 /* if the region is at the beginning of <start,end> we move
129                  * start to the end of the region since it's ok until there
130                  */
131                 if (ei->addr <= start)
132                         start = ei->addr + ei->size;
133                 /* if start is now at or beyond end, we're done, full coverage */
134                 if (start >= end)
135                         return 1; /* we're done */
136         }
137         return 0;
138 }
139
140 /* 
141  * Find a free area in a specific range. 
142  */ 
143 unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsigned size) 
144
145         int i; 
146         for (i = 0; i < e820.nr_map; i++) { 
147                 struct e820entry *ei = &e820.map[i]; 
148                 unsigned long addr = ei->addr, last; 
149                 if (ei->type != E820_RAM) 
150                         continue; 
151                 if (addr < start) 
152                         addr = start;
153                 if (addr > ei->addr + ei->size) 
154                         continue; 
155                 while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
156                         ;
157                 last = addr + size;
158                 if (last > ei->addr + ei->size)
159                         continue;
160                 if (last > end) 
161                         continue;
162                 return addr; 
163         } 
164         return -1UL;            
165
166
167 /* 
168  * Free bootmem based on the e820 table for a node.
169  */
170 void __init e820_bootmem_free(unsigned long start, unsigned long end)
171 {
172         int i;
173         for (i = 0; i < e820.nr_map; i++) {
174                 struct e820entry *ei = &e820.map[i]; 
175                 unsigned long last, addr;
176
177                 if (ei->type != E820_RAM || 
178                     ei->addr+ei->size <= start || 
179                     ei->addr >= end)
180                         continue;
181
182                 addr = round_up(ei->addr, PAGE_SIZE);
183                 if (addr < start) 
184                         addr = start;
185
186                 last = round_down(ei->addr + ei->size, PAGE_SIZE); 
187                 if (last >= end)
188                         last = end; 
189
190                 if (last > addr && last-addr >= PAGE_SIZE)
191                         free_bootmem(addr, last-addr);
192         }
193 }
194
195 /*
196  * Find the highest page frame number we have available
197  */
198 unsigned long __init e820_end_of_ram(void)
199 {
200         int i;
201         unsigned long end_pfn = 0;
202         
203         for (i = 0; i < e820.nr_map; i++) {
204                 struct e820entry *ei = &e820.map[i]; 
205                 unsigned long start, end;
206
207                 start = round_up(ei->addr, PAGE_SIZE); 
208                 end = round_down(ei->addr + ei->size, PAGE_SIZE); 
209                 if (start >= end)
210                         continue;
211                 if (ei->type == E820_RAM) { 
212                 if (end > end_pfn<<PAGE_SHIFT)
213                         end_pfn = end>>PAGE_SHIFT;
214                 } else { 
215                         if (end > end_pfn_map<<PAGE_SHIFT) 
216                                 end_pfn_map = end>>PAGE_SHIFT;
217                 } 
218         }
219
220         if (end_pfn > end_pfn_map) 
221                 end_pfn_map = end_pfn;
222         if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
223                 end_pfn_map = MAXMEM>>PAGE_SHIFT;
224         if (end_pfn > end_user_pfn)
225                 end_pfn = end_user_pfn;
226         if (end_pfn > end_pfn_map) 
227                 end_pfn = end_pfn_map; 
228
229         return end_pfn; 
230 }
231
232 /* 
233  * Compute how much memory is missing in a range.
234  * Unlike the other functions in this file the arguments are in page numbers.
235  */
236 unsigned long __init
237 e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
238 {
239         unsigned long ram = 0;
240         unsigned long start = start_pfn << PAGE_SHIFT;
241         unsigned long end = end_pfn << PAGE_SHIFT;
242         int i;
243         for (i = 0; i < e820.nr_map; i++) {
244                 struct e820entry *ei = &e820.map[i];
245                 unsigned long last, addr;
246
247                 if (ei->type != E820_RAM ||
248                     ei->addr+ei->size <= start ||
249                     ei->addr >= end)
250                         continue;
251
252                 addr = round_up(ei->addr, PAGE_SIZE);
253                 if (addr < start)
254                         addr = start;
255
256                 last = round_down(ei->addr + ei->size, PAGE_SIZE);
257                 if (last >= end)
258                         last = end;
259
260                 if (last > addr)
261                         ram += last - addr;
262         }
263         return ((end - start) - ram) >> PAGE_SHIFT;
264 }
265
266 /*
267  * Mark e820 reserved areas as busy for the resource manager.
268  */
269 void __init e820_reserve_resources(void)
270 {
271         int i;
272         for (i = 0; i < e820.nr_map; i++) {
273                 struct resource *res;
274                 res = alloc_bootmem(sizeof(struct resource));
275                 switch (e820.map[i].type) {
276                 case E820_RAM:  res->name = "System RAM"; break;
277                 case E820_ACPI: res->name = "ACPI Tables"; break;
278                 case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
279                 default:        res->name = "reserved";
280                 }
281                 res->start = e820.map[i].addr;
282                 res->end = res->start + e820.map[i].size - 1;
283                 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
284                 request_resource(&iomem_resource, res);
285                 if (e820.map[i].type == E820_RAM) {
286                         /*
287                          *  We don't know which RAM region contains kernel data,
288                          *  so we try it repeatedly and let the resource manager
289                          *  test it.
290                          */
291                         request_resource(res, &code_resource);
292                         request_resource(res, &data_resource);
293 #ifdef CONFIG_KEXEC
294                         request_resource(res, &crashk_res);
295 #endif
296                 }
297         }
298 }
299
300 /* 
301  * Add a memory region to the kernel e820 map.
302  */ 
303 void __init add_memory_region(unsigned long start, unsigned long size, int type)
304 {
305         int x = e820.nr_map;
306
307         if (x == E820MAX) {
308                 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
309                 return;
310         }
311
312         e820.map[x].addr = start;
313         e820.map[x].size = size;
314         e820.map[x].type = type;
315         e820.nr_map++;
316 }
317
318 void __init e820_print_map(char *who)
319 {
320         int i;
321         char type[16];
322
323         for (i = 0; i < e820.nr_map; i++) {
324                 switch (e820.map[i].type) {
325                 case E820_RAM:  sprintf(type, "(usable)\n");
326                                 break;
327                 case E820_RESERVED:
328                                 sprintf(type, "(reserved)\n");
329                                 break;
330                 case E820_ACPI:
331                                 sprintf(type, "(ACPI data)\n");
332                                 break;
333                 case E820_NVS:
334                                 sprintf(type, "(ACPI NVS)\n");
335                                 break;
336                 default:        sprintf(type, "type %u\n", e820.map[i].type);
337                                 break;
338                 }
339
340                 printk(KERN_DEBUG
341                         " %s: %016Lx - %016Lx %s", who,
342                         (unsigned long long) e820.map[i].addr,
343                         (unsigned long long) (e820.map[i].addr + e820.map[i].size),
344                         type);
345         }
346 }
347
348 /*
349  * Sanitize the BIOS e820 map.
350  *
351  * Some e820 responses include overlapping entries.  The following 
352  * replaces the original e820 map with a new one, removing overlaps.
353  *
354  */
355 static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
356 {
357         struct change_member {
358                 struct e820entry *pbios; /* pointer to original bios entry */
359                 unsigned long long addr; /* address for this change point */
360         };
361         static struct change_member change_point_list[2*E820MAX] __initdata;
362         static struct change_member *change_point[2*E820MAX] __initdata;
363         static struct e820entry *overlap_list[E820MAX] __initdata;
364         static struct e820entry new_bios[E820MAX] __initdata;
365         struct change_member *change_tmp;
366         unsigned long current_type, last_type;
367         unsigned long long last_addr;
368         int chgidx, still_changing;
369         int overlap_entries;
370         int new_bios_entry;
371         int old_nr, new_nr, chg_nr;
372         int i;
373
374         /*
375                 Visually we're performing the following (1,2,3,4 = memory types)...
376
377                 Sample memory map (w/overlaps):
378                    ____22__________________
379                    ______________________4_
380                    ____1111________________
381                    _44_____________________
382                    11111111________________
383                    ____________________33__
384                    ___________44___________
385                    __________33333_________
386                    ______________22________
387                    ___________________2222_
388                    _________111111111______
389                    _____________________11_
390                    _________________4______
391
392                 Sanitized equivalent (no overlap):
393                    1_______________________
394                    _44_____________________
395                    ___1____________________
396                    ____22__________________
397                    ______11________________
398                    _________1______________
399                    __________3_____________
400                    ___________44___________
401                    _____________33_________
402                    _______________2________
403                    ________________1_______
404                    _________________4______
405                    ___________________2____
406                    ____________________33__
407                    ______________________4_
408         */
409
410         /* if there's only one memory region, don't bother */
411         if (*pnr_map < 2)
412                 return -1;
413
414         old_nr = *pnr_map;
415
416         /* bail out if we find any unreasonable addresses in bios map */
417         for (i=0; i<old_nr; i++)
418                 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
419                         return -1;
420
421         /* create pointers for initial change-point information (for sorting) */
422         for (i=0; i < 2*old_nr; i++)
423                 change_point[i] = &change_point_list[i];
424
425         /* record all known change-points (starting and ending addresses),
426            omitting those that are for empty memory regions */
427         chgidx = 0;
428         for (i=0; i < old_nr; i++)      {
429                 if (biosmap[i].size != 0) {
430                         change_point[chgidx]->addr = biosmap[i].addr;
431                         change_point[chgidx++]->pbios = &biosmap[i];
432                         change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
433                         change_point[chgidx++]->pbios = &biosmap[i];
434                 }
435         }
436         chg_nr = chgidx;
437
438         /* sort change-point list by memory addresses (low -> high) */
439         still_changing = 1;
440         while (still_changing)  {
441                 still_changing = 0;
442                 for (i=1; i < chg_nr; i++)  {
443                         /* if <current_addr> > <last_addr>, swap */
444                         /* or, if current=<start_addr> & last=<end_addr>, swap */
445                         if ((change_point[i]->addr < change_point[i-1]->addr) ||
446                                 ((change_point[i]->addr == change_point[i-1]->addr) &&
447                                  (change_point[i]->addr == change_point[i]->pbios->addr) &&
448                                  (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
449                            )
450                         {
451                                 change_tmp = change_point[i];
452                                 change_point[i] = change_point[i-1];
453                                 change_point[i-1] = change_tmp;
454                                 still_changing=1;
455                         }
456                 }
457         }
458
459         /* create a new bios memory map, removing overlaps */
460         overlap_entries=0;       /* number of entries in the overlap table */
461         new_bios_entry=0;        /* index for creating new bios map entries */
462         last_type = 0;           /* start with undefined memory type */
463         last_addr = 0;           /* start with 0 as last starting address */
464         /* loop through change-points, determining affect on the new bios map */
465         for (chgidx=0; chgidx < chg_nr; chgidx++)
466         {
467                 /* keep track of all overlapping bios entries */
468                 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
469                 {
470                         /* add map entry to overlap list (> 1 entry implies an overlap) */
471                         overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
472                 }
473                 else
474                 {
475                         /* remove entry from list (order independent, so swap with last) */
476                         for (i=0; i<overlap_entries; i++)
477                         {
478                                 if (overlap_list[i] == change_point[chgidx]->pbios)
479                                         overlap_list[i] = overlap_list[overlap_entries-1];
480                         }
481                         overlap_entries--;
482                 }
483                 /* if there are overlapping entries, decide which "type" to use */
484                 /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
485                 current_type = 0;
486                 for (i=0; i<overlap_entries; i++)
487                         if (overlap_list[i]->type > current_type)
488                                 current_type = overlap_list[i]->type;
489                 /* continue building up new bios map based on this information */
490                 if (current_type != last_type)  {
491                         if (last_type != 0)      {
492                                 new_bios[new_bios_entry].size =
493                                         change_point[chgidx]->addr - last_addr;
494                                 /* move forward only if the new size was non-zero */
495                                 if (new_bios[new_bios_entry].size != 0)
496                                         if (++new_bios_entry >= E820MAX)
497                                                 break;  /* no more space left for new bios entries */
498                         }
499                         if (current_type != 0)  {
500                                 new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
501                                 new_bios[new_bios_entry].type = current_type;
502                                 last_addr=change_point[chgidx]->addr;
503                         }
504                         last_type = current_type;
505                 }
506         }
507         new_nr = new_bios_entry;   /* retain count for new bios entries */
508
509         /* copy new bios mapping into original location */
510         memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
511         *pnr_map = new_nr;
512
513         return 0;
514 }
515
516 /*
517  * Copy the BIOS e820 map into a safe place.
518  *
519  * Sanity-check it while we're at it..
520  *
521  * If we're lucky and live on a modern system, the setup code
522  * will have given us a memory map that we can use to properly
523  * set up memory.  If we aren't, we'll fake a memory map.
524  *
525  * We check to see that the memory map contains at least 2 elements
526  * before we'll use it, because the detection code in setup.S may
527  * not be perfect and most every PC known to man has two memory
528  * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
529  * thinkpad 560x, for example, does not cooperate with the memory
530  * detection code.)
531  */
532 static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
533 {
534         /* Only one memory region (or negative)? Ignore it */
535         if (nr_map < 2)
536                 return -1;
537
538         do {
539                 unsigned long start = biosmap->addr;
540                 unsigned long size = biosmap->size;
541                 unsigned long end = start + size;
542                 unsigned long type = biosmap->type;
543
544                 /* Overflow in 64 bits? Ignore the memory map. */
545                 if (start > end)
546                         return -1;
547
548                 /*
549                  * Some BIOSes claim RAM in the 640k - 1M region.
550                  * Not right. Fix it up.
551                  * 
552                  * This should be removed on Hammer which is supposed to not
553                  * have non e820 covered ISA mappings there, but I had some strange
554                  * problems so it stays for now.  -AK
555                  */
556                 if (type == E820_RAM) {
557                         if (start < 0x100000ULL && end > 0xA0000ULL) {
558                                 if (start < 0xA0000ULL)
559                                         add_memory_region(start, 0xA0000ULL-start, type);
560                                 if (end <= 0x100000ULL)
561                                         continue;
562                                 start = 0x100000ULL;
563                                 size = end - start;
564                         }
565                 }
566
567                 add_memory_region(start, size, type);
568         } while (biosmap++,--nr_map);
569         return 0;
570 }
571
572 void __init setup_memory_region(void)
573 {
574         char *who = "BIOS-e820";
575
576         /*
577          * Try to copy the BIOS-supplied E820-map.
578          *
579          * Otherwise fake a memory map; one section from 0k->640k,
580          * the next section from 1mb->appropriate_mem_k
581          */
582         sanitize_e820_map(E820_MAP, &E820_MAP_NR);
583         if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
584                 unsigned long mem_size;
585
586                 /* compare results from other methods and take the greater */
587                 if (ALT_MEM_K < EXT_MEM_K) {
588                         mem_size = EXT_MEM_K;
589                         who = "BIOS-88";
590                 } else {
591                         mem_size = ALT_MEM_K;
592                         who = "BIOS-e801";
593                 }
594
595                 e820.nr_map = 0;
596                 add_memory_region(0, LOWMEMSIZE(), E820_RAM);
597                 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
598         }
599
600         printk(KERN_DEBUG "BIOS-provided physical RAM map:\n");
601         e820_print_map(who);
602
603         /* This also sets end_pfn_map */
604         end_pfn = e820_end_of_ram();
605 }
606
607 void __init parse_memopt(char *p, char **from) 
608
609         end_user_pfn = memparse(p, from);
610         end_user_pfn >>= PAGE_SHIFT;    
611
612
613 void __init parse_memmapopt(char *p, char **from)
614 {
615         unsigned long long start_at, mem_size;
616
617         mem_size = memparse(p, from);
618         p = *from;
619         if (*p == '@') {
620                 start_at = memparse(p+1, from);
621                 add_memory_region(start_at, mem_size, E820_RAM);
622         } else if (*p == '#') {
623                 start_at = memparse(p+1, from);
624                 add_memory_region(start_at, mem_size, E820_ACPI);
625         } else if (*p == '$') {
626                 start_at = memparse(p+1, from);
627                 add_memory_region(start_at, mem_size, E820_RESERVED);
628         } else {
629                 end_user_pfn = (mem_size >> PAGE_SHIFT);
630         }
631         p = *from;
632 }
633
634 unsigned long pci_mem_start = 0xaeedbabe;
635
636 /*
637  * Search for the biggest gap in the low 32 bits of the e820
638  * memory space.  We pass this space to PCI to assign MMIO resources
639  * for hotplug or unconfigured devices in.
640  * Hopefully the BIOS let enough space left.
641  */
642 __init void e820_setup_gap(void)
643 {
644         unsigned long gapstart, gapsize, round;
645         unsigned long last;
646         int i;
647         int found = 0;
648
649         last = 0x100000000ull;
650         gapstart = 0x10000000;
651         gapsize = 0x400000;
652         i = e820.nr_map;
653         while (--i >= 0) {
654                 unsigned long long start = e820.map[i].addr;
655                 unsigned long long end = start + e820.map[i].size;
656
657                 /*
658                  * Since "last" is at most 4GB, we know we'll
659                  * fit in 32 bits if this condition is true
660                  */
661                 if (last > end) {
662                         unsigned long gap = last - end;
663
664                         if (gap > gapsize) {
665                                 gapsize = gap;
666                                 gapstart = end;
667                                 found = 1;
668                         }
669                 }
670                 if (start < last)
671                         last = start;
672         }
673
674         if (!found) {
675                 gapstart = (end_pfn << PAGE_SHIFT) + 1024*1024;
676                 printk(KERN_ERR "PCI: Warning: Cannot find a gap in the 32bit address range\n"
677                        KERN_ERR "PCI: Unassigned devices with 32bit resource registers may break!\n");
678         }
679
680         /*
681          * See how much we want to round up: start off with
682          * rounding to the next 1MB area.
683          */
684         round = 0x100000;
685         while ((gapsize >> 4) > round)
686                 round += round;
687         /* Fun with two's complement */
688         pci_mem_start = (gapstart + round) & -round;
689
690         printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
691                 pci_mem_start, gapstart, gapsize);
692 }