aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/setup_64.c
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-12-03 06:11:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 12:17:21 -0500
commita88b5ba8bd8ac18aad65ee6c6a254e2e74876db3 (patch)
treeeb3d0ffaf53c3f7ec6083752c2097cecd1cb892a /arch/sparc/kernel/setup_64.c
parentd670bd4f803c8b646acd20f3ba21e65458293faf (diff)
sparc,sparc64: unify kernel/
o Move all files from sparc64/kernel/ to sparc/kernel - rename as appropriate o Update sparc/Makefile to the changes o Update sparc/kernel/Makefile to include the sparc64 files NOTE: This commit changes link order on sparc64! Link order had to change for either of sparc32 and sparc64. And assuming sparc64 see more testing than sparc32 change link order on sparc64 where issues will be caught faster. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/setup_64.c')
-rw-r--r--arch/sparc/kernel/setup_64.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
new file mode 100644
index 000000000000..c8b03a4f68bf
--- /dev/null
+++ b/arch/sparc/kernel/setup_64.c
@@ -0,0 +1,428 @@
1/*
2 * linux/arch/sparc64/kernel/setup.c
3 *
4 * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 */
7
8#include <linux/errno.h>
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/mm.h>
12#include <linux/stddef.h>
13#include <linux/unistd.h>
14#include <linux/ptrace.h>
15#include <linux/slab.h>
16#include <asm/smp.h>
17#include <linux/user.h>
18#include <linux/screen_info.h>
19#include <linux/delay.h>
20#include <linux/fs.h>
21#include <linux/seq_file.h>
22#include <linux/syscalls.h>
23#include <linux/kdev_t.h>
24#include <linux/major.h>
25#include <linux/string.h>
26#include <linux/init.h>
27#include <linux/inet.h>
28#include <linux/console.h>
29#include <linux/root_dev.h>
30#include <linux/interrupt.h>
31#include <linux/cpu.h>
32#include <linux/initrd.h>
33
34#include <asm/system.h>
35#include <asm/io.h>
36#include <asm/processor.h>
37#include <asm/oplib.h>
38#include <asm/page.h>
39#include <asm/pgtable.h>
40#include <asm/idprom.h>
41#include <asm/head.h>
42#include <asm/starfire.h>
43#include <asm/mmu_context.h>
44#include <asm/timer.h>
45#include <asm/sections.h>
46#include <asm/setup.h>
47#include <asm/mmu.h>
48#include <asm/ns87303.h>
49
50#ifdef CONFIG_IP_PNP
51#include <net/ipconfig.h>
52#endif
53
54#include "entry.h"
55
56/* Used to synchronize accesses to NatSemi SUPER I/O chip configure
57 * operations in asm/ns87303.h
58 */
59DEFINE_SPINLOCK(ns87303_lock);
60
61struct screen_info screen_info = {
62 0, 0, /* orig-x, orig-y */
63 0, /* unused */
64 0, /* orig-video-page */
65 0, /* orig-video-mode */
66 128, /* orig-video-cols */
67 0, 0, 0, /* unused, ega_bx, unused */
68 54, /* orig-video-lines */
69 0, /* orig-video-isVGA */
70 16 /* orig-video-points */
71};
72
73static void
74prom_console_write(struct console *con, const char *s, unsigned n)
75{
76 prom_write(s, n);
77}
78
79/* Exported for mm/init.c:paging_init. */
80unsigned long cmdline_memory_size = 0;
81
82static struct console prom_early_console = {
83 .name = "earlyprom",
84 .write = prom_console_write,
85 .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
86 .index = -1,
87};
88
89/*
90 * Process kernel command line switches that are specific to the
91 * SPARC or that require special low-level processing.
92 */
93static void __init process_switch(char c)
94{
95 switch (c) {
96 case 'd':
97 case 's':
98 break;
99 case 'h':
100 prom_printf("boot_flags_init: Halt!\n");
101 prom_halt();
102 break;
103 case 'p':
104 /* Just ignore, this behavior is now the default. */
105 break;
106 case 'P':
107 /* Force UltraSPARC-III P-Cache on. */
108 if (tlb_type != cheetah) {
109 printk("BOOT: Ignoring P-Cache force option.\n");
110 break;
111 }
112 cheetah_pcache_forced_on = 1;
113 add_taint(TAINT_MACHINE_CHECK);
114 cheetah_enable_pcache();
115 break;
116
117 default:
118 printk("Unknown boot switch (-%c)\n", c);
119 break;
120 }
121}
122
123static void __init boot_flags_init(char *commands)
124{
125 while (*commands) {
126 /* Move to the start of the next "argument". */
127 while (*commands && *commands == ' ')
128 commands++;
129
130 /* Process any command switches, otherwise skip it. */
131 if (*commands == '\0')
132 break;
133 if (*commands == '-') {
134 commands++;
135 while (*commands && *commands != ' ')
136 process_switch(*commands++);
137 continue;
138 }
139 if (!strncmp(commands, "mem=", 4)) {
140 /*
141 * "mem=XXX[kKmM]" overrides the PROM-reported
142 * memory size.
143 */
144 cmdline_memory_size = simple_strtoul(commands + 4,
145 &commands, 0);
146 if (*commands == 'K' || *commands == 'k') {
147 cmdline_memory_size <<= 10;
148 commands++;
149 } else if (*commands=='M' || *commands=='m') {
150 cmdline_memory_size <<= 20;
151 commands++;
152 }
153 }
154 while (*commands && *commands != ' ')
155 commands++;
156 }
157}
158
159extern unsigned short root_flags;
160extern unsigned short root_dev;
161extern unsigned short ram_flags;
162#define RAMDISK_IMAGE_START_MASK 0x07FF
163#define RAMDISK_PROMPT_FLAG 0x8000
164#define RAMDISK_LOAD_FLAG 0x4000
165
166extern int root_mountflags;
167
168char reboot_command[COMMAND_LINE_SIZE];
169
170static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
171
172void __init per_cpu_patch(void)
173{
174 struct cpuid_patch_entry *p;
175 unsigned long ver;
176 int is_jbus;
177
178 if (tlb_type == spitfire && !this_is_starfire)
179 return;
180
181 is_jbus = 0;
182 if (tlb_type != hypervisor) {
183 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
184 is_jbus = ((ver >> 32UL) == __JALAPENO_ID ||
185 (ver >> 32UL) == __SERRANO_ID);
186 }
187
188 p = &__cpuid_patch;
189 while (p < &__cpuid_patch_end) {
190 unsigned long addr = p->addr;
191 unsigned int *insns;
192
193 switch (tlb_type) {
194 case spitfire:
195 insns = &p->starfire[0];
196 break;
197 case cheetah:
198 case cheetah_plus:
199 if (is_jbus)
200 insns = &p->cheetah_jbus[0];
201 else
202 insns = &p->cheetah_safari[0];
203 break;
204 case hypervisor:
205 insns = &p->sun4v[0];
206 break;
207 default:
208 prom_printf("Unknown cpu type, halting.\n");
209 prom_halt();
210 };
211
212 *(unsigned int *) (addr + 0) = insns[0];
213 wmb();
214 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
215
216 *(unsigned int *) (addr + 4) = insns[1];
217 wmb();
218 __asm__ __volatile__("flush %0" : : "r" (addr + 4));
219
220 *(unsigned int *) (addr + 8) = insns[2];
221 wmb();
222 __asm__ __volatile__("flush %0" : : "r" (addr + 8));
223
224 *(unsigned int *) (addr + 12) = insns[3];
225 wmb();
226 __asm__ __volatile__("flush %0" : : "r" (addr + 12));
227
228 p++;
229 }
230}
231
232void __init sun4v_patch(void)
233{
234 extern void sun4v_hvapi_init(void);
235 struct sun4v_1insn_patch_entry *p1;
236 struct sun4v_2insn_patch_entry *p2;
237
238 if (tlb_type != hypervisor)
239 return;
240
241 p1 = &__sun4v_1insn_patch;
242 while (p1 < &__sun4v_1insn_patch_end) {
243 unsigned long addr = p1->addr;
244
245 *(unsigned int *) (addr + 0) = p1->insn;
246 wmb();
247 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
248
249 p1++;
250 }
251
252 p2 = &__sun4v_2insn_patch;
253 while (p2 < &__sun4v_2insn_patch_end) {
254 unsigned long addr = p2->addr;
255
256 *(unsigned int *) (addr + 0) = p2->insns[0];
257 wmb();
258 __asm__ __volatile__("flush %0" : : "r" (addr + 0));
259
260 *(unsigned int *) (addr + 4) = p2->insns[1];
261 wmb();
262 __asm__ __volatile__("flush %0" : : "r" (addr + 4));
263
264 p2++;
265 }
266
267 sun4v_hvapi_init();
268}
269
270#ifdef CONFIG_SMP
271void __init boot_cpu_id_too_large(int cpu)
272{
273 prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n",
274 cpu, NR_CPUS);
275 prom_halt();
276}
277#endif
278
279void __init setup_arch(char **cmdline_p)
280{
281 /* Initialize PROM console and command line. */
282 *cmdline_p = prom_getbootargs();
283 strcpy(boot_command_line, *cmdline_p);
284 parse_early_param();
285
286 boot_flags_init(*cmdline_p);
287 register_console(&prom_early_console);
288
289 if (tlb_type == hypervisor)
290 printk("ARCH: SUN4V\n");
291 else
292 printk("ARCH: SUN4U\n");
293
294#ifdef CONFIG_DUMMY_CONSOLE
295 conswitchp = &dummy_con;
296#elif defined(CONFIG_PROM_CONSOLE)
297 conswitchp = &prom_con;
298#endif
299
300 idprom_init();
301
302 if (!root_flags)
303 root_mountflags &= ~MS_RDONLY;
304 ROOT_DEV = old_decode_dev(root_dev);
305#ifdef CONFIG_BLK_DEV_RAM
306 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
307 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0);
308 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);
309#endif
310
311 task_thread_info(&init_task)->kregs = &fake_swapper_regs;
312
313#ifdef CONFIG_IP_PNP
314 if (!ic_set_manually) {
315 int chosen = prom_finddevice ("/chosen");
316 u32 cl, sv, gw;
317
318 cl = prom_getintdefault (chosen, "client-ip", 0);
319 sv = prom_getintdefault (chosen, "server-ip", 0);
320 gw = prom_getintdefault (chosen, "gateway-ip", 0);
321 if (cl && sv) {
322 ic_myaddr = cl;
323 ic_servaddr = sv;
324 if (gw)
325 ic_gateway = gw;
326#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_RARP)
327 ic_proto_enabled = 0;
328#endif
329 }
330 }
331#endif
332
333 /* Get boot processor trap_block[] setup. */
334 init_cur_cpu_trap(current_thread_info());
335
336 paging_init();
337}
338
339/* BUFFER is PAGE_SIZE bytes long. */
340
341extern void smp_info(struct seq_file *);
342extern void smp_bogo(struct seq_file *);
343extern void mmu_info(struct seq_file *);
344
345unsigned int dcache_parity_tl1_occurred;
346unsigned int icache_parity_tl1_occurred;
347
348int ncpus_probed;
349
350static int show_cpuinfo(struct seq_file *m, void *__unused)
351{
352 seq_printf(m,
353 "cpu\t\t: %s\n"
354 "fpu\t\t: %s\n"
355 "prom\t\t: %s\n"
356 "type\t\t: %s\n"
357 "ncpus probed\t: %d\n"
358 "ncpus active\t: %d\n"
359 "D$ parity tl1\t: %u\n"
360 "I$ parity tl1\t: %u\n"
361#ifndef CONFIG_SMP
362 "Cpu0ClkTck\t: %016lx\n"
363#endif
364 ,
365 sparc_cpu_type,
366 sparc_fpu_type,
367 prom_version,
368 ((tlb_type == hypervisor) ?
369 "sun4v" :
370 "sun4u"),
371 ncpus_probed,
372 num_online_cpus(),
373 dcache_parity_tl1_occurred,
374 icache_parity_tl1_occurred
375#ifndef CONFIG_SMP
376 , cpu_data(0).clock_tick
377#endif
378 );
379#ifdef CONFIG_SMP
380 smp_bogo(m);
381#endif
382 mmu_info(m);
383#ifdef CONFIG_SMP
384 smp_info(m);
385#endif
386 return 0;
387}
388
389static void *c_start(struct seq_file *m, loff_t *pos)
390{
391 /* The pointer we are returning is arbitrary,
392 * it just has to be non-NULL and not IS_ERR
393 * in the success case.
394 */
395 return *pos == 0 ? &c_start : NULL;
396}
397
398static void *c_next(struct seq_file *m, void *v, loff_t *pos)
399{
400 ++*pos;
401 return c_start(m, pos);
402}
403
404static void c_stop(struct seq_file *m, void *v)
405{
406}
407
408const struct seq_operations cpuinfo_op = {
409 .start =c_start,
410 .next = c_next,
411 .stop = c_stop,
412 .show = show_cpuinfo,
413};
414
415extern int stop_a_enabled;
416
417void sun_do_break(void)
418{
419 if (!stop_a_enabled)
420 return;
421
422 prom_printf("\n");
423 flush_user_windows();
424
425 prom_cmdline();
426}
427
428int stop_a_enabled = 1;