xref: /openbmc/linux/arch/sparc/kernel/smp_32.c (revision 4c8c3c7f)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
2d670bd4fSSam Ravnborg /* smp.c: Sparc SMP support.
3d670bd4fSSam Ravnborg  *
4d670bd4fSSam Ravnborg  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5d670bd4fSSam Ravnborg  * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6d670bd4fSSam Ravnborg  * Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org)
7d670bd4fSSam Ravnborg  */
8d670bd4fSSam Ravnborg 
9d670bd4fSSam Ravnborg #include <asm/head.h>
10d670bd4fSSam Ravnborg 
11d670bd4fSSam Ravnborg #include <linux/kernel.h>
12d670bd4fSSam Ravnborg #include <linux/sched.h>
13d670bd4fSSam Ravnborg #include <linux/threads.h>
14d670bd4fSSam Ravnborg #include <linux/smp.h>
15d670bd4fSSam Ravnborg #include <linux/interrupt.h>
16d670bd4fSSam Ravnborg #include <linux/kernel_stat.h>
17d670bd4fSSam Ravnborg #include <linux/init.h>
18d670bd4fSSam Ravnborg #include <linux/spinlock.h>
19d670bd4fSSam Ravnborg #include <linux/mm.h>
20d670bd4fSSam Ravnborg #include <linux/fs.h>
21d670bd4fSSam Ravnborg #include <linux/seq_file.h>
22d670bd4fSSam Ravnborg #include <linux/cache.h>
23d670bd4fSSam Ravnborg #include <linux/delay.h>
24d3091298SSam Ravnborg #include <linux/profile.h>
25f9fd3488SSam Ravnborg #include <linux/cpu.h>
26d670bd4fSSam Ravnborg 
27d670bd4fSSam Ravnborg #include <asm/ptrace.h>
2860063497SArun Sharma #include <linux/atomic.h>
29d670bd4fSSam Ravnborg 
30d670bd4fSSam Ravnborg #include <asm/irq.h>
31d670bd4fSSam Ravnborg #include <asm/page.h>
32d670bd4fSSam Ravnborg #include <asm/oplib.h>
33d670bd4fSSam Ravnborg #include <asm/cacheflush.h>
34d670bd4fSSam Ravnborg #include <asm/tlbflush.h>
35d670bd4fSSam Ravnborg #include <asm/cpudata.h>
36f9fd3488SSam Ravnborg #include <asm/timer.h>
378401707fSKonrad Eisele #include <asm/leon.h>
38d670bd4fSSam Ravnborg 
39f9fd3488SSam Ravnborg #include "kernel.h"
40d670bd4fSSam Ravnborg #include "irq.h"
41d670bd4fSSam Ravnborg 
422066aaddSPaul Gortmaker volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
43d670bd4fSSam Ravnborg 
44d670bd4fSSam Ravnborg cpumask_t smp_commenced_mask = CPU_MASK_NONE;
45d670bd4fSSam Ravnborg 
464ba22b16SSam Ravnborg const struct sparc32_ipi_ops *sparc32_ipi_ops;
474ba22b16SSam Ravnborg 
48d670bd4fSSam Ravnborg /* The only guaranteed locking primitive available on all Sparc
49d670bd4fSSam Ravnborg  * processors is 'ldstub [%reg + immediate], %dest_reg' which atomically
50d670bd4fSSam Ravnborg  * places the current byte at the effective address into dest_reg and
51d670bd4fSSam Ravnborg  * places 0xff there afterwards.  Pretty lame locking primitive
52d670bd4fSSam Ravnborg  * compared to the Alpha and the Intel no?  Most Sparcs have 'swap'
53d670bd4fSSam Ravnborg  * instruction which is much better...
54d670bd4fSSam Ravnborg  */
55d670bd4fSSam Ravnborg 
smp_store_cpu_info(int id)562066aaddSPaul Gortmaker void smp_store_cpu_info(int id)
57d670bd4fSSam Ravnborg {
58d670bd4fSSam Ravnborg 	int cpu_node;
59f486b3dcSSam Ravnborg 	int mid;
60d670bd4fSSam Ravnborg 
61d670bd4fSSam Ravnborg 	cpu_data(id).udelay_val = loops_per_jiffy;
62d670bd4fSSam Ravnborg 
63d670bd4fSSam Ravnborg 	cpu_find_by_mid(id, &cpu_node);
64d670bd4fSSam Ravnborg 	cpu_data(id).clock_tick = prom_getintdefault(cpu_node,
65d670bd4fSSam Ravnborg 						     "clock-frequency", 0);
66d670bd4fSSam Ravnborg 	cpu_data(id).prom_node = cpu_node;
67f486b3dcSSam Ravnborg 	mid = cpu_get_hwmid(cpu_node);
68d670bd4fSSam Ravnborg 
69f486b3dcSSam Ravnborg 	if (mid < 0) {
70551d57ffSHans Wennborg 		printk(KERN_NOTICE "No MID found for CPU%d at node 0x%08x", id, cpu_node);
71f486b3dcSSam Ravnborg 		mid = 0;
72f486b3dcSSam Ravnborg 	}
73f486b3dcSSam Ravnborg 	cpu_data(id).mid = mid;
74d670bd4fSSam Ravnborg }
75d670bd4fSSam Ravnborg 
smp_cpus_done(unsigned int max_cpus)76d670bd4fSSam Ravnborg void __init smp_cpus_done(unsigned int max_cpus)
77d670bd4fSSam Ravnborg {
78d670bd4fSSam Ravnborg 	unsigned long bogosum = 0;
79ec7c14bdSRusty Russell 	int cpu, num = 0;
80d670bd4fSSam Ravnborg 
81ec7c14bdSRusty Russell 	for_each_online_cpu(cpu) {
82d670bd4fSSam Ravnborg 		num++;
83d670bd4fSSam Ravnborg 		bogosum += cpu_data(cpu).udelay_val;
84d670bd4fSSam Ravnborg 	}
85d670bd4fSSam Ravnborg 
86d670bd4fSSam Ravnborg 	printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
87d670bd4fSSam Ravnborg 		num, bogosum/(500000/HZ),
88d670bd4fSSam Ravnborg 		(bogosum/(5000/HZ))%100);
89d670bd4fSSam Ravnborg 
90d670bd4fSSam Ravnborg 	switch(sparc_cpu_model) {
91d670bd4fSSam Ravnborg 	case sun4m:
92d670bd4fSSam Ravnborg 		smp4m_smp_done();
93d670bd4fSSam Ravnborg 		break;
94d670bd4fSSam Ravnborg 	case sun4d:
95d670bd4fSSam Ravnborg 		smp4d_smp_done();
96d670bd4fSSam Ravnborg 		break;
978401707fSKonrad Eisele 	case sparc_leon:
988401707fSKonrad Eisele 		leon_smp_done();
998401707fSKonrad Eisele 		break;
100d670bd4fSSam Ravnborg 	case sun4e:
101d670bd4fSSam Ravnborg 		printk("SUN4E\n");
102d670bd4fSSam Ravnborg 		BUG();
103d670bd4fSSam Ravnborg 		break;
104d670bd4fSSam Ravnborg 	case sun4u:
105d670bd4fSSam Ravnborg 		printk("SUN4U\n");
106d670bd4fSSam Ravnborg 		BUG();
107d670bd4fSSam Ravnborg 		break;
108d670bd4fSSam Ravnborg 	default:
109d670bd4fSSam Ravnborg 		printk("UNKNOWN!\n");
110d670bd4fSSam Ravnborg 		BUG();
111d670bd4fSSam Ravnborg 		break;
1126cb79b3fSJoe Perches 	}
113d670bd4fSSam Ravnborg }
114d670bd4fSSam Ravnborg 
cpu_panic(void)115d670bd4fSSam Ravnborg void cpu_panic(void)
116d670bd4fSSam Ravnborg {
117d670bd4fSSam Ravnborg 	printk("CPU[%d]: Returns from cpu_idle!\n", smp_processor_id());
118d670bd4fSSam Ravnborg 	panic("SMP bolixed\n");
119d670bd4fSSam Ravnborg }
120d670bd4fSSam Ravnborg 
1212066aaddSPaul Gortmaker struct linux_prom_registers smp_penguin_ctable = { 0 };
122d670bd4fSSam Ravnborg 
arch_smp_send_reschedule(int cpu)123*4c8c3c7fSValentin Schneider void arch_smp_send_reschedule(int cpu)
124d670bd4fSSam Ravnborg {
125d6d04819SDaniel Hellstrom 	/*
126d6d04819SDaniel Hellstrom 	 * CPU model dependent way of implementing IPI generation targeting
127d6d04819SDaniel Hellstrom 	 * a single CPU. The trap handler needs only to do trap entry/return
128d6d04819SDaniel Hellstrom 	 * to call schedule.
129d6d04819SDaniel Hellstrom 	 */
1304ba22b16SSam Ravnborg 	sparc32_ipi_ops->resched(cpu);
131d670bd4fSSam Ravnborg }
132d670bd4fSSam Ravnborg 
smp_send_stop(void)133d670bd4fSSam Ravnborg void smp_send_stop(void)
134d670bd4fSSam Ravnborg {
135d670bd4fSSam Ravnborg }
136d670bd4fSSam Ravnborg 
arch_send_call_function_single_ipi(int cpu)137d6d04819SDaniel Hellstrom void arch_send_call_function_single_ipi(int cpu)
138d6d04819SDaniel Hellstrom {
139d6d04819SDaniel Hellstrom 	/* trigger one IPI single call on one CPU */
1404ba22b16SSam Ravnborg 	sparc32_ipi_ops->single(cpu);
141d6d04819SDaniel Hellstrom }
142d6d04819SDaniel Hellstrom 
arch_send_call_function_ipi_mask(const struct cpumask * mask)143d6d04819SDaniel Hellstrom void arch_send_call_function_ipi_mask(const struct cpumask *mask)
144d6d04819SDaniel Hellstrom {
145d6d04819SDaniel Hellstrom 	int cpu;
146d6d04819SDaniel Hellstrom 
147d6d04819SDaniel Hellstrom 	/* trigger IPI mask call on each CPU */
148d6d04819SDaniel Hellstrom 	for_each_cpu(cpu, mask)
1494ba22b16SSam Ravnborg 		sparc32_ipi_ops->mask_one(cpu);
150d6d04819SDaniel Hellstrom }
151d6d04819SDaniel Hellstrom 
smp_resched_interrupt(void)152d6d04819SDaniel Hellstrom void smp_resched_interrupt(void)
153d6d04819SDaniel Hellstrom {
15490d3ac15SDavid S. Miller 	irq_enter();
15590d3ac15SDavid S. Miller 	scheduler_ipi();
156d6d04819SDaniel Hellstrom 	local_cpu_data().irq_resched_count++;
15790d3ac15SDavid S. Miller 	irq_exit();
15890d3ac15SDavid S. Miller 	/* re-schedule routine called by interrupt return code. */
159d6d04819SDaniel Hellstrom }
160d6d04819SDaniel Hellstrom 
smp_call_function_single_interrupt(void)161d6d04819SDaniel Hellstrom void smp_call_function_single_interrupt(void)
162d6d04819SDaniel Hellstrom {
163d6d04819SDaniel Hellstrom 	irq_enter();
164d6d04819SDaniel Hellstrom 	generic_smp_call_function_single_interrupt();
165d6d04819SDaniel Hellstrom 	local_cpu_data().irq_call_count++;
166d6d04819SDaniel Hellstrom 	irq_exit();
167d6d04819SDaniel Hellstrom }
168d6d04819SDaniel Hellstrom 
smp_call_function_interrupt(void)169d6d04819SDaniel Hellstrom void smp_call_function_interrupt(void)
170d6d04819SDaniel Hellstrom {
171d6d04819SDaniel Hellstrom 	irq_enter();
172d6d04819SDaniel Hellstrom 	generic_smp_call_function_interrupt();
173d6d04819SDaniel Hellstrom 	local_cpu_data().irq_call_count++;
174d6d04819SDaniel Hellstrom 	irq_exit();
175d6d04819SDaniel Hellstrom }
176d6d04819SDaniel Hellstrom 
smp_prepare_cpus(unsigned int max_cpus)177d670bd4fSSam Ravnborg void __init smp_prepare_cpus(unsigned int max_cpus)
178d670bd4fSSam Ravnborg {
179d670bd4fSSam Ravnborg 	int i, cpuid, extra;
180d670bd4fSSam Ravnborg 
181d670bd4fSSam Ravnborg 	printk("Entering SMP Mode...\n");
182d670bd4fSSam Ravnborg 
183d670bd4fSSam Ravnborg 	extra = 0;
184d670bd4fSSam Ravnborg 	for (i = 0; !cpu_find_by_instance(i, NULL, &cpuid); i++) {
185d670bd4fSSam Ravnborg 		if (cpuid >= NR_CPUS)
186d670bd4fSSam Ravnborg 			extra++;
187d670bd4fSSam Ravnborg 	}
188d670bd4fSSam Ravnborg 	/* i = number of cpus */
189d670bd4fSSam Ravnborg 	if (extra && max_cpus > i - extra)
190d670bd4fSSam Ravnborg 		printk("Warning: NR_CPUS is too low to start all cpus\n");
191d670bd4fSSam Ravnborg 
192d670bd4fSSam Ravnborg 	smp_store_cpu_info(boot_cpu_id);
193d670bd4fSSam Ravnborg 
194d670bd4fSSam Ravnborg 	switch(sparc_cpu_model) {
195d670bd4fSSam Ravnborg 	case sun4m:
196d670bd4fSSam Ravnborg 		smp4m_boot_cpus();
197d670bd4fSSam Ravnborg 		break;
198d670bd4fSSam Ravnborg 	case sun4d:
199d670bd4fSSam Ravnborg 		smp4d_boot_cpus();
200d670bd4fSSam Ravnborg 		break;
2018401707fSKonrad Eisele 	case sparc_leon:
2028401707fSKonrad Eisele 		leon_boot_cpus();
2038401707fSKonrad Eisele 		break;
204d670bd4fSSam Ravnborg 	case sun4e:
205d670bd4fSSam Ravnborg 		printk("SUN4E\n");
206d670bd4fSSam Ravnborg 		BUG();
207d670bd4fSSam Ravnborg 		break;
208d670bd4fSSam Ravnborg 	case sun4u:
209d670bd4fSSam Ravnborg 		printk("SUN4U\n");
210d670bd4fSSam Ravnborg 		BUG();
211d670bd4fSSam Ravnborg 		break;
212d670bd4fSSam Ravnborg 	default:
213d670bd4fSSam Ravnborg 		printk("UNKNOWN!\n");
214d670bd4fSSam Ravnborg 		BUG();
215d670bd4fSSam Ravnborg 		break;
2166cb79b3fSJoe Perches 	}
217d670bd4fSSam Ravnborg }
218d670bd4fSSam Ravnborg 
219d670bd4fSSam Ravnborg /* Set this up early so that things like the scheduler can init
220d670bd4fSSam Ravnborg  * properly.  We use the same cpu mask for both the present and
221d670bd4fSSam Ravnborg  * possible cpu map.
222d670bd4fSSam Ravnborg  */
smp_setup_cpu_possible_map(void)223d670bd4fSSam Ravnborg void __init smp_setup_cpu_possible_map(void)
224d670bd4fSSam Ravnborg {
225d670bd4fSSam Ravnborg 	int instance, mid;
226d670bd4fSSam Ravnborg 
227d670bd4fSSam Ravnborg 	instance = 0;
228d670bd4fSSam Ravnborg 	while (!cpu_find_by_instance(instance, NULL, &mid)) {
229d670bd4fSSam Ravnborg 		if (mid < NR_CPUS) {
230fe73971cSRusty Russell 			set_cpu_possible(mid, true);
231fe73971cSRusty Russell 			set_cpu_present(mid, true);
232d670bd4fSSam Ravnborg 		}
233d670bd4fSSam Ravnborg 		instance++;
234d670bd4fSSam Ravnborg 	}
235d670bd4fSSam Ravnborg }
236d670bd4fSSam Ravnborg 
smp_prepare_boot_cpu(void)237d670bd4fSSam Ravnborg void __init smp_prepare_boot_cpu(void)
238d670bd4fSSam Ravnborg {
239d670bd4fSSam Ravnborg 	int cpuid = hard_smp_processor_id();
240d670bd4fSSam Ravnborg 
241d670bd4fSSam Ravnborg 	if (cpuid >= NR_CPUS) {
242d670bd4fSSam Ravnborg 		prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
243d670bd4fSSam Ravnborg 		prom_halt();
244d670bd4fSSam Ravnborg 	}
245d670bd4fSSam Ravnborg 	if (cpuid != 0)
246d670bd4fSSam Ravnborg 		printk("boot cpu id != 0, this could work but is untested\n");
247d670bd4fSSam Ravnborg 
248d670bd4fSSam Ravnborg 	current_thread_info()->cpu = cpuid;
249fe73971cSRusty Russell 	set_cpu_online(cpuid, true);
250fe73971cSRusty Russell 	set_cpu_possible(cpuid, true);
251d670bd4fSSam Ravnborg }
252d670bd4fSSam Ravnborg 
__cpu_up(unsigned int cpu,struct task_struct * tidle)2532066aaddSPaul Gortmaker int __cpu_up(unsigned int cpu, struct task_struct *tidle)
254d670bd4fSSam Ravnborg {
255d670bd4fSSam Ravnborg 	int ret=0;
256d670bd4fSSam Ravnborg 
257d670bd4fSSam Ravnborg 	switch(sparc_cpu_model) {
258d670bd4fSSam Ravnborg 	case sun4m:
259f0a2bc7eSThomas Gleixner 		ret = smp4m_boot_one_cpu(cpu, tidle);
260d670bd4fSSam Ravnborg 		break;
261d670bd4fSSam Ravnborg 	case sun4d:
262f0a2bc7eSThomas Gleixner 		ret = smp4d_boot_one_cpu(cpu, tidle);
263d670bd4fSSam Ravnborg 		break;
2648401707fSKonrad Eisele 	case sparc_leon:
265f0a2bc7eSThomas Gleixner 		ret = leon_boot_one_cpu(cpu, tidle);
2668401707fSKonrad Eisele 		break;
267d670bd4fSSam Ravnborg 	case sun4e:
268d670bd4fSSam Ravnborg 		printk("SUN4E\n");
269d670bd4fSSam Ravnborg 		BUG();
270d670bd4fSSam Ravnborg 		break;
271d670bd4fSSam Ravnborg 	case sun4u:
272d670bd4fSSam Ravnborg 		printk("SUN4U\n");
273d670bd4fSSam Ravnborg 		BUG();
274d670bd4fSSam Ravnborg 		break;
275d670bd4fSSam Ravnborg 	default:
276d670bd4fSSam Ravnborg 		printk("UNKNOWN!\n");
277d670bd4fSSam Ravnborg 		BUG();
278d670bd4fSSam Ravnborg 		break;
2796cb79b3fSJoe Perches 	}
280d670bd4fSSam Ravnborg 
281d670bd4fSSam Ravnborg 	if (!ret) {
282fb1fece5SKOSAKI Motohiro 		cpumask_set_cpu(cpu, &smp_commenced_mask);
283d670bd4fSSam Ravnborg 		while (!cpu_online(cpu))
284d670bd4fSSam Ravnborg 			mb();
285d670bd4fSSam Ravnborg 	}
286d670bd4fSSam Ravnborg 	return ret;
287d670bd4fSSam Ravnborg }
288d670bd4fSSam Ravnborg 
arch_cpu_pre_starting(void * arg)289c0b0ba84SSam Ravnborg static void arch_cpu_pre_starting(void *arg)
290f9fd3488SSam Ravnborg {
291f9fd3488SSam Ravnborg 	local_ops->cache_all();
292f9fd3488SSam Ravnborg 	local_ops->tlb_all();
293f9fd3488SSam Ravnborg 
294f9fd3488SSam Ravnborg 	switch(sparc_cpu_model) {
295f9fd3488SSam Ravnborg 	case sun4m:
296f9fd3488SSam Ravnborg 		sun4m_cpu_pre_starting(arg);
297f9fd3488SSam Ravnborg 		break;
298f9fd3488SSam Ravnborg 	case sun4d:
299f9fd3488SSam Ravnborg 		sun4d_cpu_pre_starting(arg);
300f9fd3488SSam Ravnborg 		break;
301f9fd3488SSam Ravnborg 	case sparc_leon:
302f9fd3488SSam Ravnborg 		leon_cpu_pre_starting(arg);
303f9fd3488SSam Ravnborg 		break;
304f9fd3488SSam Ravnborg 	default:
305f9fd3488SSam Ravnborg 		BUG();
306f9fd3488SSam Ravnborg 	}
307f9fd3488SSam Ravnborg }
308f9fd3488SSam Ravnborg 
arch_cpu_pre_online(void * arg)309c0b0ba84SSam Ravnborg static void arch_cpu_pre_online(void *arg)
310f9fd3488SSam Ravnborg {
311f9fd3488SSam Ravnborg 	unsigned int cpuid = hard_smp_processor_id();
312f9fd3488SSam Ravnborg 
313f9fd3488SSam Ravnborg 	register_percpu_ce(cpuid);
314f9fd3488SSam Ravnborg 
315f9fd3488SSam Ravnborg 	calibrate_delay();
316f9fd3488SSam Ravnborg 	smp_store_cpu_info(cpuid);
317f9fd3488SSam Ravnborg 
318f9fd3488SSam Ravnborg 	local_ops->cache_all();
319f9fd3488SSam Ravnborg 	local_ops->tlb_all();
320f9fd3488SSam Ravnborg 
321f9fd3488SSam Ravnborg 	switch(sparc_cpu_model) {
322f9fd3488SSam Ravnborg 	case sun4m:
323f9fd3488SSam Ravnborg 		sun4m_cpu_pre_online(arg);
324f9fd3488SSam Ravnborg 		break;
325f9fd3488SSam Ravnborg 	case sun4d:
326f9fd3488SSam Ravnborg 		sun4d_cpu_pre_online(arg);
327f9fd3488SSam Ravnborg 		break;
328f9fd3488SSam Ravnborg 	case sparc_leon:
329f9fd3488SSam Ravnborg 		leon_cpu_pre_online(arg);
330f9fd3488SSam Ravnborg 		break;
331f9fd3488SSam Ravnborg 	default:
332f9fd3488SSam Ravnborg 		BUG();
333f9fd3488SSam Ravnborg 	}
334f9fd3488SSam Ravnborg }
335f9fd3488SSam Ravnborg 
sparc_start_secondary(void * arg)336c0b0ba84SSam Ravnborg static void sparc_start_secondary(void *arg)
337f9fd3488SSam Ravnborg {
338f9fd3488SSam Ravnborg 	unsigned int cpu;
339f9fd3488SSam Ravnborg 
340f9fd3488SSam Ravnborg 	/*
341f9fd3488SSam Ravnborg 	 * SMP booting is extremely fragile in some architectures. So run
342f9fd3488SSam Ravnborg 	 * the cpu initialization code first before anything else.
343f9fd3488SSam Ravnborg 	 */
344f9fd3488SSam Ravnborg 	arch_cpu_pre_starting(arg);
345f9fd3488SSam Ravnborg 
346f9fd3488SSam Ravnborg 	cpu = smp_processor_id();
347f9fd3488SSam Ravnborg 
348f9fd3488SSam Ravnborg 	notify_cpu_starting(cpu);
349f9fd3488SSam Ravnborg 	arch_cpu_pre_online(arg);
350f9fd3488SSam Ravnborg 
351f9fd3488SSam Ravnborg 	/* Set the CPU in the cpu_online_mask */
352f9fd3488SSam Ravnborg 	set_cpu_online(cpu, true);
353f9fd3488SSam Ravnborg 
354f9fd3488SSam Ravnborg 	/* Enable local interrupts now */
355f9fd3488SSam Ravnborg 	local_irq_enable();
356f9fd3488SSam Ravnborg 
357f9fd3488SSam Ravnborg 	wmb();
358fc6d73d6SThomas Gleixner 	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
359f9fd3488SSam Ravnborg 
360f9fd3488SSam Ravnborg 	/* We should never reach here! */
361f9fd3488SSam Ravnborg 	BUG();
362f9fd3488SSam Ravnborg }
363f9fd3488SSam Ravnborg 
smp_callin(void)3642066aaddSPaul Gortmaker void smp_callin(void)
365f9fd3488SSam Ravnborg {
366f9fd3488SSam Ravnborg 	sparc_start_secondary(NULL);
367f9fd3488SSam Ravnborg }
368f9fd3488SSam Ravnborg 
smp_bogo(struct seq_file * m)369d670bd4fSSam Ravnborg void smp_bogo(struct seq_file *m)
370d670bd4fSSam Ravnborg {
371d670bd4fSSam Ravnborg 	int i;
372d670bd4fSSam Ravnborg 
373d670bd4fSSam Ravnborg 	for_each_online_cpu(i) {
374d670bd4fSSam Ravnborg 		seq_printf(m,
375d670bd4fSSam Ravnborg 			   "Cpu%dBogo\t: %lu.%02lu\n",
376d670bd4fSSam Ravnborg 			   i,
377d670bd4fSSam Ravnborg 			   cpu_data(i).udelay_val/(500000/HZ),
378d670bd4fSSam Ravnborg 			   (cpu_data(i).udelay_val/(5000/HZ))%100);
379d670bd4fSSam Ravnborg 	}
380d670bd4fSSam Ravnborg }
381d670bd4fSSam Ravnborg 
smp_info(struct seq_file * m)382d670bd4fSSam Ravnborg void smp_info(struct seq_file *m)
383d670bd4fSSam Ravnborg {
384d670bd4fSSam Ravnborg 	int i;
385d670bd4fSSam Ravnborg 
386d670bd4fSSam Ravnborg 	seq_printf(m, "State:\n");
387d670bd4fSSam Ravnborg 	for_each_online_cpu(i)
388d670bd4fSSam Ravnborg 		seq_printf(m, "CPU%d\t\t: online\n", i);
389d670bd4fSSam Ravnborg }
390