linux/arch/i386/kernel/e820.c
<<
>>
Prefs
   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#include <linux/uaccess.h>
  13
  14#include <asm/pgtable.h>
  15#include <asm/page.h>
  16#include <asm/e820.h>
  17#include <asm/setup.h>
  18
  19#ifdef CONFIG_EFI
  20int efi_enabled = 0;
  21EXPORT_SYMBOL(efi_enabled);
  22#endif
  23
  24struct e820map e820;
  25struct change_member {
  26        struct e820entry *pbios; /* pointer to original bios entry */
  27        unsigned long long addr; /* address for this change point */
  28};
  29static struct change_member change_point_list[2*E820MAX] __initdata;
  30static struct change_member *change_point[2*E820MAX] __initdata;
  31static struct e820entry *overlap_list[E820MAX] __initdata;
  32static struct e820entry new_bios[E820MAX] __initdata;
  33/* For PCI or other memory-mapped resources */
  34unsigned long pci_mem_start = 0x10000000;
  35#ifdef CONFIG_PCI
  36EXPORT_SYMBOL(pci_mem_start);
  37#endif
  38extern int user_defined_memmap;
  39struct resource data_resource = {
  40        .name   = "Kernel data",
  41        .start  = 0,
  42        .end    = 0,
  43        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
  44};
  45
  46struct resource code_resource = {
  47        .name   = "Kernel code",
  48        .start  = 0,
  49        .end    = 0,
  50        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
  51};
  52
  53static struct resource system_rom_resource = {
  54        .name   = "System ROM",
  55        .start  = 0xf0000,
  56        .end    = 0xfffff,
  57        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  58};
  59
  60static struct resource extension_rom_resource = {
  61        .name   = "Extension ROM",
  62        .start  = 0xe0000,
  63        .end    = 0xeffff,
  64        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  65};
  66
  67static struct resource adapter_rom_resources[] = { {
  68        .name   = "Adapter ROM",
  69        .start  = 0xc8000,
  70        .end    = 0,
  71        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  72}, {
  73        .name   = "Adapter ROM",
  74        .start  = 0,
  75        .end    = 0,
  76        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  77}, {
  78        .name   = "Adapter ROM",
  79        .start  = 0,
  80        .end    = 0,
  81        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  82}, {
  83        .name   = "Adapter ROM",
  84        .start  = 0,
  85        .end    = 0,
  86        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  87}, {
  88        .name   = "Adapter ROM",
  89        .start  = 0,
  90        .end    = 0,
  91        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  92}, {
  93        .name   = "Adapter ROM",
  94        .start  = 0,
  95        .end    = 0,
  96        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
  97} };
  98
  99static struct resource video_rom_resource = {
 100        .name   = "Video ROM",
 101        .start  = 0xc0000,
 102        .end    = 0xc7fff,
 103        .flags  = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
 104};
 105
 106static struct resource video_ram_resource = {
 107        .name   = "Video RAM area",
 108        .start  = 0xa0000,
 109        .end    = 0xbffff,
 110        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
 111};
 112
 113static struct resource standard_io_resources[] = { {
 114        .name   = "dma1",
 115        .start  = 0x0000,
 116        .end    = 0x001f,
 117        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 118}, {
 119        .name   = "pic1",
 120        .start  = 0x0020,
 121        .end    = 0x0021,
 122        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 123}, {
 124        .name   = "timer0",
 125        .start  = 0x0040,
 126        .end    = 0x0043,
 127        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 128}, {
 129        .name   = "timer1",
 130        .start  = 0x0050,
 131        .end    = 0x0053,
 132        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 133}, {
 134        .name   = "keyboard",
 135        .start  = 0x0060,
 136        .end    = 0x006f,
 137        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 138}, {
 139        .name   = "dma page reg",
 140        .start  = 0x0080,
 141        .end    = 0x008f,
 142        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 143}, {
 144        .name   = "pic2",
 145        .start  = 0x00a0,
 146        .end    = 0x00a1,
 147        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 148}, {
 149        .name   = "dma2",
 150        .start  = 0x00c0,
 151        .end    = 0x00df,
 152        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 153}, {
 154        .name   = "fpu",
 155        .start  = 0x00f0,
 156        .end    = 0x00ff,
 157        .flags  = IORESOURCE_BUSY | IORESOURCE_IO
 158} };
 159
 160#define ROMSIGNATURE 0xaa55
 161
 162static int __init romsignature(const unsigned char *rom)
 163{
 164        const unsigned short * const ptr = (const unsigned short *)rom;
 165        unsigned short sig;
 166
 167        return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
 168}
 169
 170static int __init romchecksum(const unsigned char *rom, unsigned long length)
 171{
 172        unsigned char sum, c;
 173
 174        for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
 175                sum += c;
 176        return !length && !sum;
 177}
 178
 179static void __init probe_roms(void)
 180{
 181        const unsigned char *rom;
 182        unsigned long start, length, upper;
 183        unsigned char c;
 184        int i;
 185
 186        /* video rom */
 187        upper = adapter_rom_resources[0].start;
 188        for (start = video_rom_resource.start; start < upper; start += 2048) {
 189                rom = isa_bus_to_virt(start);
 190                if (!romsignature(rom))
 191                        continue;
 192
 193                video_rom_resource.start = start;
 194
 195                if (probe_kernel_address(rom + 2, c) != 0)
 196                        continue;
 197
 198                /* 0 < length <= 0x7f * 512, historically */
 199                length = c * 512;
 200
 201                /* if checksum okay, trust length byte */
 202                if (length && romchecksum(rom, length))
 203                        video_rom_resource.end = start + length - 1;
 204
 205                request_resource(&iomem_resource, &video_rom_resource);
 206                break;
 207        }
 208
 209        start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
 210        if (start < upper)
 211                start = upper;
 212
 213        /* system rom */
 214        request_resource(&iomem_resource, &system_rom_resource);
 215        upper = system_rom_resource.start;
 216
 217        /* check for extension rom (ignore length byte!) */
 218        rom = isa_bus_to_virt(extension_rom_resource.start);
 219        if (romsignature(rom)) {
 220                length = extension_rom_resource.end - extension_rom_resource.start + 1;
 221                if (romchecksum(rom, length)) {
 222                        request_resource(&iomem_resource, &extension_rom_resource);
 223                        upper = extension_rom_resource.start;
 224                }
 225        }
 226
 227        /* check for adapter roms on 2k boundaries */
 228        for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
 229                rom = isa_bus_to_virt(start);
 230                if (!romsignature(rom))
 231                        continue;
 232
 233                if (probe_kernel_address(rom + 2, c) != 0)
 234                        continue;
 235
 236                /* 0 < length <= 0x7f * 512, historically */
 237                length = c * 512;
 238
 239                /* but accept any length that fits if checksum okay */
 240                if (!length || start + length > upper || !romchecksum(rom, length))
 241                        continue;
 242
 243                adapter_rom_resources[i].start = start;
 244                adapter_rom_resources[i].end = start + length - 1;
 245                request_resource(&iomem_resource, &adapter_rom_resources[i]);
 246
 247                start = adapter_rom_resources[i++].end & ~2047UL;
 248        }
 249}
 250
 251/*
 252 * Request address space for all standard RAM and ROM resources
 253 * and also for regions reported as reserved by the e820.
 254 */
 255static void __init
 256legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
 257{
 258        int i;
 259
 260        probe_roms();
 261        for (i = 0; i < e820.nr_map; i++) {
 262                struct resource *res;
 263#ifndef CONFIG_RESOURCES_64BIT
 264                if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
 265                        continue;
 266#endif
 267                res = kzalloc(sizeof(struct resource), GFP_ATOMIC);
 268                switch (e820.map[i].type) {
 269                case E820_RAM:  res->name = "System RAM"; break;
 270                case E820_ACPI: res->name = "ACPI Tables"; break;
 271                case E820_NVS:  res->name = "ACPI Non-volatile Storage"; break;
 272                default:        res->name = "reserved";
 273                }
 274                res->start = e820.map[i].addr;
 275                res->end = res->start + e820.map[i].size - 1;
 276                res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 277                if (request_resource(&iomem_resource, res)) {
 278                        kfree(res);
 279                        continue;
 280                }
 281                if (e820.map[i].type == E820_RAM) {
 282                        /*
 283                         *  We don't know which RAM region contains kernel data,
 284                         *  so we try it repeatedly and let the resource manager
 285                         *  test it.
 286                         */
 287                        request_resource(res, code_resource);
 288                        request_resource(res, data_resource);
 289#ifdef CONFIG_KEXEC
 290                        request_resource(res, &crashk_res);
 291#endif
 292                }
 293        }
 294}
 295
 296/*
 297 * Request address space for all standard resources
 298 *
 299 * This is called just before pcibios_init(), which is also a
 300 * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
 301 */
 302static int __init request_standard_resources(void)
 303{
 304        int i;
 305
 306        printk("Setting up standard PCI resources\n");
 307        if (efi_enabled)
 308                efi_initialize_iomem_resources(&code_resource, &data_resource);
 309        else
 310                legacy_init_iomem_resources(&code_resource, &data_resource);
 311
 312        /* EFI systems may still have VGA */
 313        request_resource(&iomem_resource, &video_ram_resource);
 314
 315        /* request I/O space for devices used on all i[345]86 PCs */
 316        for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++)
 317                request_resource(&ioport_resource, &standard_io_resources[i]);
 318        return 0;
 319}
 320
 321subsys_initcall(request_standard_resources);
 322
 323void __init add_memory_region(unsigned long long start,
 324                              unsigned long long size, int type)
 325{
 326        int x;
 327
 328        if (!efi_enabled) {
 329                x = e820.nr_map;
 330
 331                if (x == E820MAX) {
 332                    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
 333                    return;
 334                }
 335
 336                e820.map[x].addr = start;
 337                e820.map[x].size = size;
 338                e820.map[x].type = type;
 339                e820.nr_map++;
 340        }
 341} /* add_memory_region */
 342
 343/*
 344 * Sanitize the BIOS e820 map.
 345 *
 346 * Some e820 responses include overlapping entries.  The following
 347 * replaces the original e820 map with a new one, removing overlaps.
 348 *
 349 */
 350int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
 351{
 352        struct change_member *change_tmp;
 353        unsigned long current_type, last_type;
 354        unsigned long long last_addr;
 355        int chgidx, still_changing;
 356        int overlap_entries;
 357        int new_bios_entry;
 358        int old_nr, new_nr, chg_nr;
 359        int i;
 360
 361        /*
 362                Visually we're performing the following (1,2,3,4 = memory types)...
 363
 364                Sample memory map (w/overlaps):
 365                   ____22__________________
 366                   ______________________4_
 367                   ____1111________________
 368                   _44_____________________
 369                   11111111________________
 370                   ____________________33__
 371                   ___________44___________
 372                   __________33333_________
 373                   ______________22________
 374                   ___________________2222_
 375                   _________111111111______
 376                   _____________________11_
 377                   _________________4______
 378
 379                Sanitized equivalent (no overlap):
 380                   1_______________________
 381                   _44_____________________
 382                   ___1____________________
 383                   ____22__________________
 384                   ______11________________
 385                   _________1______________
 386                   __________3_____________
 387                   ___________44___________
 388                   _____________33_________
 389                   _______________2________
 390                   ________________1_______
 391                   _________________4______
 392                   ___________________2____
 393                   ____________________33__
 394                   ______________________4_
 395        */
 396        /* if there's only one memory region, don't bother */
 397        if (*pnr_map < 2) {
 398                return -1;
 399        }
 400
 401        old_nr = *pnr_map;
 402
 403        /* bail out if we find any unreasonable addresses in bios map */
 404        for (i=0; i<old_nr; i++)
 405                if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) {
 406                        return -1;
 407                }
 408
 409        /* create pointers for initial change-point information (for sorting) */
 410        for (i=0; i < 2*old_nr; i++)
 411                change_point[i] = &change_point_list[i];
 412
 413        /* record all known change-points (starting and ending addresses),
 414           omitting those that are for empty memory regions */
 415        chgidx = 0;
 416        for (i=0; i < old_nr; i++)      {
 417                if (biosmap[i].size != 0) {
 418                        change_point[chgidx]->addr = biosmap[i].addr;
 419                        change_point[chgidx++]->pbios = &biosmap[i];
 420                        change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
 421                        change_point[chgidx++]->pbios = &biosmap[i];
 422                }
 423        }
 424        chg_nr = chgidx;        /* true number of change-points */
 425
 426        /* sort change-point list by memory addresses (low -> high) */
 427        still_changing = 1;
 428        while (still_changing)  {
 429                still_changing = 0;
 430                for (i=1; i < chg_nr; i++)  {
 431                        /* if <current_addr> > <last_addr>, swap */
 432                        /* or, if current=<start_addr> & last=<end_addr>, swap */
 433                        if ((change_point[i]->addr < change_point[i-1]->addr) ||
 434                                ((change_point[i]->addr == change_point[i-1]->addr) &&
 435                                 (change_point[i]->addr == change_point[i]->pbios->addr) &&
 436                                 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
 437                           )
 438                        {
 439                                change_tmp = change_point[i];
 440                                change_point[i] = change_point[i-1];
 441                                change_point[i-1] = change_tmp;
 442                                still_changing=1;
 443                        }
 444                }
 445        }
 446
 447        /* create a new bios memory map, removing overlaps */
 448        overlap_entries=0;       /* number of entries in the overlap table */
 449        new_bios_entry=0;        /* index for creating new bios map entries */
 450        last_type = 0;           /* start with undefined memory type */
 451        last_addr = 0;           /* start with 0 as last starting address */
 452        /* loop through change-points, determining affect on the new bios map */
 453        for (chgidx=0; chgidx < chg_nr; chgidx++)
 454        {
 455                /* keep track of all overlapping bios entries */
 456                if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
 457                {
 458                        /* add map entry to overlap list (> 1 entry implies an overlap) */
 459                        overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
 460                }
 461                else
 462                {
 463                        /* remove entry from list (order independent, so swap with last) */
 464                        for (i=0; i<overlap_entries; i++)
 465                        {
 466                                if (overlap_list[i] == change_point[chgidx]->pbios)
 467                                        overlap_list[i] = overlap_list[overlap_entries-1];
 468                        }
 469                        overlap_entries--;
 470                }
 471                /* if there are overlapping entries, decide which "type" to use */
 472                /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
 473                current_type = 0;
 474                for (i=0; i<overlap_entries; i++)
 475                        if (overlap_list[i]->type > current_type)
 476                                current_type = overlap_list[i]->type;
 477                /* continue building up new bios map based on this information */
 478                if (current_type != last_type)  {
 479                        if (last_type != 0)      {
 480                                new_bios[new_bios_entry].size =
 481                                        change_point[chgidx]->addr - last_addr;
 482                                /* move forward only if the new size was non-zero */
 483                                if (new_bios[new_bios_entry].size != 0)
 484                                        if (++new_bios_entry >= E820MAX)
 485                                                break;  /* no more space left for new bios entries */
 486                        }
 487                        if (current_type != 0)  {
 488                                new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
 489                                new_bios[new_bios_entry].type = current_type;
 490                                last_addr=change_point[chgidx]->addr;
 491                        }
 492                        last_type = current_type;
 493                }
 494        }
 495        new_nr = new_bios_entry;   /* retain count for new bios entries */
 496
 497        /* copy new bios mapping into original location */
 498        memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
 499        *pnr_map = new_nr;
 500
 501        return 0;
 502}
 503
 504/*
 505 * Copy the BIOS e820 map into a safe place.
 506 *
 507 * Sanity-check it while we're at it..
 508 *
 509 * If we're lucky and live on a modern system, the setup code
 510 * will have given us a memory map that we can use to properly
 511 * set up memory.  If we aren't, we'll fake a memory map.
 512 *
 513 * We check to see that the memory map contains at least 2 elements
 514 * before we'll use it, because the detection code in setup.S may
 515 * not be perfect and most every PC known to man has two memory
 516 * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
 517 * thinkpad 560x, for example, does not cooperate with the memory
 518 * detection code.)
 519 */
 520int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
 521{
 522        /* Only one memory region (or negative)? Ignore it */
 523        if (nr_map < 2)
 524                return -1;
 525
 526        do {
 527                unsigned long long start = biosmap->addr;
 528                unsigned long long size = biosmap->size;
 529                unsigned long long end = start + size;
 530                unsigned long type = biosmap->type;
 531
 532                /* Overflow in 64 bits? Ignore the memory map. */
 533                if (start > end)
 534                        return -1;
 535
 536                /*
 537                 * Some BIOSes claim RAM in the 640k - 1M region.
 538                 * Not right. Fix it up.
 539                 */
 540                if (type == E820_RAM) {
 541                        if (start < 0x100000ULL && end > 0xA0000ULL) {
 542                                if (start < 0xA0000ULL)
 543                                        add_memory_region(start, 0xA0000ULL-start, type);
 544                                if (end <= 0x100000ULL)
 545                                        continue;
 546                                start = 0x100000ULL;
 547                                size = end - start;
 548                        }
 549                }
 550                add_memory_region(start, size, type);
 551        } while (biosmap++,--nr_map);
 552        return 0;
 553}
 554
 555/*
 556 * Callback for efi_memory_walk.
 557 */
 558static int __init
 559efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
 560{
 561        unsigned long *max_pfn = arg, pfn;
 562
 563        if (start < end) {
 564                pfn = PFN_UP(end -1);
 565                if (pfn > *max_pfn)
 566                        *max_pfn = pfn;
 567        }
 568        return 0;
 569}
 570
 571static int __init
 572efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
 573{
 574        memory_present(0, PFN_UP(start), PFN_DOWN(end));
 575        return 0;
 576}
 577
 578/*
 579 * Find the highest page frame number we have available
 580 */
 581void __init find_max_pfn(void)
 582{
 583        int i;
 584
 585        max_pfn = 0;
 586        if (efi_enabled) {
 587                efi_memmap_walk(efi_find_max_pfn, &max_pfn);
 588                efi_memmap_walk(efi_memory_present_wrapper, NULL);
 589                return;
 590        }
 591
 592        for (i = 0; i < e820.nr_map; i++) {
 593                unsigned long start, end;
 594                /* RAM? */
 595                if (e820.map[i].type != E820_RAM)
 596                        continue;
 597                start = PFN_UP(e820.map[i].addr);
 598                end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
 599                if (start >= end)
 600                        continue;
 601                if (end > max_pfn)
 602                        max_pfn = end;
 603                memory_present(0, start, end);
 604        }
 605}
 606
 607/*
 608 * Free all available memory for boot time allocation.  Used
 609 * as a callback function by efi_memory_walk()
 610 */
 611
 612static int __init
 613free_available_memory(unsigned long start, unsigned long end, void *arg)
 614{
 615        /* check max_low_pfn */
 616        if (start >= (max_low_pfn << PAGE_SHIFT))
 617                return 0;
 618        if (end >= (max_low_pfn << PAGE_SHIFT))
 619                end = max_low_pfn << PAGE_SHIFT;
 620        if (start < end)
 621                free_bootmem(start, end - start);
 622
 623        return 0;
 624}
 625/*
 626 * Register fully available low RAM pages with the bootmem allocator.
 627 */
 628void __init register_bootmem_low_pages(unsigned long max_low_pfn)
 629{
 630        int i;
 631
 632        if (efi_enabled) {
 633                efi_memmap_walk(free_available_memory, NULL);
 634                return;
 635        }
 636        for (i = 0; i < e820.nr_map; i++) {
 637                unsigned long curr_pfn, last_pfn, size;
 638                /*
 639                 * Reserve usable low memory
 640                 */
 641                if (e820.map[i].type != E820_RAM)
 642                        continue;
 643                /*
 644                 * We are rounding up the start address of usable memory:
 645                 */
 646                curr_pfn = PFN_UP(e820.map[i].addr);
 647                if (curr_pfn >= max_low_pfn)
 648                        continue;
 649                /*
 650                 * ... and at the end of the usable range downwards:
 651                 */
 652                last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
 653
 654                if (last_pfn > max_low_pfn)
 655                        last_pfn = max_low_pfn;
 656
 657                /*
 658                 * .. finally, did all the rounding and playing
 659                 * around just make the area go away?
 660                 */
 661                if (last_pfn <= curr_pfn)
 662                        continue;
 663
 664                size = last_pfn - curr_pfn;
 665                free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
 666        }
 667}
 668
 669void __init e820_register_memory(void)
 670{
 671        unsigned long gapstart, gapsize, round;
 672        unsigned long long last;
 673        int i;
 674
 675        /*
 676         * Search for the bigest gap in the low 32 bits of the e820
 677         * memory space.
 678         */
 679        last = 0x100000000ull;
 680        gapstart = 0x10000000;
 681        gapsize = 0x400000;
 682        i = e820.nr_map;
 683        while (--i >= 0) {
 684                unsigned long long start = e820.map[i].addr;
 685                unsigned long long end = start + e820.map[i].size;
 686
 687                /*
 688                 * Since "last" is at most 4GB, we know we'll
 689                 * fit in 32 bits if this condition is true
 690                 */
 691                if (last > end) {
 692                        unsigned long gap = last - end;
 693
 694                        if (gap > gapsize) {
 695                                gapsize = gap;
 696                                gapstart = end;
 697                        }
 698                }
 699                if (start < last)
 700                        last = start;
 701        }
 702
 703        /*
 704         * See how much we want to round up: start off with
 705         * rounding to the next 1MB area.
 706         */
 707        round = 0x100000;
 708        while ((gapsize >> 4) > round)
 709                round += round;
 710        /* Fun with two's complement */
 711        pci_mem_start = (gapstart + round) & -round;
 712
 713        printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n",
 714                pci_mem_start, gapstart, gapsize);
 715}
 716
 717void __init print_memory_map(char *who)
 718{
 719        int i;
 720
 721        for (i = 0; i < e820.nr_map; i++) {
 722                printk(" %s: %016Lx - %016Lx ", who,
 723                        e820.map[i].addr,
 724                        e820.map[i].addr + e820.map[i].size);
 725                switch (e820.map[i].type) {
 726                case E820_RAM:  printk("(usable)\n");
 727                                break;
 728                case E820_RESERVED:
 729                                printk("(reserved)\n");
 730                                break;
 731                case E820_ACPI:
 732                                printk("(ACPI data)\n");
 733                                break;
 734                case E820_NVS:
 735                                printk("(ACPI NVS)\n");
 736                                break;
 737                default:        printk("type %lu\n", e820.map[i].type);
 738                                break;
 739                }
 740        }
 741}
 742
 743static __init __always_inline void efi_limit_regions(unsigned long long size)
 744{
 745        unsigned long long current_addr = 0;
 746        efi_memory_desc_t *md, *next_md;
 747        void *p, *p1;
 748        int i, j;
 749
 750        j = 0;
 751        p1 = memmap.map;
 752        for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) {
 753                md = p;
 754                next_md = p1;
 755                current_addr = md->phys_addr +
 756                        PFN_PHYS(md->num_pages);
 757                if (is_available_memory(md)) {
 758                        if (md->phys_addr >= size) continue;
 759                        memcpy(next_md, md, memmap.desc_size);
 760                        if (current_addr >= size) {
 761                                next_md->num_pages -=
 762                                        PFN_UP(current_addr-size);
 763                        }
 764                        p1 += memmap.desc_size;
 765                        next_md = p1;
 766                        j++;
 767                } else if ((md->attribute & EFI_MEMORY_RUNTIME) ==
 768                           EFI_MEMORY_RUNTIME) {
 769                        /* In order to make runtime services
 770                         * available we have to include runtime
 771                         * memory regions in memory map */
 772                        memcpy(next_md, md, memmap.desc_size);
 773                        p1 += memmap.desc_size;
 774                        next_md = p1;
 775                        j++;
 776                }
 777        }
 778        memmap.nr_map = j;
 779        memmap.map_end = memmap.map +
 780                (memmap.nr_map * memmap.desc_size);
 781}
 782
 783void __init limit_regions(unsigned long long size)
 784{
 785        unsigned long long current_addr;
 786        int i;
 787
 788        print_memory_map("limit_regions start");
 789        if (efi_enabled) {
 790                efi_limit_regions(size);
 791                return;
 792        }
 793        for (i = 0; i < e820.nr_map; i++) {
 794                current_addr = e820.map[i].addr + e820.map[i].size;
 795                if (current_addr < size)
 796                        continue;
 797
 798                if (e820.map[i].type != E820_RAM)
 799                        continue;
 800
 801                if (e820.map[i].addr >= size) {
 802                        /*
 803                         * This region starts past the end of the
 804                         * requested size, skip it completely.
 805                         */
 806                        e820.nr_map = i;
 807                } else {
 808                        e820.nr_map = i + 1;
 809                        e820.map[i].size -= current_addr - size;
 810                }
 811                print_memory_map("limit_regions endfor");
 812                return;
 813        }
 814        print_memory_map("limit_regions endfunc");
 815}
 816
 817/*
 818 * This function checks if any part of the range <start,end> is mapped
 819 * with type.
 820 */
 821int
 822e820_any_mapped(u64 start, u64 end, unsigned type)
 823{
 824        int i;
 825        for (i = 0; i < e820.nr_map; i++) {
 826                const struct e820entry *ei = &e820.map[i];
 827                if (type && ei->type != type)
 828                        continue;
 829                if (ei->addr >= end || ei->addr + ei->size <= start)
 830                        continue;
 831                return 1;
 832        }
 833        return 0;
 834}
 835EXPORT_SYMBOL_GPL(e820_any_mapped);
 836
 837 /*
 838  * This function checks if the entire range <start,end> is mapped with type.
 839  *
 840  * Note: this function only works correct if the e820 table is sorted and
 841  * not-overlapping, which is the case
 842  */
 843int __init
 844e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
 845{
 846        u64 start = s;
 847        u64 end = e;
 848        int i;
 849        for (i = 0; i < e820.nr_map; i++) {
 850                struct e820entry *ei = &e820.map[i];
 851                if (type && ei->type != type)
 852                        continue;
 853                /* is the region (part) in overlap with the current region ?*/
 854                if (ei->addr >= end || ei->addr + ei->size <= start)
 855                        continue;
 856                /* if the region is at the beginning of <start,end> we move
 857                 * start to the end of the region since it's ok until there
 858                 */
 859                if (ei->addr <= start)
 860                        start = ei->addr + ei->size;
 861                /* if start is now at or beyond end, we're done, full
 862                 * coverage */
 863                if (start >= end)
 864                        return 1; /* we're done */
 865        }
 866        return 0;
 867}
 868
 869static int __init parse_memmap(char *arg)
 870{
 871        if (!arg)
 872                return -EINVAL;
 873
 874        if (strcmp(arg, "exactmap") == 0) {
 875#ifdef CONFIG_CRASH_DUMP
 876                /* If we are doing a crash dump, we
 877                 * still need to know the real mem
 878                 * size before original memory map is
 879                 * reset.
 880                 */
 881                find_max_pfn();
 882                saved_max_pfn = max_pfn;
 883#endif
 884                e820.nr_map = 0;
 885                user_defined_memmap = 1;
 886        } else {
 887                /* If the user specifies memory size, we
 888                 * limit the BIOS-provided memory map to
 889                 * that size. exactmap can be used to specify
 890                 * the exact map. mem=number can be used to
 891                 * trim the existing memory map.
 892                 */
 893                unsigned long long start_at, mem_size;
 894
 895                mem_size = memparse(arg, &arg);
 896                if (*arg == '@') {
 897                        start_at = memparse(arg+1, &arg);
 898                        add_memory_region(start_at, mem_size, E820_RAM);
 899                } else if (*arg == '#') {
 900                        start_at = memparse(arg+1, &arg);
 901                        add_memory_region(start_at, mem_size, E820_ACPI);
 902                } else if (*arg == '$') {
 903                        start_at = memparse(arg+1, &arg);
 904                        add_memory_region(start_at, mem_size, E820_RESERVED);
 905                } else {
 906                        limit_regions(mem_size);
 907                        user_defined_memmap = 1;
 908                }
 909        }
 910        return 0;
 911}
 912early_param("memmap", parse_memmap);
 913
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.