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);
  23
  24pg_data_t m32r_node_data[MAX_NUMNODES];
  25
  26/* Memory profile */
  27typedef struct {
  28        unsigned long start_pfn;
  29        unsigned long pages;
  30        unsigned long holes;
  31        unsigned long free_pfn;
  32} mem_prof_t;
  33static mem_prof_t mem_prof[MAX_NUMNODES];
  34
  35extern unsigned long memory_start;
  36extern unsigned long memory_end;
  37
  38static void __init mem_prof_init(void)
  39{
  40        unsigned long start_pfn, holes, free_pfn;
  41        const unsigned long zone_alignment = 1UL << (MAX_ORDER - 1);
  42        unsigned long ul;
  43        mem_prof_t *mp;
  44
  45        /* Node#0 SDRAM */
  46        mp = &mem_prof[0];
  47        mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
  48        mp->pages = PFN_DOWN(memory_end - memory_start);
  49        mp->holes = 0;
  50        mp->free_pfn = PFN_UP(__pa(_end));
  51
  52        /* Node#1 internal SRAM */
  53        mp = &mem_prof[1];
  54        start_pfn = free_pfn = PFN_UP(CONFIG_IRAM_START);
  55        holes = 0;
  56        if (start_pfn & (zone_alignment - 1)) {
  57                ul = zone_alignment;
  58                while (start_pfn >= ul)
  59                        ul += zone_alignment;
  60
  61                start_pfn = ul - zone_alignment;
  62                holes = free_pfn - start_pfn;
  63        }
  64
  65        mp->start_pfn = start_pfn;
  66        mp->pages = PFN_DOWN(CONFIG_IRAM_SIZE) + holes;
  67        mp->holes = holes;
  68        mp->free_pfn = PFN_UP(CONFIG_IRAM_START);
  69}
  70
  71unsigned long __init setup_memory(void)
  72{
  73        unsigned long bootmap_size;
  74        unsigned long min_pfn;
  75        int nid;
  76        mem_prof_t *mp;
  77
  78        max_low_pfn = 0;
  79        min_low_pfn = -1;
  80
  81        mem_prof_init();
  82
  83        for_each_online_node(nid) {
  84                mp = &mem_prof[nid];
  85                NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
  86                NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
  87                min_pfn = mp->start_pfn;
  88                max_pfn = mp->start_pfn + mp->pages;
  89                bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
  90                        mp->start_pfn, max_pfn);
  91
  92                free_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  93                        PFN_PHYS(mp->pages));
  94
  95                reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  96                        PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size,
  97                        BOOTMEM_DEFAULT);
  98
  99                if (max_low_pfn < max_pfn)
 100                        max_low_pfn = max_pfn;
 101
 102                if (min_low_pfn > min_pfn)
 103                        min_low_pfn = min_pfn;
 104        }
 105
 106#ifdef CONFIG_BLK_DEV_INITRD
 107        if (LOADER_TYPE && INITRD_START) {
 108                if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
 109                        reserve_bootmem_node(NODE_DATA(0), INITRD_START,
 110                                INITRD_SIZE, BOOTMEM_DEFAULT);
 111                        initrd_start = INITRD_START + PAGE_OFFSET;
 112                        initrd_end = initrd_start + INITRD_SIZE;
 113                        printk("initrd:start[%08lx],size[%08lx]\n",
 114                                initrd_start, INITRD_SIZE);
 115                } else {
 116                        printk("initrd extends beyond end of memory "
 117                                "(0x%08lx > 0x%08llx)\ndisabling initrd\n",
 118                                INITRD_START + INITRD_SIZE,
 119                                (unsigned long long)PFN_PHYS(max_low_pfn));
 120
 121                        initrd_start = 0;
 122                }
 123        }
 124#endif  /* CONFIG_BLK_DEV_INITRD */
 125
 126        return max_low_pfn;
 127}
 128
 129#define START_PFN(nid)          (NODE_DATA(nid)->bdata->node_min_pfn)
 130#define MAX_LOW_PFN(nid)        (NODE_DATA(nid)->bdata->node_low_pfn)
 131
 132void __init zone_sizes_init(void)
 133{
 134        unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES];
 135        unsigned long low, start_pfn;
 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
 150                node_set_state(nid, N_NORMAL_MEMORY);
 151                free_area_init_node(nid, zones_size, start_pfn, zholes_size);
 152        }
 153
 154        /*
 155         * For test
 156         *  Use all area of internal RAM.
 157         *  see __alloc_pages()
 158         */
 159        NODE_DATA(1)->node_zones->watermark[WMARK_MIN] = 0;
 160        NODE_DATA(1)->node_zones->watermark[WMARK_LOW] = 0;
 161        NODE_DATA(1)->node_zones->watermark[WMARK_HIGH] = 0;
 162}
 163