Blame view

arch/mips/sgi-ip27/ip27-init.c 5.36 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
  /*
   * 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.
   *
   * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com)
   * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/sched.h>
631330f58   Ralf Baechle   MIPS: Build fix -...
12
  #include <linux/smp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/cpumask.h>
  #include <asm/cpu.h>
  #include <asm/io.h>
  #include <asm/pgtable.h>
  #include <asm/time.h>
  #include <asm/sn/types.h>
  #include <asm/sn/sn0/addrs.h>
  #include <asm/sn/sn0/hubni.h>
  #include <asm/sn/sn0/hubio.h>
  #include <asm/sn/klconfig.h>
  #include <asm/sn/ioc3.h>
  #include <asm/mipsregs.h>
  #include <asm/sn/gda.h>
  #include <asm/sn/hub.h>
  #include <asm/sn/intr.h>
  #include <asm/current.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  #include <asm/processor.h>
  #include <asm/mmu_context.h>
  #include <asm/thread_info.h>
  #include <asm/sn/launch.h>
  #include <asm/sn/sn_private.h>
  #include <asm/sn/sn0/ip27.h>
  #include <asm/sn/mapped_kernel.h>
  
  #define CPU_NONE		(cpuid_t)-1
  
  static DECLARE_BITMAP(hub_init_mask, MAX_COMPACT_NODES);
  nasid_t master_nasid = INVALID_NASID;
  
  cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
  nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
  cnodeid_t	cpuid_to_compact_node[MAXCPUS];
  
  EXPORT_SYMBOL(nasid_to_compact_node);
cc6e8e081   Ralf Baechle   [MIPS] Remove IP2...
49
50
  struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
  EXPORT_SYMBOL_GPL(sn_cpu_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
  extern void pcibr_setup(cnodeid_t);
  
  extern void xtalk_probe_node(cnodeid_t nid);
234fcd148   Ralf Baechle   [MIPS] Fix loads ...
54
  static void __cpuinit per_hub_init(cnodeid_t cnode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
  {
  	struct hub_data *hub = hub_data(cnode);
  	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
4f12bfe5a   Ralf Baechle   HUB interrupts ar...
58
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
  
  	cpu_set(smp_processor_id(), hub->h_cpus);
  
  	if (test_and_set_bit(cnode, hub_init_mask))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
  	/*
  	 * Set CRB timeout at 5ms, (< PI timeout of 10ms)
  	 */
  	REMOTE_HUB_S(nasid, IIO_ICTP, 0x800);
  	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
  
  	hub_rtc_init(cnode);
  	xtalk_probe_node(cnode);
  
  #ifdef CONFIG_REPLICATE_EXHANDLERS
  	/*
  	 * If this is not a headless node initialization,
  	 * copy over the caliased exception handlers.
  	 */
  	if (get_compact_nodeid() == cnode) {
  		extern char except_vec2_generic, except_vec3_generic;
  		extern void build_tlb_refill_handler(void);
  
  		memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80);
  		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80);
  		build_tlb_refill_handler();
  		memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80);
  		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100);
  		__flush_cache_all();
  	}
  #endif
4f12bfe5a   Ralf Baechle   HUB interrupts ar...
90
91
92
  
  	/*
  	 * Some interrupts are reserved by hardware or by software convention.
25985edce   Lucas De Marchi   Fix common misspe...
93
  	 * Mark these as reserved right away so they won't be used accidentally
4f12bfe5a   Ralf Baechle   HUB interrupts ar...
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  	 * later.
  	 */
  	for (i = 0; i <= BASE_PCI_IRQ; i++) {
  		__set_bit(i, hub->irq_alloc_mask);
  		LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i);
  	}
  
  	__set_bit(IP_PEND0_6_63, hub->irq_alloc_mask);
  	LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63);
  
  	for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) {
  		__set_bit(i, hub->irq_alloc_mask);
  		LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
  }
06d428d71   Ralf Baechle   [MIPS] time: SMP/...
109
  void __cpuinit per_cpu_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
114
115
116
117
118
119
120
121
  {
  	int cpu = smp_processor_id();
  	int slice = LOCAL_HUB_L(PI_CPU_NUM);
  	cnodeid_t cnode = get_compact_nodeid();
  	struct hub_data *hub = hub_data(cnode);
  	struct slice_data *si = hub->slice + slice;
  	int i;
  
  	if (test_and_set_bit(slice, &hub->slice_map))
  		return;
  
  	clear_c0_status(ST0_IM);
4f12bfe5a   Ralf Baechle   HUB interrupts ar...
122
  	per_hub_init(cnode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
126
  	for (i = 0; i < LEVELS_PER_SLICE; i++)
  		si->level_to_irq[i] = -1;
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
129
130
131
132
133
134
135
136
137
138
  	 * We use this so we can find the local hub's data as fast as only
  	 * possible.
  	 */
  	cpu_data[cpu].data = si;
  
  	cpu_time_init();
  	install_ipi();
  
  	/* Install our NMI handler if symmon hasn't installed one. */
  	install_cpu_nmi_handler(cputoslice(cpu));
  
  	set_c0_status(SRB_DEV0 | SRB_DEV1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  }
  
  /*
   * get_nasid() returns the physical node id number of the caller.
   */
  nasid_t
  get_nasid(void)
  {
  	return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
  	                 >> NSRI_NODEID_SHFT);
  }
  
  /*
   * Map the physical node id to a virtual node id (virtual node ids are contiguous).
   */
  cnodeid_t get_compact_nodeid(void)
  {
  	return NASID_TO_COMPACT_NODEID(get_nasid());
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
160
161
162
163
164
165
166
167
  static inline void ioc3_eth_init(void)
  {
  	struct ioc3 *ioc3;
  	nasid_t nid;
  
  	nid = get_nasid();
  	ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
  
  	ioc3->eier = 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  extern void ip27_reboot_setup(void);
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
169
  void __init plat_mem_setup(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
  {
  	hubreg_t p, e, n_mode;
  	nasid_t nid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
  	ip27_reboot_setup();
  
  	/*
  	 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
  	 */
  	nid = get_nasid();
  	printk("IP27: Running on node %d.
  ", nid);
  
  	p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
  	e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
  	printk("Node %d has %s primary CPU%s.
  ", nid,
  	       p ? "a" : "no",
  	       e ? ", CPU is running" : "");
  
  	p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
  	e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
  	printk("Node %d has %s secondary CPU%s.
  ", nid,
  	       p ? "a" : "no",
  	       e ? ", CPU is running" : "");
  
  	/*
  	 * Try to catch kernel missconfigurations and give user an
  	 * indication what option to select.
  	 */
  	n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
  	printk("Machine is in %c mode.
  ", n_mode ? 'N' : 'M');
aa9772e33   Ralf Baechle   [MIPS] SN: Rename...
203
  #ifdef CONFIG_SGI_SN_N_MODE
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
208
209
  	if (!n_mode)
  		panic("Kernel compiled for M mode.");
  #else
  	if (n_mode)
  		panic("Kernel compiled for N mode.");
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
213
  	ioc3_eth_init();
  	per_cpu_init();
  
  	set_io_port_base(IO_BASE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  }