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/memblock.h> |
12 | #include <linux/mm.h> |
13 | #include <linux/numa.h> |
14 | #include <linux/pfn.h> |
15 | #include <asm/sections.h> |
16 | |
17 | struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; |
18 | EXPORT_SYMBOL_GPL(node_data); |
19 | |
20 | /* |
21 | * On SH machines the conventional approach is to stash system RAM |
22 | * in node 0, and other memory blocks in to node 1 and up, ordered by |
23 | * latency. Each node's pgdat is node-local at the beginning of the node, |
24 | * immediately followed by the node mem map. |
25 | */ |
26 | void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) |
27 | { |
28 | unsigned long start_pfn, end_pfn; |
29 | |
30 | /* Don't allow bogus node assignment */ |
31 | BUG_ON(nid >= MAX_NUMNODES || nid <= 0); |
32 | |
33 | start_pfn = PFN_DOWN(start); |
34 | end_pfn = PFN_DOWN(end); |
35 | |
36 | pmb_bolt_mapping((unsigned long)__va(start), start, end - start, |
37 | PAGE_KERNEL); |
38 | |
39 | memblock_add(base: start, size: end - start); |
40 | |
41 | __add_active_range(nid, start_pfn, end_pfn); |
42 | |
43 | /* Node-local pgdat */ |
44 | NODE_DATA(nid) = memblock_alloc_node(size: sizeof(struct pglist_data), |
45 | SMP_CACHE_BYTES, nid); |
46 | if (!NODE_DATA(nid)) |
47 | panic(fmt: "%s: Failed to allocate %zu bytes align=0x%x nid=%d\n" , |
48 | __func__, sizeof(struct pglist_data), SMP_CACHE_BYTES, |
49 | nid); |
50 | |
51 | NODE_DATA(nid)->node_start_pfn = start_pfn; |
52 | NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; |
53 | |
54 | /* It's up */ |
55 | node_set_online(nid); |
56 | } |
57 | |