xref: /openbmc/linux/arch/sparc/kernel/setup_32.c (revision 1279aa06)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2d670bd4fSSam Ravnborg /*
3d670bd4fSSam Ravnborg  *  linux/arch/sparc/kernel/setup.c
4d670bd4fSSam Ravnborg  *
5d670bd4fSSam Ravnborg  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
6d670bd4fSSam Ravnborg  *  Copyright (C) 2000  Anton Blanchard (anton@samba.org)
7d670bd4fSSam Ravnborg  */
8d670bd4fSSam Ravnborg 
9d670bd4fSSam Ravnborg #include <linux/errno.h>
10d670bd4fSSam Ravnborg #include <linux/sched.h>
11d670bd4fSSam Ravnborg #include <linux/kernel.h>
12d670bd4fSSam Ravnborg #include <linux/mm.h>
13d670bd4fSSam Ravnborg #include <linux/stddef.h>
14d670bd4fSSam Ravnborg #include <linux/unistd.h>
15d670bd4fSSam Ravnborg #include <linux/ptrace.h>
16d670bd4fSSam Ravnborg #include <linux/slab.h>
17d670bd4fSSam Ravnborg #include <linux/initrd.h>
18d670bd4fSSam Ravnborg #include <asm/smp.h>
19d670bd4fSSam Ravnborg #include <linux/user.h>
20d670bd4fSSam Ravnborg #include <linux/screen_info.h>
21d670bd4fSSam Ravnborg #include <linux/delay.h>
22d670bd4fSSam Ravnborg #include <linux/fs.h>
23d670bd4fSSam Ravnborg #include <linux/seq_file.h>
24d670bd4fSSam Ravnborg #include <linux/syscalls.h>
25d670bd4fSSam Ravnborg #include <linux/kdev_t.h>
26d670bd4fSSam Ravnborg #include <linux/major.h>
27d670bd4fSSam Ravnborg #include <linux/string.h>
28d670bd4fSSam Ravnborg #include <linux/init.h>
29d670bd4fSSam Ravnborg #include <linux/interrupt.h>
30d670bd4fSSam Ravnborg #include <linux/console.h>
31d670bd4fSSam Ravnborg #include <linux/spinlock.h>
32d670bd4fSSam Ravnborg #include <linux/root_dev.h>
33d670bd4fSSam Ravnborg #include <linux/cpu.h>
34d670bd4fSSam Ravnborg #include <linux/kdebug.h>
357b64db60SPaul Gortmaker #include <linux/export.h>
364efb55e6SSam Ravnborg #include <linux/start_kernel.h>
37e262e32dSDavid Howells #include <uapi/linux/mount.h>
38d670bd4fSSam Ravnborg 
39d670bd4fSSam Ravnborg #include <asm/io.h>
40d670bd4fSSam Ravnborg #include <asm/processor.h>
41d670bd4fSSam Ravnborg #include <asm/oplib.h>
42d670bd4fSSam Ravnborg #include <asm/page.h>
43d670bd4fSSam Ravnborg #include <asm/traps.h>
44d670bd4fSSam Ravnborg #include <asm/vaddrs.h>
45d670bd4fSSam Ravnborg #include <asm/mbus.h>
46d670bd4fSSam Ravnborg #include <asm/idprom.h>
47d670bd4fSSam Ravnborg #include <asm/cpudata.h>
48d670bd4fSSam Ravnborg #include <asm/setup.h>
49d550bbd4SDavid Howells #include <asm/cacheflush.h>
505b8b93c4SSam Ravnborg #include <asm/sections.h>
51d670bd4fSSam Ravnborg 
5253ae3419SSam Ravnborg #include "kernel.h"
5353ae3419SSam Ravnborg 
54d670bd4fSSam Ravnborg struct screen_info screen_info = {
55d670bd4fSSam Ravnborg 	0, 0,			/* orig-x, orig-y */
56d670bd4fSSam Ravnborg 	0,			/* unused */
57d670bd4fSSam Ravnborg 	0,			/* orig-video-page */
58d670bd4fSSam Ravnborg 	0,			/* orig-video-mode */
59d670bd4fSSam Ravnborg 	128,			/* orig-video-cols */
60d670bd4fSSam Ravnborg 	0,0,0,			/* ega_ax, ega_bx, ega_cx */
61d670bd4fSSam Ravnborg 	54,			/* orig-video-lines */
62d670bd4fSSam Ravnborg 	0,                      /* orig-video-isVGA */
63d670bd4fSSam Ravnborg 	16                      /* orig-video-points */
64d670bd4fSSam Ravnborg };
65d670bd4fSSam Ravnborg 
66d670bd4fSSam Ravnborg /* Typing sync at the prom prompt calls the function pointed to by
67d670bd4fSSam Ravnborg  * romvec->pv_synchook which I set to the following function.
68d670bd4fSSam Ravnborg  * This should sync all filesystems and return, for now it just
69d670bd4fSSam Ravnborg  * prints out pretty messages and returns.
70d670bd4fSSam Ravnborg  */
71d670bd4fSSam Ravnborg 
72d670bd4fSSam Ravnborg /* Pretty sick eh? */
prom_sync_me(void)73d670bd4fSSam Ravnborg static void prom_sync_me(void)
74d670bd4fSSam Ravnborg {
75d670bd4fSSam Ravnborg 	unsigned long prom_tbr, flags;
76d670bd4fSSam Ravnborg 
77d670bd4fSSam Ravnborg 	/* XXX Badly broken. FIX! - Anton */
78d670bd4fSSam Ravnborg 	local_irq_save(flags);
79d670bd4fSSam Ravnborg 	__asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr));
80d670bd4fSSam Ravnborg 	__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
81d670bd4fSSam Ravnborg 			     "nop\n\t"
82d670bd4fSSam Ravnborg 			     "nop\n\t"
83d670bd4fSSam Ravnborg 			     "nop\n\t" : : "r" (&trapbase));
84d670bd4fSSam Ravnborg 
85d670bd4fSSam Ravnborg 	prom_printf("PROM SYNC COMMAND...\n");
86*1279aa06SKefeng Wang 	show_mem();
8729f043a2SPaul E. McKenney 	if (!is_idle_task(current)) {
88d670bd4fSSam Ravnborg 		local_irq_enable();
8970f68ee8SDominik Brodowski 		ksys_sync();
90d670bd4fSSam Ravnborg 		local_irq_disable();
91d670bd4fSSam Ravnborg 	}
92d670bd4fSSam Ravnborg 	prom_printf("Returning to prom\n");
93d670bd4fSSam Ravnborg 
94d670bd4fSSam Ravnborg 	__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
95d670bd4fSSam Ravnborg 			     "nop\n\t"
96d670bd4fSSam Ravnborg 			     "nop\n\t"
97d670bd4fSSam Ravnborg 			     "nop\n\t" : : "r" (prom_tbr));
98d670bd4fSSam Ravnborg 	local_irq_restore(flags);
99d670bd4fSSam Ravnborg }
100d670bd4fSSam Ravnborg 
101d670bd4fSSam Ravnborg static unsigned int boot_flags __initdata = 0;
102d670bd4fSSam Ravnborg #define BOOTME_DEBUG  0x1
103d670bd4fSSam Ravnborg 
104d670bd4fSSam Ravnborg /* Exported for mm/init.c:paging_init. */
105d670bd4fSSam Ravnborg unsigned long cmdline_memory_size __initdata = 0;
106d670bd4fSSam Ravnborg 
1075fcafb7aSDaniel Hellstrom /* which CPU booted us (0xff = not set) */
1085fcafb7aSDaniel Hellstrom unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */
1095fcafb7aSDaniel Hellstrom 
110d670bd4fSSam Ravnborg static void
prom_console_write(struct console * con,const char * s,unsigned int n)1119ef595d8SJoe Perches prom_console_write(struct console *con, const char *s, unsigned int n)
112d670bd4fSSam Ravnborg {
113d670bd4fSSam Ravnborg 	prom_write(s, n);
114d670bd4fSSam Ravnborg }
115d670bd4fSSam Ravnborg 
1167671fa22SSam Ravnborg static struct console prom_early_console = {
1177671fa22SSam Ravnborg 	.name =		"earlyprom",
118d670bd4fSSam Ravnborg 	.write =	prom_console_write,
1197671fa22SSam Ravnborg 	.flags =	CON_PRINTBUFFER | CON_BOOT,
120d670bd4fSSam Ravnborg 	.index =	-1,
121d670bd4fSSam Ravnborg };
122d670bd4fSSam Ravnborg 
123d670bd4fSSam Ravnborg /*
124d670bd4fSSam Ravnborg  * Process kernel command line switches that are specific to the
125d670bd4fSSam Ravnborg  * SPARC or that require special low-level processing.
126d670bd4fSSam Ravnborg  */
process_switch(char c)127d670bd4fSSam Ravnborg static void __init process_switch(char c)
128d670bd4fSSam Ravnborg {
129d670bd4fSSam Ravnborg 	switch (c) {
130d670bd4fSSam Ravnborg 	case 'd':
131d670bd4fSSam Ravnborg 		boot_flags |= BOOTME_DEBUG;
132d670bd4fSSam Ravnborg 		break;
133d670bd4fSSam Ravnborg 	case 's':
134d670bd4fSSam Ravnborg 		break;
135d670bd4fSSam Ravnborg 	case 'h':
136d670bd4fSSam Ravnborg 		prom_printf("boot_flags_init: Halt!\n");
137d670bd4fSSam Ravnborg 		prom_halt();
138d670bd4fSSam Ravnborg 		break;
139d670bd4fSSam Ravnborg 	case 'p':
14011032c17SDavid S. Miller 		prom_early_console.flags &= ~CON_BOOT;
141d670bd4fSSam Ravnborg 		break;
142d670bd4fSSam Ravnborg 	default:
143d670bd4fSSam Ravnborg 		printk("Unknown boot switch (-%c)\n", c);
144d670bd4fSSam Ravnborg 		break;
145d670bd4fSSam Ravnborg 	}
146d670bd4fSSam Ravnborg }
147d670bd4fSSam Ravnborg 
boot_flags_init(char * commands)148d670bd4fSSam Ravnborg static void __init boot_flags_init(char *commands)
149d670bd4fSSam Ravnborg {
150d670bd4fSSam Ravnborg 	while (*commands) {
151d670bd4fSSam Ravnborg 		/* Move to the start of the next "argument". */
1528c64415cSDavid S. Miller 		while (*commands == ' ')
153d670bd4fSSam Ravnborg 			commands++;
154d670bd4fSSam Ravnborg 
155d670bd4fSSam Ravnborg 		/* Process any command switches, otherwise skip it. */
156d670bd4fSSam Ravnborg 		if (*commands == '\0')
157d670bd4fSSam Ravnborg 			break;
158d670bd4fSSam Ravnborg 		if (*commands == '-') {
159d670bd4fSSam Ravnborg 			commands++;
160d670bd4fSSam Ravnborg 			while (*commands && *commands != ' ')
161d670bd4fSSam Ravnborg 				process_switch(*commands++);
162d670bd4fSSam Ravnborg 			continue;
163d670bd4fSSam Ravnborg 		}
164d670bd4fSSam Ravnborg 		if (!strncmp(commands, "mem=", 4)) {
165d670bd4fSSam Ravnborg 			/*
166d670bd4fSSam Ravnborg 			 * "mem=XXX[kKmM] overrides the PROM-reported
167d670bd4fSSam Ravnborg 			 * memory size.
168d670bd4fSSam Ravnborg 			 */
169d670bd4fSSam Ravnborg 			cmdline_memory_size = simple_strtoul(commands + 4,
170d670bd4fSSam Ravnborg 						     &commands, 0);
171d670bd4fSSam Ravnborg 			if (*commands == 'K' || *commands == 'k') {
172d670bd4fSSam Ravnborg 				cmdline_memory_size <<= 10;
173d670bd4fSSam Ravnborg 				commands++;
174d670bd4fSSam Ravnborg 			} else if (*commands=='M' || *commands=='m') {
175d670bd4fSSam Ravnborg 				cmdline_memory_size <<= 20;
176d670bd4fSSam Ravnborg 				commands++;
177d670bd4fSSam Ravnborg 			}
178d670bd4fSSam Ravnborg 		}
179d670bd4fSSam Ravnborg 		while (*commands && *commands != ' ')
180d670bd4fSSam Ravnborg 			commands++;
181d670bd4fSSam Ravnborg 	}
182d670bd4fSSam Ravnborg }
183d670bd4fSSam Ravnborg 
184d670bd4fSSam Ravnborg extern unsigned short root_flags;
185d670bd4fSSam Ravnborg extern unsigned short root_dev;
186d670bd4fSSam Ravnborg extern unsigned short ram_flags;
187d670bd4fSSam Ravnborg #define RAMDISK_IMAGE_START_MASK	0x07FF
188d670bd4fSSam Ravnborg #define RAMDISK_PROMPT_FLAG		0x8000
189d670bd4fSSam Ravnborg #define RAMDISK_LOAD_FLAG		0x4000
190d670bd4fSSam Ravnborg 
191d670bd4fSSam Ravnborg extern int root_mountflags;
192d670bd4fSSam Ravnborg 
193d670bd4fSSam Ravnborg char reboot_command[COMMAND_LINE_SIZE];
1946943f3daSSam Ravnborg 
195c68e5d39SDavid S. Miller struct cpuid_patch_entry {
196c68e5d39SDavid S. Miller 	unsigned int	addr;
197c68e5d39SDavid S. Miller 	unsigned int	sun4d[3];
198c68e5d39SDavid S. Miller 	unsigned int	leon[3];
199c68e5d39SDavid S. Miller };
200c68e5d39SDavid S. Miller extern struct cpuid_patch_entry __cpuid_patch, __cpuid_patch_end;
201c68e5d39SDavid S. Miller 
per_cpu_patch(void)202c68e5d39SDavid S. Miller static void __init per_cpu_patch(void)
203c68e5d39SDavid S. Miller {
204c68e5d39SDavid S. Miller 	struct cpuid_patch_entry *p;
205c68e5d39SDavid S. Miller 
206c68e5d39SDavid S. Miller 	if (sparc_cpu_model == sun4m) {
207c68e5d39SDavid S. Miller 		/* Nothing to do, this is what the unpatched code
208c68e5d39SDavid S. Miller 		 * targets.
209c68e5d39SDavid S. Miller 		 */
210c68e5d39SDavid S. Miller 		return;
211c68e5d39SDavid S. Miller 	}
212c68e5d39SDavid S. Miller 
213c68e5d39SDavid S. Miller 	p = &__cpuid_patch;
214c68e5d39SDavid S. Miller 	while (p < &__cpuid_patch_end) {
215c68e5d39SDavid S. Miller 		unsigned long addr = p->addr;
216c68e5d39SDavid S. Miller 		unsigned int *insns;
217c68e5d39SDavid S. Miller 
218c68e5d39SDavid S. Miller 		switch (sparc_cpu_model) {
219c68e5d39SDavid S. Miller 		case sun4d:
220c68e5d39SDavid S. Miller 			insns = &p->sun4d[0];
221c68e5d39SDavid S. Miller 			break;
222c68e5d39SDavid S. Miller 
223c68e5d39SDavid S. Miller 		case sparc_leon:
224c68e5d39SDavid S. Miller 			insns = &p->leon[0];
225c68e5d39SDavid S. Miller 			break;
226c68e5d39SDavid S. Miller 		default:
227c68e5d39SDavid S. Miller 			prom_printf("Unknown cpu type, halting.\n");
228c68e5d39SDavid S. Miller 			prom_halt();
229c68e5d39SDavid S. Miller 		}
230c68e5d39SDavid S. Miller 		*(unsigned int *) (addr + 0) = insns[0];
2311edc1783SSam Ravnborg 		flushi(addr + 0);
232c68e5d39SDavid S. Miller 		*(unsigned int *) (addr + 4) = insns[1];
2331edc1783SSam Ravnborg 		flushi(addr + 4);
234c68e5d39SDavid S. Miller 		*(unsigned int *) (addr + 8) = insns[2];
2351edc1783SSam Ravnborg 		flushi(addr + 8);
2369cd5f822SSam Ravnborg 
2379cd5f822SSam Ravnborg 		p++;
238c68e5d39SDavid S. Miller 	}
239c68e5d39SDavid S. Miller }
240c68e5d39SDavid S. Miller 
2415b8b93c4SSam Ravnborg struct leon_1insn_patch_entry {
2425b8b93c4SSam Ravnborg 	unsigned int addr;
2435b8b93c4SSam Ravnborg 	unsigned int insn;
2445b8b93c4SSam Ravnborg };
2455b8b93c4SSam Ravnborg 
246d670bd4fSSam Ravnborg enum sparc_cpu sparc_cpu_model;
2476943f3daSSam Ravnborg EXPORT_SYMBOL(sparc_cpu_model);
248d670bd4fSSam Ravnborg 
leon_patch(void)2495b8b93c4SSam Ravnborg static __init void leon_patch(void)
2505b8b93c4SSam Ravnborg {
2515b8b93c4SSam Ravnborg 	struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
2525b8b93c4SSam Ravnborg 	struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
253d670bd4fSSam Ravnborg 
2545b8b93c4SSam Ravnborg 	/* Default instruction is leon - no patching */
2555b8b93c4SSam Ravnborg 	if (sparc_cpu_model == sparc_leon)
2565b8b93c4SSam Ravnborg 		return;
2575b8b93c4SSam Ravnborg 
2585b8b93c4SSam Ravnborg 	while (start < end) {
2595b8b93c4SSam Ravnborg 		unsigned long addr = start->addr;
2605b8b93c4SSam Ravnborg 
2615b8b93c4SSam Ravnborg 		*(unsigned int *)(addr) = start->insn;
2625b8b93c4SSam Ravnborg 		flushi(addr);
2635b8b93c4SSam Ravnborg 
2645b8b93c4SSam Ravnborg 		start++;
2655b8b93c4SSam Ravnborg 	}
2665b8b93c4SSam Ravnborg }
2675b8b93c4SSam Ravnborg 
2685b8b93c4SSam Ravnborg struct tt_entry *sparc_ttable;
269d670bd4fSSam Ravnborg 
2704efb55e6SSam Ravnborg /* Called from head_32.S - before we have setup anything
2714efb55e6SSam Ravnborg  * in the kernel. Be very careful with what you do here.
2724efb55e6SSam Ravnborg  */
sparc32_start_kernel(struct linux_romvec * rp)2734efb55e6SSam Ravnborg void __init sparc32_start_kernel(struct linux_romvec *rp)
2744efb55e6SSam Ravnborg {
2754efb55e6SSam Ravnborg 	prom_init(rp);
2765b8b93c4SSam Ravnborg 
2775b8b93c4SSam Ravnborg 	/* Set sparc_cpu_model */
2785b8b93c4SSam Ravnborg 	sparc_cpu_model = sun_unknown;
2795b8b93c4SSam Ravnborg 	if (!strcmp(&cputypval[0], "sun4m"))
2805b8b93c4SSam Ravnborg 		sparc_cpu_model = sun4m;
2815b8b93c4SSam Ravnborg 	if (!strcmp(&cputypval[0], "sun4s"))
2825b8b93c4SSam Ravnborg 		sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */
2835b8b93c4SSam Ravnborg 	if (!strcmp(&cputypval[0], "sun4d"))
2845b8b93c4SSam Ravnborg 		sparc_cpu_model = sun4d;
2855b8b93c4SSam Ravnborg 	if (!strcmp(&cputypval[0], "sun4e"))
2865b8b93c4SSam Ravnborg 		sparc_cpu_model = sun4e;
2875b8b93c4SSam Ravnborg 	if (!strcmp(&cputypval[0], "sun4u"))
2885b8b93c4SSam Ravnborg 		sparc_cpu_model = sun4u;
2895b8b93c4SSam Ravnborg 	if (!strncmp(&cputypval[0], "leon" , 4))
2905b8b93c4SSam Ravnborg 		sparc_cpu_model = sparc_leon;
2915b8b93c4SSam Ravnborg 
2925b8b93c4SSam Ravnborg 	leon_patch();
2934efb55e6SSam Ravnborg 	start_kernel();
2944efb55e6SSam Ravnborg }
2954efb55e6SSam Ravnborg 
setup_arch(char ** cmdline_p)296d670bd4fSSam Ravnborg void __init setup_arch(char **cmdline_p)
297d670bd4fSSam Ravnborg {
298d670bd4fSSam Ravnborg 	int i;
299d670bd4fSSam Ravnborg 	unsigned long highest_paddr;
300d670bd4fSSam Ravnborg 
3013c46e2d6SSam Ravnborg 	sparc_ttable = &trapbase;
302d670bd4fSSam Ravnborg 
303d670bd4fSSam Ravnborg 	/* Initialize PROM console and command line. */
304d670bd4fSSam Ravnborg 	*cmdline_p = prom_getbootargs();
305bb07972fSAzeem Shaikh 	strscpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
306d670bd4fSSam Ravnborg 	parse_early_param();
307d670bd4fSSam Ravnborg 
3087671fa22SSam Ravnborg 	boot_flags_init(*cmdline_p);
3097671fa22SSam Ravnborg 
3107671fa22SSam Ravnborg 	register_console(&prom_early_console);
3117671fa22SSam Ravnborg 
312d670bd4fSSam Ravnborg 	switch(sparc_cpu_model) {
313d670bd4fSSam Ravnborg 	case sun4m:
314afaffac3SCorentin Labbe 		pr_info("ARCH: SUN4M\n");
315d670bd4fSSam Ravnborg 		break;
316d670bd4fSSam Ravnborg 	case sun4d:
317afaffac3SCorentin Labbe 		pr_info("ARCH: SUN4D\n");
318d670bd4fSSam Ravnborg 		break;
319d670bd4fSSam Ravnborg 	case sun4e:
320afaffac3SCorentin Labbe 		pr_info("ARCH: SUN4E\n");
321d670bd4fSSam Ravnborg 		break;
322d670bd4fSSam Ravnborg 	case sun4u:
323afaffac3SCorentin Labbe 		pr_info("ARCH: SUN4U\n");
324d670bd4fSSam Ravnborg 		break;
3250fd7ef1fSKonrad Eisele 	case sparc_leon:
326afaffac3SCorentin Labbe 		pr_info("ARCH: LEON\n");
3270fd7ef1fSKonrad Eisele 		break;
328d670bd4fSSam Ravnborg 	default:
329afaffac3SCorentin Labbe 		pr_info("ARCH: UNKNOWN!\n");
330d670bd4fSSam Ravnborg 		break;
3316cb79b3fSJoe Perches 	}
332d670bd4fSSam Ravnborg 
333d670bd4fSSam Ravnborg 	idprom_init();
334d670bd4fSSam Ravnborg 	load_mmu();
335d670bd4fSSam Ravnborg 
336d670bd4fSSam Ravnborg 	phys_base = 0xffffffffUL;
337d670bd4fSSam Ravnborg 	highest_paddr = 0UL;
338d670bd4fSSam Ravnborg 	for (i = 0; sp_banks[i].num_bytes != 0; i++) {
339d670bd4fSSam Ravnborg 		unsigned long top;
340d670bd4fSSam Ravnborg 
341d670bd4fSSam Ravnborg 		if (sp_banks[i].base_addr < phys_base)
342d670bd4fSSam Ravnborg 			phys_base = sp_banks[i].base_addr;
343d670bd4fSSam Ravnborg 		top = sp_banks[i].base_addr +
344d670bd4fSSam Ravnborg 			sp_banks[i].num_bytes;
345d670bd4fSSam Ravnborg 		if (highest_paddr < top)
346d670bd4fSSam Ravnborg 			highest_paddr = top;
347d670bd4fSSam Ravnborg 	}
348d670bd4fSSam Ravnborg 	pfn_base = phys_base >> PAGE_SHIFT;
349d670bd4fSSam Ravnborg 
350d670bd4fSSam Ravnborg 	if (!root_flags)
351d670bd4fSSam Ravnborg 		root_mountflags &= ~MS_RDONLY;
352d670bd4fSSam Ravnborg 	ROOT_DEV = old_decode_dev(root_dev);
353d670bd4fSSam Ravnborg #ifdef CONFIG_BLK_DEV_RAM
354d670bd4fSSam Ravnborg 	rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK;
355d670bd4fSSam Ravnborg #endif
356d670bd4fSSam Ravnborg 
357d670bd4fSSam Ravnborg 	prom_setsync(prom_sync_me);
358d670bd4fSSam Ravnborg 
359d191723fSSam Ravnborg 	if((boot_flags & BOOTME_DEBUG) && (linux_dbvec != NULL) &&
360d670bd4fSSam Ravnborg 	   ((*(short *)linux_dbvec) != -1)) {
361d670bd4fSSam Ravnborg 		printk("Booted under KADB. Syncing trap table.\n");
362d670bd4fSSam Ravnborg 		(*(linux_dbvec->teach_debugger))();
363d670bd4fSSam Ravnborg 	}
364d670bd4fSSam Ravnborg 
3651edc1783SSam Ravnborg 	/* Run-time patch instructions to match the cpu model */
366c68e5d39SDavid S. Miller 	per_cpu_patch();
367c68e5d39SDavid S. Miller 
3681edc1783SSam Ravnborg 	paging_init();
3691edc1783SSam Ravnborg 
370d670bd4fSSam Ravnborg 	smp_setup_cpu_possible_map();
371d670bd4fSSam Ravnborg }
372d670bd4fSSam Ravnborg 
373d670bd4fSSam Ravnborg extern int stop_a_enabled;
374d670bd4fSSam Ravnborg 
sun_do_break(void)375d670bd4fSSam Ravnborg void sun_do_break(void)
376d670bd4fSSam Ravnborg {
377d670bd4fSSam Ravnborg 	if (!stop_a_enabled)
378d670bd4fSSam Ravnborg 		return;
379d670bd4fSSam Ravnborg 
380d670bd4fSSam Ravnborg 	printk("\n");
381d670bd4fSSam Ravnborg 	flush_user_windows();
382d670bd4fSSam Ravnborg 
383d670bd4fSSam Ravnborg 	prom_cmdline();
384d670bd4fSSam Ravnborg }
3856943f3daSSam Ravnborg EXPORT_SYMBOL(sun_do_break);
386d670bd4fSSam Ravnborg 
387d670bd4fSSam Ravnborg int stop_a_enabled = 1;
388d670bd4fSSam Ravnborg 
topology_init(void)389d670bd4fSSam Ravnborg static int __init topology_init(void)
390d670bd4fSSam Ravnborg {
391d670bd4fSSam Ravnborg 	int i, ncpus, err;
392d670bd4fSSam Ravnborg 
393d670bd4fSSam Ravnborg 	/* Count the number of physically present processors in
394d670bd4fSSam Ravnborg 	 * the machine, even on uniprocessor, so that /proc/cpuinfo
395d670bd4fSSam Ravnborg 	 * output is consistent with 2.4.x
396d670bd4fSSam Ravnborg 	 */
397d670bd4fSSam Ravnborg 	ncpus = 0;
398d670bd4fSSam Ravnborg 	while (!cpu_find_by_instance(ncpus, NULL, NULL))
399d670bd4fSSam Ravnborg 		ncpus++;
400d670bd4fSSam Ravnborg 	ncpus_probed = ncpus;
401d670bd4fSSam Ravnborg 
402d670bd4fSSam Ravnborg 	err = 0;
403d670bd4fSSam Ravnborg 	for_each_online_cpu(i) {
404d670bd4fSSam Ravnborg 		struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
405d670bd4fSSam Ravnborg 		if (!p)
406d670bd4fSSam Ravnborg 			err = -ENOMEM;
407d670bd4fSSam Ravnborg 		else
408d670bd4fSSam Ravnborg 			register_cpu(p, i);
409d670bd4fSSam Ravnborg 	}
410d670bd4fSSam Ravnborg 
411d670bd4fSSam Ravnborg 	return err;
412d670bd4fSSam Ravnborg }
413d670bd4fSSam Ravnborg 
414d670bd4fSSam Ravnborg subsys_initcall(topology_init);
41544ade508SThomas Gleixner 
41644ade508SThomas Gleixner #if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
arch_cpu_finalize_init(void)41744ade508SThomas Gleixner void __init arch_cpu_finalize_init(void)
41844ade508SThomas Gleixner {
41944ade508SThomas Gleixner 	cpu_data(0).udelay_val = loops_per_jiffy;
42044ade508SThomas Gleixner }
42144ade508SThomas Gleixner #endif
422