Blame view

arch/mips/sgi-ip27/ip27-klnuma.c 3.61 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
  /*
   * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00.
   * Copyright 2000 - 2001 Silicon Graphics, Inc.
   * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com)
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
  #include <linux/init.h>
27ac792ca   Andrea Righi   PAGE_ALIGN(): cor...
7
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
14
  #include <linux/mmzone.h>
  #include <linux/kernel.h>
  #include <linux/nodemask.h>
  #include <linux/string.h>
  
  #include <asm/page.h>
  #include <asm/sections.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  #include <asm/sn/types.h>
  #include <asm/sn/arch.h>
  #include <asm/sn/gda.h>
  #include <asm/sn/hub.h>
  #include <asm/sn/mapped_kernel.h>
  #include <asm/sn/sn_private.h>
  
  static cpumask_t ktext_repmask;
  
  /*
   * XXX - This needs to be much smarter about where it puts copies of the
   * kernel.  For example, we should never put a copy on a headless node,
   * and we should respect the topology of the machine.
   */
c11b3c1bc   Ralf Baechle   [MIPS] IP27: Make...
29
  void __init setup_replication_mask(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
  	/* Set only the master cnode's bit.  The master cnode is always 0. */
  	cpus_clear(ktext_repmask);
  	cpu_set(0, ktext_repmask);
  
  #ifdef CONFIG_REPLICATE_KTEXT
  #ifndef CONFIG_MAPPED_KERNEL
  #error Kernel replication works with mapped kernel support. No calias support.
  #endif
89c960961   Ralf Baechle   [MIPS] IP27: Fix ...
39
40
41
42
43
44
45
46
47
  	{
  		cnodeid_t	cnode;
  
  		for_each_online_node(cnode) {
  			if (cnode == 0)
  				continue;
  			/* Advertise that we have a copy of the kernel */
  			cpu_set(cnode, ktext_repmask);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
50
51
52
53
54
55
56
  	}
  #endif
  	/* Set up a GDA pointer to the replication mask. */
  	GDA->g_ktext_repmask = &ktext_repmask;
  }
  
  
  static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  	kern_vars_t *kvp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  	kvp = &hub_data(client_nasid)->kern_vars;
  
  	KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp;
  
  	kvp->kv_magic = KV_MAGIC;
  	kvp->kv_ro_nasid = server_nasid;
  	kvp->kv_rw_nasid = master_nasid;
  	kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid);
  	kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid);
  	printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d
  ", client_nasid, server_nasid, master_nasid);
  }
  
  /* XXX - When the BTE works, we should use it instead of this. */
  static __init void copy_kernel(nasid_t dest_nasid)
  {
  	unsigned long dest_kern_start, source_start, source_end, kern_size;
  
  	source_start = (unsigned long) _stext;
  	source_end = (unsigned long) _etext;
  	kern_size = source_end - source_start;
  
  	dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start),
  					    dest_nasid);
  	memcpy((void *)dest_kern_start, (void *)source_start, kern_size);
  }
  
  void __init replicate_kernel_text()
  {
  	cnodeid_t cnode;
  	nasid_t client_nasid;
  	nasid_t server_nasid;
  
  	server_nasid = master_nasid;
  
  	/* Record where the master node should get its kernel text */
  	set_ktext_source(master_nasid, master_nasid);
  
  	for_each_online_node(cnode) {
  		if (cnode == 0)
  			continue;
  		client_nasid = COMPACT_TO_NASID_NODEID(cnode);
  
  		/* Check if this node should get a copy of the kernel */
  		if (cpu_isset(cnode, ktext_repmask)) {
  			server_nasid = client_nasid;
  			copy_kernel(server_nasid);
  		}
  
  		/* Record where this node should get its kernel text */
  		set_ktext_source(client_nasid, server_nasid);
  	}
  }
  
  /*
   * Return pfn of first free page of memory on a node. PROM may allocate
   * data structures on the first couple of pages of the first slot of each
   * node. If this is the case, getfirstfree(node) > getslotstart(node, 0).
   */
  pfn_t node_getfirstfree(cnodeid_t cnode)
  {
  	unsigned long loadbase = REP_BASE;
  	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
  	unsigned long offset;
  
  #ifdef CONFIG_MAPPED_KERNEL
  	loadbase += 16777216;
  #endif
  	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
  	if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
  		return (TO_NODE(nasid, offset) >> PAGE_SHIFT);
  	else
  		return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >>
  								PAGE_SHIFT);
  }