linux/arch/sh/mm/numa.c
<<
>>
Prefs
   1/*
   2 * arch/sh/mm/numa.c - Multiple node support for SH machines
   3 *
   4 *  Copyright (C) 2007  Paul Mundt
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10#include <linux/module.h>
  11#include <linux/bootmem.h>
  12#include <linux/lmb.h>
  13#include <linux/mm.h>
  14#include <linux/numa.h>
  15#include <linux/pfn.h>
  16#include <asm/sections.h>
  17
  18struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
  19EXPORT_SYMBOL_GPL(node_data);
  20
  21/*
  22 * On SH machines the conventional approach is to stash system RAM
  23 * in node 0, and other memory blocks in to node 1 and up, ordered by
  24 * latency. Each node's pgdat is node-local at the beginning of the node,
  25 * immediately followed by the node mem map.
  26 */
  27void __init setup_memory(void)
  28{
  29        unsigned long free_pfn = PFN_UP(__pa(_end));
  30        u64 base = min_low_pfn << PAGE_SHIFT;
  31        u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
  32
  33        lmb_add(base, size);
  34
  35        /* Reserve the LMB regions used by the kernel, initrd, etc.. */
  36        lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
  37                    (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
  38                    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
  39
  40        /*
  41         * Node 0 sets up its pgdat at the first available pfn,
  42         * and bumps it up before setting up the bootmem allocator.
  43         */
  44        NODE_DATA(0) = pfn_to_kaddr(free_pfn);
  45        memset(NODE_DATA(0), 0, sizeof(struct pglist_data));
  46        free_pfn += PFN_UP(sizeof(struct pglist_data));
  47        NODE_DATA(0)->bdata = &bootmem_node_data[0];
  48
  49        /* Set up node 0 */
  50        setup_bootmem_allocator(free_pfn);
  51
  52        /* Give the platforms a chance to hook up their nodes */
  53        plat_mem_setup();
  54}
  55
  56void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
  57{
  58        unsigned long bootmap_pages;
  59        unsigned long start_pfn, end_pfn;
  60        unsigned long bootmem_paddr;
  61
  62        /* Don't allow bogus node assignment */
  63        BUG_ON(nid > MAX_NUMNODES || nid == 0);
  64
  65        start_pfn = start >> PAGE_SHIFT;
  66        end_pfn = end >> PAGE_SHIFT;
  67
  68        lmb_add(start, end - start);
  69
  70        __add_active_range(nid, start_pfn, end_pfn);
  71
  72        /* Node-local pgdat */
  73        NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
  74                                             SMP_CACHE_BYTES, end_pfn));
  75        memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
  76
  77        NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
  78        NODE_DATA(nid)->node_start_pfn = start_pfn;
  79        NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
  80
  81        /* Node-local bootmap */
  82        bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
  83        bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
  84                                       PAGE_SIZE, end_pfn);
  85        init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
  86                          start_pfn, end_pfn);
  87
  88        free_bootmem_with_active_regions(nid, end_pfn);
  89
  90        /* Reserve the pgdat and bootmap space with the bootmem allocator */
  91        reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT,
  92                             sizeof(struct pglist_data), BOOTMEM_DEFAULT);
  93        reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr,
  94                             bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
  95
  96        /* It's up */
  97        node_set_online(nid);
  98
  99        /* Kick sparsemem */
 100        sparse_memory_present_with_active_regions(nid);
 101}
 102
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.