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
  35static void __init mem_prof_init(void)
  36{
  37        unsigned long start_pfn, holes, free_pfn;
  38        const unsigned long zone_alignment = 1UL << (MAX_ORDER - 1);
  39        unsigned long ul;
  40        mem_prof_t *mp;
  41
  42        /* Node#0 SDRAM */
  43        mp = &mem_prof[0];
  44        mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
  45        mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE);
  46        mp->holes = 0;
  47        mp->free_pfn = PFN_UP(__pa(_end));
  48
  49        /* Node#1 internal SRAM */
  50        mp = &mem_prof[1];
  51        start_pfn = free_pfn = PFN_UP(CONFIG_IRAM_START);
  52        holes = 0;
  53        if (start_pfn & (zone_alignment - 1)) {
  54                ul = zone_alignment;
  55                while (start_pfn >= ul)
  56                        ul += zone_alignment;
  57
  58                start_pfn = ul - zone_alignment;
  59                holes = free_pfn - start_pfn;
  60        }
  61
  62        mp->start_pfn = start_pfn;
  63        mp->pages = PFN_DOWN(CONFIG_IRAM_SIZE) + holes;
  64        mp->holes = holes;
  65        mp->free_pfn = PFN_UP(CONFIG_IRAM_START);
  66}
  67
  68unsigned long __init setup_memory(void)
  69{
  70        unsigned long bootmap_size;
  71        unsigned long min_pfn;
  72        int nid;
  73        mem_prof_t *mp;
  74
  75        max_low_pfn = 0;
  76        min_low_pfn = -1;
  77
  78        mem_prof_init();
  79
  80        for_each_online_node(nid) {
  81                mp = &mem_prof[nid];
  82                NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
  83                NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
  84                min_pfn = mp->start_pfn;
  85                max_pfn = mp->start_pfn + mp->pages;
  86                bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
  87                        mp->start_pfn, max_pfn);
  88
  89                free_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  90                        PFN_PHYS(mp->pages));
  91
  92                reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
  93                        PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size,
  94                        BOOTMEM_DEFAULT);
  95
  96                if (max_low_pfn < max_pfn)
  97                        max_low_pfn = max_pfn;
  98
  99                if (min_low_pfn > min_pfn)
 100                        min_low_pfn = min_pfn;
 101        }
 102
 103#ifdef CONFIG_BLK_DEV_INITRD
 104        if (LOADER_TYPE && INITRD_START) {
 105                if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
 106                        reserve_bootmem_node(NODE_DATA(0), INITRD_START,
 107                                INITRD_SIZE, BOOTMEM_DEFAULT);
 108                        initrd_start = INITRD_START + PAGE_OFFSET;
 109                        initrd_end = initrd_start + INITRD_SIZE;
 110                        printk("initrd:start[%08lx],size[%08lx]\n",
 111                                initrd_start, INITRD_SIZE);
 112                } else {
 113                        printk("initrd extends beyond end of memory "
 114                                "(0x%08lx > 0x%08llx)\ndisabling initrd\n",
 115                                INITRD_START + INITRD_SIZE,
 116                                (unsigned long long)PFN_PHYS(max_low_pfn));
 117
 118                        initrd_start = 0;
 119                }
 120        }
 121#endif  /* CONFIG_BLK_DEV_INITRD */
 122
 123        return max_low_pfn;
 124}
 125
 126#define START_PFN(nid)          (NODE_DATA(nid)->bdata->node_min_pfn)
 127#define MAX_LOW_PFN(nid)        (NODE_DATA(nid)->bdata->node_low_pfn)
 128
 129unsigned long __init zone_sizes_init(void)
 130{
 131        unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES];
 132        unsigned long low, start_pfn;
 133        unsigned long holes = 0;
 134        int nid, i;
 135        mem_prof_t *mp;
 136
 137        for_each_online_node(nid) {
 138                mp = &mem_prof[nid];
 139                for (i = 0 ; i < MAX_NR_ZONES ; i++) {
 140                        zones_size[i] = 0;
 141                        zholes_size[i] = 0;
 142                }
 143                start_pfn = START_PFN(nid);
 144                low = MAX_LOW_PFN(nid);
 145                zones_size[ZONE_DMA] = low - start_pfn;
 146                zholes_size[ZONE_DMA] = mp->holes;
 147                holes += zholes_size[ZONE_DMA];
 148
 149                free_area_init_node(nid, zones_size, start_pfn, zholes_size);
 150        }
 151
 152        /*
 153         * For test
 154         *  Use all area of internal RAM.
 155         *  see __alloc_pages()
 156         */
 157        NODE_DATA(1)->node_zones->pages_min = 0;
 158        NODE_DATA(1)->node_zones->pages_low = 0;
 159        NODE_DATA(1)->node_zones->pages_high = 0;
 160
 161        return holes;
 162}
 163
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.