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