linux/arch/m32r/mm/discontig.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/m32r/mm/discontig.c
   3 *
   4 *  Discontig memory support
   5 *
   6 *  Copyright (c) 2003  Hitoshi Yamamoto
   7 */
   8
   9#include <linux/mm.h>
  10#include <linux/bootmem.h>
  11#include <linux/mmzone.h>
  12#include <linux/initrd.h>
  13#include <linux/nodemask.h>
  14#include <linux/module.h>
  15#include <linux/pfn.h>
  16
  17#include <asm/setup.h>
  18
  19extern char _end[];
  20
  21struct pglist_data *node_data[MAX_NUMNODES];
  22EXPORT_SYMBOL(node_data);
  23static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata;
  24
  25pg_data_t m32r_node_data[MAX_NUMNODES];
  26
  27/* Memory profile */
  28typedef struct {
  29        unsigned long start_pfn;
  30        unsigned long pages;
  31        unsigned long holes;
  32        unsigned long free_pfn;
  33} mem_prof_t;
  34static mem_prof_t mem_prof[MAX_NUMNODES];
  35
  36static void __init mem_prof_init(void)
  37{
  38        unsigned long start_pfn, holes, free_pfn;
  39        const unsigned long zone_alignment = 1UL << (MAX_ORDER - 1);
  40        unsigned long ul;
  41        mem_prof_t *mp;
  42
  43        /* Node#0 SDRAM */
  44        mp = &mem_prof[0];
  45        mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
  46        mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE);
  47        mp->holes = 0;
  48        mp->free_pfn = PFN_UP(__pa(_end));
  49
  50        /* Node#1 internal SRAM */
  51        mp = &mem_prof[1];
  52        start_pfn = free_pfn = PFN_UP(CONFIG_IRAM_START);
  53        holes = 0;
  54        if (start_pfn & (zone_alignment - 1)) {
  55                ul = zone_alignment;
  56                while (start_pfn >= ul)
  57                        ul += zone_alignment;
  58
  59                start_pfn = ul - zone_alignment;
  60                holes = free_pfn - start_pfn;
  61        }
  62
  63        mp->start_pfn = start_pfn;
  64        mp->pages = PFN_DOWN(CONFIG_IRAM_SIZE) + holes;
  65        mp->holes = holes;
  66        mp->free_pfn = PFN_UP(CONFIG_IRAM_START);
  67}
  68
  69unsigned long __init setup_memory(void)
  70{
  71        unsigned long bootmap_size;
  72        unsigned long min_pfn;
  73        int nid;
  74        mem_prof_t *mp;
  75
  76        max_low_pfn = 0;
  77        min_low_pfn = -1;
  78
  79        mem_prof_init();
  80
  81        for_each_online_node(nid) {
  82                mp = &mem_prof[nid];
  83                NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
  84                NODE_DATA(nid)->bdata = &node_bdata[nid];
  85                min_pfn = mp->start_pfn;
  86                max_pfn = mp->start_pfn + mp->pages;
  87                bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
  88                        mp->start_pfn, max_pfn);
  89
  90                free_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  91                        PFN_PHYS(mp->pages));
  92
  93                reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  94                        PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size,
  95                        BOOTMEM_DEFAULT);
  96
  97                if (max_low_pfn < max_pfn)
  98                        max_low_pfn = max_pfn;
  99
 100                if (min_low_pfn > min_pfn)
 101                        min_low_pfn = min_pfn;
 102        }
 103
 104#ifdef CONFIG_BLK_DEV_INITRD
 105        if (LOADER_TYPE && INITRD_START) {
 106                if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
 107                        reserve_bootmem_node(NODE_DATA(0), INITRD_START,
 108                                INITRD_SIZE, BOOTMEM_DEFAULT);
 109                        initrd_start = INITRD_START + PAGE_OFFSET;
 110                        initrd_end = initrd_start + INITRD_SIZE;
 111                        printk("initrd:start[%08lx],size[%08lx]\n",
 112                                initrd_start, INITRD_SIZE);
 113                } else {
 114                        printk("initrd extends beyond end of memory "
 115                                "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
 116                                INITRD_START + INITRD_SIZE,
 117                                PFN_PHYS(max_low_pfn));
 118
 119                        initrd_start = 0;
 120                }
 121        }
 122#endif  /* CONFIG_BLK_DEV_INITRD */
 123
 124        return max_low_pfn;
 125}
 126
 127#define START_PFN(nid)  \
 128        (NODE_DATA(nid)->bdata->node_boot_start >> PAGE_SHIFT)
 129#define MAX_LOW_PFN(nid)        (NODE_DATA(nid)->bdata->node_low_pfn)
 130
 131unsigned long __init zone_sizes_init(void)
 132{
 133        unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES];
 134        unsigned long low, start_pfn;
 135        unsigned long holes = 0;
 136        int nid, i;
 137        mem_prof_t *mp;
 138
 139        for_each_online_node(nid) {
 140                mp = &mem_prof[nid];
 141                for (i = 0 ; i < MAX_NR_ZONES ; i++) {
 142                        zones_size[i] = 0;
 143                        zholes_size[i] = 0;
 144                }
 145                start_pfn = START_PFN(nid);
 146                low = MAX_LOW_PFN(nid);
 147                zones_size[ZONE_DMA] = low - start_pfn;
 148                zholes_size[ZONE_DMA] = mp->holes;
 149                holes += zholes_size[ZONE_DMA];
 150
 151                free_area_init_node(nid, NODE_DATA(nid), zones_size,
 152                        start_pfn, zholes_size);
 153        }
 154
 155        /*
 156         * For test
 157         *  Use all area of internal RAM.
 158         *  see __alloc_pages()
 159         */
 160        NODE_DATA(1)->node_zones->pages_min = 0;
 161        NODE_DATA(1)->node_zones->pages_low = 0;
 162        NODE_DATA(1)->node_zones->pages_high = 0;
 163
 164        return holes;
 165}
 166
 167
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.