linux/arch/arm/mm/init.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mm/init.c
   3 *
   4 *  Copyright (C) 1995-2005 Russell King
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 */
  10#include <linux/kernel.h>
  11#include <linux/errno.h>
  12#include <linux/swap.h>
  13#include <linux/init.h>
  14#include <linux/bootmem.h>
  15#include <linux/mman.h>
  16#include <linux/nodemask.h>
  17#include <linux/initrd.h>
  18#include <linux/sort.h>
  19#include <linux/highmem.h>
  20
  21#include <asm/mach-types.h>
  22#include <asm/sections.h>
  23#include <asm/setup.h>
  24#include <asm/sizes.h>
  25#include <asm/tlb.h>
  26
  27#include <asm/mach/arch.h>
  28#include <asm/mach/map.h>
  29
  30#include "mm.h"
  31
  32static unsigned long phys_initrd_start __initdata = 0;
  33static unsigned long phys_initrd_size __initdata = 0;
  34
  35static void __init early_initrd(char **p)
  36{
  37        unsigned long start, size;
  38
  39        start = memparse(*p, p);
  40        if (**p == ',') {
  41                size = memparse((*p) + 1, p);
  42
  43                phys_initrd_start = start;
  44                phys_initrd_size = size;
  45        }
  46}
  47__early_param("initrd=", early_initrd);
  48
  49static int __init parse_tag_initrd(const struct tag *tag)
  50{
  51        printk(KERN_WARNING "ATAG_INITRD is deprecated; "
  52                "please update your bootloader.\n");
  53        phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
  54        phys_initrd_size = tag->u.initrd.size;
  55        return 0;
  56}
  57
  58__tagtable(ATAG_INITRD, parse_tag_initrd);
  59
  60static int __init parse_tag_initrd2(const struct tag *tag)
  61{
  62        phys_initrd_start = tag->u.initrd.start;
  63        phys_initrd_size = tag->u.initrd.size;
  64        return 0;
  65}
  66
  67__tagtable(ATAG_INITRD2, parse_tag_initrd2);
  68
  69/*
  70 * This keeps memory configuration data used by a couple memory
  71 * initialization functions, as well as show_mem() for the skipping
  72 * of holes in the memory map.  It is populated by arm_add_memory().
  73 */
  74struct meminfo meminfo;
  75
  76void show_mem(void)
  77{
  78        int free = 0, total = 0, reserved = 0;
  79        int shared = 0, cached = 0, slab = 0, node, i;
  80        struct meminfo * mi = &meminfo;
  81
  82        printk("Mem-info:\n");
  83        show_free_areas();
  84        for_each_online_node(node) {
  85                pg_data_t *n = NODE_DATA(node);
  86                struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
  87
  88                for_each_nodebank (i,mi,node) {
  89                        struct membank *bank = &mi->bank[i];
  90                        unsigned int pfn1, pfn2;
  91                        struct page *page, *end;
  92
  93                        pfn1 = bank_pfn_start(bank);
  94                        pfn2 = bank_pfn_end(bank);
  95
  96                        page = map + pfn1;
  97                        end  = map + pfn2;
  98
  99                        do {
 100                                total++;
 101                                if (PageReserved(page))
 102                                        reserved++;
 103                                else if (PageSwapCache(page))
 104                                        cached++;
 105                                else if (PageSlab(page))
 106                                        slab++;
 107                                else if (!page_count(page))
 108                                        free++;
 109                                else
 110                                        shared += page_count(page) - 1;
 111                                page++;
 112                        } while (page < end);
 113                }
 114        }
 115
 116        printk("%d pages of RAM\n", total);
 117        printk("%d free pages\n", free);
 118        printk("%d reserved pages\n", reserved);
 119        printk("%d slab pages\n", slab);
 120        printk("%d pages shared\n", shared);
 121        printk("%d pages swap cached\n", cached);
 122}
 123
 124static void __init find_node_limits(int node, struct meminfo *mi,
 125        unsigned long *min, unsigned long *max_low, unsigned long *max_high)
 126{
 127        int i;
 128
 129        *min = -1UL;
 130        *max_low = *max_high = 0;
 131
 132        for_each_nodebank(i, mi, node) {
 133                struct membank *bank = &mi->bank[i];
 134                unsigned long start, end;
 135
 136                start = bank_pfn_start(bank);
 137                end = bank_pfn_end(bank);
 138
 139                if (*min > start)
 140                        *min = start;
 141                if (*max_high < end)
 142                        *max_high = end;
 143                if (bank->highmem)
 144                        continue;
 145                if (*max_low < end)
 146                        *max_low = end;
 147        }
 148}
 149
 150/*
 151 * FIXME: We really want to avoid allocating the bootmap bitmap
 152 * over the top of the initrd.  Hopefully, this is located towards
 153 * the start of a bank, so if we allocate the bootmap bitmap at
 154 * the end, we won't clash.
 155 */
 156static unsigned int __init
 157find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
 158{
 159        unsigned int start_pfn, i, bootmap_pfn;
 160
 161        start_pfn   = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
 162        bootmap_pfn = 0;
 163
 164        for_each_nodebank(i, mi, node) {
 165                struct membank *bank = &mi->bank[i];
 166                unsigned int start, end;
 167
 168                start = bank_pfn_start(bank);
 169                end   = bank_pfn_end(bank);
 170
 171                if (end < start_pfn)
 172                        continue;
 173
 174                if (start < start_pfn)
 175                        start = start_pfn;
 176
 177                if (end <= start)
 178                        continue;
 179
 180                if (end - start >= bootmap_pages) {
 181                        bootmap_pfn = start;
 182                        break;
 183                }
 184        }
 185
 186        if (bootmap_pfn == 0)
 187                BUG();
 188
 189        return bootmap_pfn;
 190}
 191
 192static int __init check_initrd(struct meminfo *mi)
 193{
 194        int initrd_node = -2;
 195#ifdef CONFIG_BLK_DEV_INITRD
 196        unsigned long end = phys_initrd_start + phys_initrd_size;
 197
 198        /*
 199         * Make sure that the initrd is within a valid area of
 200         * memory.
 201         */
 202        if (phys_initrd_size) {
 203                unsigned int i;
 204
 205                initrd_node = -1;
 206
 207                for (i = 0; i < mi->nr_banks; i++) {
 208                        struct membank *bank = &mi->bank[i];
 209                        if (bank_phys_start(bank) <= phys_initrd_start &&
 210                            end <= bank_phys_end(bank))
 211                                initrd_node = bank->node;
 212                }
 213        }
 214
 215        if (initrd_node == -1) {
 216                printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
 217                       "physical memory - disabling initrd\n",
 218                       phys_initrd_start, phys_initrd_size);
 219                phys_initrd_start = phys_initrd_size = 0;
 220        }
 221#endif
 222
 223        return initrd_node;
 224}
 225
 226static inline void map_memory_bank(struct membank *bank)
 227{
 228#ifdef CONFIG_MMU
 229        struct map_desc map;
 230
 231        map.pfn = bank_pfn_start(bank);
 232        map.virtual = __phys_to_virt(bank_phys_start(bank));
 233        map.length = bank_phys_size(bank);
 234        map.type = MT_MEMORY;
 235
 236        create_mapping(&map);
 237#endif
 238}
 239
 240static void __init bootmem_init_node(int node, struct meminfo *mi,
 241        unsigned long start_pfn, unsigned long end_pfn)
 242{
 243        unsigned long boot_pfn;
 244        unsigned int boot_pages;
 245        pg_data_t *pgdat;
 246        int i;
 247
 248        /*
 249         * Map the memory banks for this node.
 250         */
 251        for_each_nodebank(i, mi, node) {
 252                struct membank *bank = &mi->bank[i];
 253
 254                if (!bank->highmem)
 255                        map_memory_bank(bank);
 256        }
 257
 258        /*
 259         * Allocate the bootmem bitmap page.
 260         */
 261        boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
 262        boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
 263
 264        /*
 265         * Initialise the bootmem allocator for this node, handing the
 266         * memory banks over to bootmem.
 267         */
 268        node_set_online(node);
 269        pgdat = NODE_DATA(node);
 270        init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
 271
 272        for_each_nodebank(i, mi, node) {
 273                struct membank *bank = &mi->bank[i];
 274                if (!bank->highmem)
 275                        free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
 276        }
 277
 278        /*
 279         * Reserve the bootmem bitmap for this node.
 280         */
 281        reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
 282                             boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 283}
 284
 285static void __init bootmem_reserve_initrd(int node)
 286{
 287#ifdef CONFIG_BLK_DEV_INITRD
 288        pg_data_t *pgdat = NODE_DATA(node);
 289        int res;
 290
 291        res = reserve_bootmem_node(pgdat, phys_initrd_start,
 292                             phys_initrd_size, BOOTMEM_EXCLUSIVE);
 293
 294        if (res == 0) {
 295                initrd_start = __phys_to_virt(phys_initrd_start);
 296                initrd_end = initrd_start + phys_initrd_size;
 297        } else {
 298                printk(KERN_ERR
 299                        "INITRD: 0x%08lx+0x%08lx overlaps in-use "
 300                        "memory region - disabling initrd\n",
 301                        phys_initrd_start, phys_initrd_size);
 302        }
 303#endif
 304}
 305
 306static void __init bootmem_free_node(int node, struct meminfo *mi)
 307{
 308        unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
 309        unsigned long min, max_low, max_high;
 310        int i;
 311
 312        find_node_limits(node, mi, &min, &max_low, &max_high);
 313
 314        /*
 315         * initialise the zones within this node.
 316         */
 317        memset(zone_size, 0, sizeof(zone_size));
 318
 319        /*
 320         * The size of this node has already been determined.  If we need
 321         * to do anything fancy with the allocation of this memory to the
 322         * zones, now is the time to do it.
 323         */
 324        zone_size[0] = max_low - min;
 325#ifdef CONFIG_HIGHMEM
 326        zone_size[ZONE_HIGHMEM] = max_high - max_low;
 327#endif
 328
 329        /*
 330         * For each bank in this node, calculate the size of the holes.
 331         *  holes = node_size - sum(bank_sizes_in_node)
 332         */
 333        memcpy(zhole_size, zone_size, sizeof(zhole_size));
 334        for_each_nodebank(i, mi, node) {
 335                int idx = 0;
 336#ifdef CONFIG_HIGHMEM
 337                if (mi->bank[i].highmem)
 338                        idx = ZONE_HIGHMEM;
 339#endif
 340                zhole_size[idx] -= bank_pfn_size(&mi->bank[i]);
 341        }
 342
 343        /*
 344         * Adjust the sizes according to any special requirements for
 345         * this machine type.
 346         */
 347        arch_adjust_zones(node, zone_size, zhole_size);
 348
 349        free_area_init_node(node, zone_size, min, zhole_size);
 350}
 351
 352#ifndef CONFIG_SPARSEMEM
 353int pfn_valid(unsigned long pfn)
 354{
 355        struct meminfo *mi = &meminfo;
 356        unsigned int left = 0, right = mi->nr_banks;
 357
 358        do {
 359                unsigned int mid = (right + left) / 2;
 360                struct membank *bank = &mi->bank[mid];
 361
 362                if (pfn < bank_pfn_start(bank))
 363                        right = mid;
 364                else if (pfn >= bank_pfn_end(bank))
 365                        left = mid + 1;
 366                else
 367                        return 1;
 368        } while (left < right);
 369        return 0;
 370}
 371EXPORT_SYMBOL(pfn_valid);
 372
 373static void arm_memory_present(struct meminfo *mi, int node)
 374{
 375}
 376#else
 377static void arm_memory_present(struct meminfo *mi, int node)
 378{
 379        int i;
 380        for_each_nodebank(i, mi, node) {
 381                struct membank *bank = &mi->bank[i];
 382                memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
 383        }
 384}
 385#endif
 386
 387static int __init meminfo_cmp(const void *_a, const void *_b)
 388{
 389        const struct membank *a = _a, *b = _b;
 390        long cmp = bank_pfn_start(a) - bank_pfn_start(b);
 391        return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
 392}
 393
 394void __init bootmem_init(void)
 395{
 396        struct meminfo *mi = &meminfo;
 397        unsigned long min, max_low, max_high;
 398        int node, initrd_node;
 399
 400        sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
 401
 402        /*
 403         * Locate which node contains the ramdisk image, if any.
 404         */
 405        initrd_node = check_initrd(mi);
 406
 407        max_low = max_high = 0;
 408
 409        /*
 410         * Run through each node initialising the bootmem allocator.
 411         */
 412        for_each_node(node) {
 413                unsigned long node_low, node_high;
 414
 415                find_node_limits(node, mi, &min, &node_low, &node_high);
 416
 417                if (node_low > max_low)
 418                        max_low = node_low;
 419                if (node_high > max_high)
 420                        max_high = node_high;
 421
 422                /*
 423                 * If there is no memory in this node, ignore it.
 424                 * (We can't have nodes which have no lowmem)
 425                 */
 426                if (node_low == 0)
 427                        continue;
 428
 429                bootmem_init_node(node, mi, min, node_low);
 430
 431                /*
 432                 * Reserve any special node zero regions.
 433                 */
 434                if (node == 0)
 435                        reserve_node_zero(NODE_DATA(node));
 436
 437                /*
 438                 * If the initrd is in this node, reserve its memory.
 439                 */
 440                if (node == initrd_node)
 441                        bootmem_reserve_initrd(node);
 442
 443                /*
 444                 * Sparsemem tries to allocate bootmem in memory_present(),
 445                 * so must be done after the fixed reservations
 446                 */
 447                arm_memory_present(mi, node);
 448        }
 449
 450        /*
 451         * sparse_init() needs the bootmem allocator up and running.
 452         */
 453        sparse_init();
 454
 455        /*
 456         * Now free memory in each node - free_area_init_node needs
 457         * the sparse mem_map arrays initialized by sparse_init()
 458         * for memmap_init_zone(), otherwise all PFNs are invalid.
 459         */
 460        for_each_node(node)
 461                bootmem_free_node(node, mi);
 462
 463        high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
 464
 465        /*
 466         * This doesn't seem to be used by the Linux memory manager any
 467         * more, but is used by ll_rw_block.  If we can get rid of it, we
 468         * also get rid of some of the stuff above as well.
 469         *
 470         * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
 471         * the system, not the maximum PFN.
 472         */
 473        max_low_pfn = max_low - PHYS_PFN_OFFSET;
 474        max_pfn = max_high - PHYS_PFN_OFFSET;
 475}
 476
 477static inline int free_area(unsigned long pfn, unsigned long end, char *s)
 478{
 479        unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10);
 480
 481        for (; pfn < end; pfn++) {
 482                struct page *page = pfn_to_page(pfn);
 483                ClearPageReserved(page);
 484                init_page_count(page);
 485                __free_page(page);
 486                pages++;
 487        }
 488
 489        if (size && s)
 490                printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
 491
 492        return pages;
 493}
 494
 495static inline void
 496free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
 497{
 498        struct page *start_pg, *end_pg;
 499        unsigned long pg, pgend;
 500
 501        /*
 502         * Convert start_pfn/end_pfn to a struct page pointer.
 503         */
 504        start_pg = pfn_to_page(start_pfn - 1) + 1;
 505        end_pg = pfn_to_page(end_pfn);
 506
 507        /*
 508         * Convert to physical addresses, and
 509         * round start upwards and end downwards.
 510         */
 511        pg = PAGE_ALIGN(__pa(start_pg));
 512        pgend = __pa(end_pg) & PAGE_MASK;
 513
 514        /*
 515         * If there are free pages between these,
 516         * free the section of the memmap array.
 517         */
 518        if (pg < pgend)
 519                free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
 520}
 521
 522/*
 523 * The mem_map array can get very big.  Free the unused area of the memory map.
 524 */
 525static void __init free_unused_memmap_node(int node, struct meminfo *mi)
 526{
 527        unsigned long bank_start, prev_bank_end = 0;
 528        unsigned int i;
 529
 530        /*
 531         * [FIXME] This relies on each bank being in address order.  This
 532         * may not be the case, especially if the user has provided the
 533         * information on the command line.
 534         */
 535        for_each_nodebank(i, mi, node) {
 536                struct membank *bank = &mi->bank[i];
 537
 538                bank_start = bank_pfn_start(bank);
 539                if (bank_start < prev_bank_end) {
 540                        printk(KERN_ERR "MEM: unordered memory banks.  "
 541                                "Not freeing memmap.\n");
 542                        break;
 543                }
 544
 545                /*
 546                 * If we had a previous bank, and there is a space
 547                 * between the current bank and the previous, free it.
 548                 */
 549                if (prev_bank_end && prev_bank_end != bank_start)
 550                        free_memmap(node, prev_bank_end, bank_start);
 551
 552                prev_bank_end = bank_pfn_end(bank);
 553        }
 554}
 555
 556/*
 557 * mem_init() marks the free areas in the mem_map and tells us how much
 558 * memory is free.  This is done after various parts of the system have
 559 * claimed their memory after the kernel image.
 560 */
 561void __init mem_init(void)
 562{
 563        unsigned int codesize, datasize, initsize;
 564        int i, node;
 565
 566#ifndef CONFIG_DISCONTIGMEM
 567        max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 568#endif
 569
 570        /* this will put all unused low memory onto the freelists */
 571        for_each_online_node(node) {
 572                pg_data_t *pgdat = NODE_DATA(node);
 573
 574                free_unused_memmap_node(node, &meminfo);
 575
 576                if (pgdat->node_spanned_pages != 0)
 577                        totalram_pages += free_all_bootmem_node(pgdat);
 578        }
 579
 580#ifdef CONFIG_SA1111
 581        /* now that our DMA memory is actually so designated, we can free it */
 582        totalram_pages += free_area(PHYS_PFN_OFFSET,
 583                                    __phys_to_pfn(__pa(swapper_pg_dir)), NULL);
 584#endif
 585
 586#ifdef CONFIG_HIGHMEM
 587        /* set highmem page free */
 588        for_each_online_node(node) {
 589                for_each_nodebank (i, &meminfo, node) {
 590                        unsigned long start = bank_pfn_start(&meminfo.bank[i]);
 591                        unsigned long end = bank_pfn_end(&meminfo.bank[i]);
 592                        if (start >= max_low_pfn + PHYS_PFN_OFFSET)
 593                                totalhigh_pages += free_area(start, end, NULL);
 594                }
 595        }
 596        totalram_pages += totalhigh_pages;
 597#endif
 598
 599        /*
 600         * Since our memory may not be contiguous, calculate the
 601         * real number of pages we have in this system
 602         */
 603        printk(KERN_INFO "Memory:");
 604        num_physpages = 0;
 605        for (i = 0; i < meminfo.nr_banks; i++) {
 606                num_physpages += bank_pfn_size(&meminfo.bank[i]);
 607                printk(" %ldMB", bank_phys_size(&meminfo.bank[i]) >> 20);
 608        }
 609        printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
 610
 611        codesize = _etext - _text;
 612        datasize = _end - _data;
 613        initsize = __init_end - __init_begin;
 614
 615        printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
 616                "%dK data, %dK init, %luK highmem)\n",
 617                nr_free_pages() << (PAGE_SHIFT-10), codesize >> 10,
 618                datasize >> 10, initsize >> 10,
 619                (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
 620
 621        if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
 622                extern int sysctl_overcommit_memory;
 623                /*
 624                 * On a machine this small we won't get
 625                 * anywhere without overcommit, so turn
 626                 * it on by default.
 627                 */
 628                sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
 629        }
 630}
 631
 632void free_initmem(void)
 633{
 634#ifdef CONFIG_HAVE_TCM
 635        extern char *__tcm_start, *__tcm_end;
 636
 637        totalram_pages += free_area(__phys_to_pfn(__pa(__tcm_start)),
 638                                    __phys_to_pfn(__pa(__tcm_end)),
 639                                    "TCM link");
 640#endif
 641
 642        if (!machine_is_integrator() && !machine_is_cintegrator())
 643                totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
 644                                            __phys_to_pfn(__pa(__init_end)),
 645                                            "init");
 646}
 647
 648#ifdef CONFIG_BLK_DEV_INITRD
 649
 650static int keep_initrd;
 651
 652void free_initrd_mem(unsigned long start, unsigned long end)
 653{
 654        if (!keep_initrd)
 655                totalram_pages += free_area(__phys_to_pfn(__pa(start)),
 656                                            __phys_to_pfn(__pa(end)),
 657                                            "initrd");
 658}
 659
 660static int __init keepinitrd_setup(char *__unused)
 661{
 662        keep_initrd = 1;
 663        return 1;
 664}
 665
 666__setup("keepinitrd", keepinitrd_setup);
 667#endif
 668