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