2007-06-06 12:52:19 +04:00
/*
* arch / sh / mm / numa . c - Multiple node support for SH machines
*
* Copyright ( C ) 2007 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/module.h>
# include <linux/bootmem.h>
2010-07-12 08:36:09 +04:00
# include <linux/memblock.h>
2007-06-06 12:52:19 +04:00
# include <linux/mm.h>
# include <linux/numa.h>
# include <linux/pfn.h>
# include <asm/sections.h>
struct pglist_data * node_data [ MAX_NUMNODES ] __read_mostly ;
EXPORT_SYMBOL_GPL ( node_data ) ;
/*
* On SH machines the conventional approach is to stash system RAM
* in node 0 , and other memory blocks in to node 1 and up , ordered by
* latency . Each node ' s pgdat is node - local at the beginning of the node ,
* immediately followed by the node mem map .
*/
void __init setup_bootmem_node ( int nid , unsigned long start , unsigned long end )
{
2009-07-04 02:34:51 +04:00
unsigned long bootmap_pages ;
unsigned long start_pfn , end_pfn ;
unsigned long bootmem_paddr ;
2007-06-06 12:52:19 +04:00
/* Don't allow bogus node assignment */
2014-12-11 02:41:31 +03:00
BUG_ON ( nid > = MAX_NUMNODES | | nid < = 0 ) ;
2007-06-06 12:52:19 +04:00
2015-09-05 01:43:35 +03:00
start_pfn = PFN_DOWN ( start ) ;
end_pfn = PFN_DOWN ( end ) ;
2007-06-06 12:52:19 +04:00
2010-03-03 07:16:31 +03:00
pmb_bolt_mapping ( ( unsigned long ) __va ( start ) , start , end - start ,
PAGE_KERNEL ) ;
2010-07-12 08:36:09 +04:00
memblock_add ( start , end - start ) ;
2009-07-04 02:34:51 +04:00
2008-04-23 15:56:44 +04:00
__add_active_range ( nid , start_pfn , end_pfn ) ;
2007-06-06 12:52:19 +04:00
/* Node-local pgdat */
2010-07-12 08:36:09 +04:00
NODE_DATA ( nid ) = __va ( memblock_alloc_base ( sizeof ( struct pglist_data ) ,
2009-12-07 17:16:07 +03:00
SMP_CACHE_BYTES , end ) ) ;
2007-06-06 12:52:19 +04:00
memset ( NODE_DATA ( nid ) , 0 , sizeof ( struct pglist_data ) ) ;
2008-07-24 08:26:55 +04:00
NODE_DATA ( nid ) - > bdata = & bootmem_node_data [ nid ] ;
2007-06-06 12:52:19 +04:00
NODE_DATA ( nid ) - > node_start_pfn = start_pfn ;
NODE_DATA ( nid ) - > node_spanned_pages = end_pfn - start_pfn ;
/* Node-local bootmap */
bootmap_pages = bootmem_bootmap_pages ( end_pfn - start_pfn ) ;
2010-07-12 08:36:09 +04:00
bootmem_paddr = memblock_alloc_base ( bootmap_pages < < PAGE_SHIFT ,
2009-12-07 17:16:07 +03:00
PAGE_SIZE , end ) ;
2009-07-04 02:34:51 +04:00
init_bootmem_node ( NODE_DATA ( nid ) , bootmem_paddr > > PAGE_SHIFT ,
start_pfn , end_pfn ) ;
2007-06-06 12:52:19 +04:00
free_bootmem_with_active_regions ( nid , end_pfn ) ;
/* Reserve the pgdat and bootmap space with the bootmem allocator */
reserve_bootmem_node ( NODE_DATA ( nid ) , start_pfn < < PAGE_SHIFT ,
2008-02-07 11:15:17 +03:00
sizeof ( struct pglist_data ) , BOOTMEM_DEFAULT ) ;
2009-07-04 02:34:51 +04:00
reserve_bootmem_node ( NODE_DATA ( nid ) , bootmem_paddr ,
2008-02-07 11:15:17 +03:00
bootmap_pages < < PAGE_SHIFT , BOOTMEM_DEFAULT ) ;
2007-06-06 12:52:19 +04:00
/* It's up */
node_set_online ( nid ) ;
/* Kick sparsemem */
sparse_memory_present_with_active_regions ( nid ) ;
}