• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  linux/arch/m32r/kernel/smpboot.c
3  *    orig : i386 2.4.10
4  *
5  *  M32R SMP booting functions
6  *
7  *  Copyright (c) 2001, 2002, 2003  Hitoshi Yamamoto
8  *
9  *  Taken from i386 version.
10  *	  (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
11  *	  (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
12  *
13  *	Much of the core SMP work is based on previous work by Thomas Radke, to
14  *	whom a great many thanks are extended.
15  *
16  *	Thanks to Intel for making available several different Pentium,
17  *	Pentium Pro and Pentium-II/Xeon MP machines.
18  *	Original development of Linux SMP code supported by Caldera.
19  *
20  *	This code is released under the GNU General Public License version 2 or
21  *	later.
22  *
23  *	Fixes
24  *		Felix Koop	:	NR_CPUS used properly
25  *		Jose Renau	:	Handle single CPU case.
26  *		Alan Cox	:	By repeated request
27  *					8) - Total BogoMIP report.
28  *		Greg Wright	:	Fix for kernel stacks panic.
29  *		Erich Boleyn	:	MP v1.4 and additional changes.
30  *	Matthias Sattler	:	Changes for 2.1 kernel map.
31  *	Michel Lespinasse	:	Changes for 2.1 kernel map.
32  *	Michael Chastain	:	Change trampoline.S to gnu as.
33  *		Alan Cox	:	Dumb bug: 'B' step PPro's are fine
34  *		Ingo Molnar	:	Added APIC timers, based on code
35  *					from Jose Renau
36  *		Ingo Molnar	:	various cleanups and rewrites
37  *		Tigran Aivazian	:	fixed "0.00 in /proc/uptime on SMP" bug.
38  *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs
39  *		Martin J. Bligh	: 	Added support for multi-quad systems
40  */
41 
42 #include <linux/module.h>
43 #include <linux/cpu.h>
44 #include <linux/init.h>
45 #include <linux/kernel.h>
46 #include <linux/mm.h>
47 #include <linux/sched.h>
48 #include <linux/sched/task.h>
49 #include <linux/err.h>
50 #include <linux/irq.h>
51 #include <linux/bootmem.h>
52 #include <linux/delay.h>
53 
54 #include <asm/io.h>
55 #include <asm/pgalloc.h>
56 #include <asm/tlbflush.h>
57 
58 #define DEBUG_SMP
59 #ifdef DEBUG_SMP
60 #define Dprintk(x...) printk(x)
61 #else
62 #define Dprintk(x...)
63 #endif
64 
65 extern cpumask_t cpu_initialized;
66 
67 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
68 /* Data structures and variables                                             */
69 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
70 
71 /* Processor that is doing the boot up */
72 static unsigned int bsp_phys_id = -1;
73 
74 /* Bitmask of physically existing CPUs */
75 physid_mask_t phys_cpu_present_map;
76 
77 cpumask_t cpu_bootout_map;
78 cpumask_t cpu_bootin_map;
79 static cpumask_t cpu_callin_map;
80 cpumask_t cpu_callout_map;
81 EXPORT_SYMBOL(cpu_callout_map);
82 
83 /* Per CPU bogomips and other parameters */
84 struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned;
85 
86 static int cpucount;
87 static cpumask_t smp_commenced_mask;
88 
89 extern struct {
90 	void * spi;
91 	unsigned short ss;
92 } stack_start;
93 
94 /* which physical physical ID maps to which logical CPU number */
95 static volatile int physid_2_cpu[NR_CPUS];
96 #define physid_to_cpu(physid)	physid_2_cpu[physid]
97 
98 /* which logical CPU number maps to which physical ID */
99 volatile int cpu_2_physid[NR_CPUS];
100 
101 DEFINE_PER_CPU(int, prof_multiplier) = 1;
102 DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
103 DEFINE_PER_CPU(int, prof_counter) = 1;
104 
105 spinlock_t ipi_lock[NR_IPIS];
106 
107 static unsigned int calibration_result;
108 
109 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
110 /* Function Prototypes                                                       */
111 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
112 
113 static void init_ipi_lock(void);
114 static void do_boot_cpu(int);
115 
116 int start_secondary(void *);
117 static void smp_callin(void);
118 static void smp_online(void);
119 
120 static void show_mp_info(int);
121 static void smp_store_cpu_info(int);
122 static void show_cpu_info(int);
123 int setup_profiling_timer(unsigned int);
124 static void init_cpu_to_physid(void);
125 static void map_cpu_to_physid(int, int);
126 static void unmap_cpu_to_physid(int, int);
127 
128 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
129 /* Boot up APs Routines : BSP                                                */
130 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
smp_prepare_boot_cpu(void)131 void smp_prepare_boot_cpu(void)
132 {
133 	bsp_phys_id = hard_smp_processor_id();
134 	physid_set(bsp_phys_id, phys_cpu_present_map);
135 	set_cpu_online(0, true);	/* BSP's cpu_id == 0 */
136 	cpumask_set_cpu(0, &cpu_callout_map);
137 	cpumask_set_cpu(0, &cpu_callin_map);
138 
139 	/*
140 	 * Initialize the logical to physical CPU number mapping
141 	 */
142 	init_cpu_to_physid();
143 	map_cpu_to_physid(0, bsp_phys_id);
144 	current_thread_info()->cpu = 0;
145 }
146 
147 /*==========================================================================*
148  * Name:         smp_prepare_cpus (old smp_boot_cpus)
149  *
150  * Description:  This routine boot up APs.
151  *
152  * Born on Date: 2002.02.05
153  *
154  * Arguments:    NONE
155  *
156  * Returns:      void (cannot fail)
157  *
158  * Modification log:
159  * Date       Who Description
160  * ---------- --- --------------------------------------------------------
161  * 2003-06-24 hy  modify for linux-2.5.69
162  *
163  *==========================================================================*/
smp_prepare_cpus(unsigned int max_cpus)164 void __init smp_prepare_cpus(unsigned int max_cpus)
165 {
166 	int phys_id;
167 	unsigned long nr_cpu;
168 
169 	nr_cpu = inl(M32R_FPGA_NUM_OF_CPUS_PORTL);
170 	if (nr_cpu > NR_CPUS) {
171 		printk(KERN_INFO "NUM_OF_CPUS reg. value [%ld] > NR_CPU [%d]",
172 			nr_cpu, NR_CPUS);
173 		goto smp_done;
174 	}
175 	for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)
176 		physid_set(phys_id, phys_cpu_present_map);
177 #ifndef CONFIG_HOTPLUG_CPU
178 	init_cpu_present(cpu_possible_mask);
179 #endif
180 
181 	show_mp_info(nr_cpu);
182 
183 	init_ipi_lock();
184 
185 	/*
186 	 * Setup boot CPU information
187 	 */
188 	smp_store_cpu_info(0); /* Final full version of the data */
189 
190 	/*
191 	 * If SMP should be disabled, then really disable it!
192 	 */
193 	if (!max_cpus) {
194 		printk(KERN_INFO "SMP mode deactivated by commandline.\n");
195 		goto smp_done;
196 	}
197 
198 	/*
199 	 * Now scan the CPU present map and fire up the other CPUs.
200 	 */
201 	Dprintk("CPU present map : %lx\n", physids_coerce(phys_cpu_present_map));
202 
203 	for (phys_id = 0 ; phys_id < NR_CPUS ; phys_id++) {
204 		/*
205 		 * Don't even attempt to start the boot CPU!
206 		 */
207 		if (phys_id == bsp_phys_id)
208 			continue;
209 
210 		if (!physid_isset(phys_id, phys_cpu_present_map))
211 			continue;
212 
213 		if (max_cpus <= cpucount + 1)
214 			continue;
215 
216 		do_boot_cpu(phys_id);
217 
218 		/*
219 		 * Make sure we unmap all failed CPUs
220 		 */
221 		if (physid_to_cpu(phys_id) == -1) {
222 			physid_clear(phys_id, phys_cpu_present_map);
223 			printk("phys CPU#%d not responding - " \
224 				"cannot use it.\n", phys_id);
225 		}
226 	}
227 
228 smp_done:
229 	Dprintk("Boot done.\n");
230 }
231 
232 /*
233  * init_ipi_lock : Initialize IPI locks.
234  */
init_ipi_lock(void)235 static void __init init_ipi_lock(void)
236 {
237 	int ipi;
238 
239 	for (ipi = 0 ; ipi < NR_IPIS ; ipi++)
240 		spin_lock_init(&ipi_lock[ipi]);
241 }
242 
243 /*==========================================================================*
244  * Name:         do_boot_cpu
245  *
246  * Description:  This routine boot up one AP.
247  *
248  * Born on Date: 2002.02.05
249  *
250  * Arguments:    phys_id - Target CPU physical ID
251  *
252  * Returns:      void (cannot fail)
253  *
254  * Modification log:
255  * Date       Who Description
256  * ---------- --- --------------------------------------------------------
257  * 2003-06-24 hy  modify for linux-2.5.69
258  *
259  *==========================================================================*/
do_boot_cpu(int phys_id)260 static void __init do_boot_cpu(int phys_id)
261 {
262 	struct task_struct *idle;
263 	unsigned long send_status, boot_status;
264 	int timeout, cpu_id;
265 
266 	cpu_id = ++cpucount;
267 
268 	/*
269 	 * We can't use kernel_thread since we must avoid to
270 	 * reschedule the child.
271 	 */
272 	idle = fork_idle(cpu_id);
273 	if (IS_ERR(idle))
274 		panic("failed fork for CPU#%d.", cpu_id);
275 
276 	idle->thread.lr = (unsigned long)start_secondary;
277 
278 	map_cpu_to_physid(cpu_id, phys_id);
279 
280 	/* So we see what's up   */
281 	printk("Booting processor %d/%d\n", phys_id, cpu_id);
282 	stack_start.spi = (void *)idle->thread.sp;
283 	task_thread_info(idle)->cpu = cpu_id;
284 
285 	/*
286 	 * Send Startup IPI
287 	 *   1.IPI received by CPU#(phys_id).
288 	 *   2.CPU#(phys_id) enter startup_AP (arch/m32r/kernel/head.S)
289 	 *   3.CPU#(phys_id) enter start_secondary()
290 	 */
291 	send_status = 0;
292 	boot_status = 0;
293 
294 	cpumask_set_cpu(phys_id, &cpu_bootout_map);
295 
296 	/* Send Startup IPI */
297 	send_IPI_mask_phys(cpumask_of(phys_id), CPU_BOOT_IPI, 0);
298 
299 	Dprintk("Waiting for send to finish...\n");
300 	timeout = 0;
301 
302 	/* Wait 100[ms] */
303 	do {
304 		Dprintk("+");
305 		udelay(1000);
306 		send_status = !cpumask_test_cpu(phys_id, &cpu_bootin_map);
307 	} while (send_status && (timeout++ < 100));
308 
309 	Dprintk("After Startup.\n");
310 
311 	if (!send_status) {
312 		/*
313 		 * allow APs to start initializing.
314 		 */
315 		Dprintk("Before Callout %d.\n", cpu_id);
316 		cpumask_set_cpu(cpu_id, &cpu_callout_map);
317 		Dprintk("After Callout %d.\n", cpu_id);
318 
319 		/*
320 		 * Wait 5s total for a response
321 		 */
322 		for (timeout = 0; timeout < 5000; timeout++) {
323 			if (cpumask_test_cpu(cpu_id, &cpu_callin_map))
324 				break;	/* It has booted */
325 			udelay(1000);
326 		}
327 
328 		if (cpumask_test_cpu(cpu_id, &cpu_callin_map)) {
329 			/* number CPUs logically, starting from 1 (BSP is 0) */
330 			Dprintk("OK.\n");
331 		} else {
332 			boot_status = 1;
333 			printk("Not responding.\n");
334 		}
335 	} else
336 		printk("IPI never delivered???\n");
337 
338 	if (send_status || boot_status) {
339 		unmap_cpu_to_physid(cpu_id, phys_id);
340 		cpumask_clear_cpu(cpu_id, &cpu_callout_map);
341 		cpumask_clear_cpu(cpu_id, &cpu_callin_map);
342 		cpumask_clear_cpu(cpu_id, &cpu_initialized);
343 		cpucount--;
344 	}
345 }
346 
__cpu_up(unsigned int cpu_id,struct task_struct * tidle)347 int __cpu_up(unsigned int cpu_id, struct task_struct *tidle)
348 {
349 	int timeout;
350 
351 	cpumask_set_cpu(cpu_id, &smp_commenced_mask);
352 
353 	/*
354 	 * Wait 5s total for a response
355 	 */
356 	for (timeout = 0; timeout < 5000; timeout++) {
357 		if (cpu_online(cpu_id))
358 			break;
359 		udelay(1000);
360 	}
361 	if (!cpu_online(cpu_id))
362 		BUG();
363 
364 	return 0;
365 }
366 
smp_cpus_done(unsigned int max_cpus)367 void __init smp_cpus_done(unsigned int max_cpus)
368 {
369 	int cpu_id, timeout;
370 	unsigned long bogosum = 0;
371 
372 	for (timeout = 0; timeout < 5000; timeout++) {
373 		if (cpumask_equal(&cpu_callin_map, cpu_online_mask))
374 			break;
375 		udelay(1000);
376 	}
377 	if (!cpumask_equal(&cpu_callin_map, cpu_online_mask))
378 		BUG();
379 
380 	for_each_online_cpu(cpu_id)
381 		show_cpu_info(cpu_id);
382 
383 	/*
384 	 * Allow the user to impress friends.
385 	 */
386 	Dprintk("Before bogomips.\n");
387 	if (cpucount) {
388 		for_each_cpu(cpu_id,cpu_online_mask)
389 			bogosum += cpu_data[cpu_id].loops_per_jiffy;
390 
391 		printk(KERN_INFO "Total of %d processors activated " \
392 			"(%lu.%02lu BogoMIPS).\n", cpucount + 1,
393 			bogosum / (500000 / HZ),
394 			(bogosum / (5000 / HZ)) % 100);
395 		Dprintk("Before bogocount - setting activated=1.\n");
396 	}
397 }
398 
399 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
400 /* Activate a secondary processor Routines                                   */
401 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
402 
403 /*==========================================================================*
404  * Name:         start_secondary
405  *
406  * Description:  This routine activate a secondary processor.
407  *
408  * Born on Date: 2002.02.05
409  *
410  * Arguments:    *unused - currently unused.
411  *
412  * Returns:      void (cannot fail)
413  *
414  * Modification log:
415  * Date       Who Description
416  * ---------- --- --------------------------------------------------------
417  * 2003-06-24 hy  modify for linux-2.5.69
418  *
419  *==========================================================================*/
start_secondary(void * unused)420 int __init start_secondary(void *unused)
421 {
422 	cpu_init();
423 	preempt_disable();
424 	smp_callin();
425 	while (!cpumask_test_cpu(smp_processor_id(), &smp_commenced_mask))
426 		cpu_relax();
427 
428 	smp_online();
429 
430 	/*
431 	 * low-memory mappings have been cleared, flush them from
432 	 * the local TLBs too.
433 	 */
434 	local_flush_tlb_all();
435 
436 	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
437 	return 0;
438 }
439 
440 /*==========================================================================*
441  * Name:         smp_callin
442  *
443  * Description:  This routine activate a secondary processor.
444  *
445  * Born on Date: 2002.02.05
446  *
447  * Arguments:    NONE
448  *
449  * Returns:      void (cannot fail)
450  *
451  * Modification log:
452  * Date       Who Description
453  * ---------- --- --------------------------------------------------------
454  * 2003-06-24 hy  modify for linux-2.5.69
455  *
456  *==========================================================================*/
smp_callin(void)457 static void __init smp_callin(void)
458 {
459 	int phys_id = hard_smp_processor_id();
460 	int cpu_id = smp_processor_id();
461 	unsigned long timeout;
462 
463 	if (cpumask_test_cpu(cpu_id, &cpu_callin_map)) {
464 		printk("huh, phys CPU#%d, CPU#%d already present??\n",
465 			phys_id, cpu_id);
466 		BUG();
467 	}
468 	Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpu_id, phys_id);
469 
470 	/* Waiting 2s total for startup (udelay is not yet working) */
471 	timeout = jiffies + (2 * HZ);
472 	while (time_before(jiffies, timeout)) {
473 		/* Has the boot CPU finished it's STARTUP sequence ? */
474 		if (cpumask_test_cpu(cpu_id, &cpu_callout_map))
475 			break;
476 		cpu_relax();
477 	}
478 
479 	if (!time_before(jiffies, timeout)) {
480 		printk("BUG: CPU#%d started up but did not get a callout!\n",
481 			cpu_id);
482 		BUG();
483 	}
484 
485 	/* Allow the master to continue. */
486 	cpumask_set_cpu(cpu_id, &cpu_callin_map);
487 }
488 
smp_online(void)489 static void __init smp_online(void)
490 {
491 	int cpu_id = smp_processor_id();
492 
493 	notify_cpu_starting(cpu_id);
494 
495 	local_irq_enable();
496 
497 	/* Get our bogomips. */
498 	calibrate_delay();
499 
500 	/* Save our processor parameters */
501  	smp_store_cpu_info(cpu_id);
502 
503 	set_cpu_online(cpu_id, true);
504 }
505 
506 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
507 /* Boot up CPUs common Routines                                              */
508 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
show_mp_info(int nr_cpu)509 static void __init show_mp_info(int nr_cpu)
510 {
511 	int i;
512 	char cpu_model0[17], cpu_model1[17], cpu_ver[9];
513 
514 	strncpy(cpu_model0, (char *)M32R_FPGA_CPU_NAME_ADDR, 16);
515 	strncpy(cpu_model1, (char *)M32R_FPGA_MODEL_ID_ADDR, 16);
516 	strncpy(cpu_ver, (char *)M32R_FPGA_VERSION_ADDR, 8);
517 
518 	cpu_model0[16] = '\0';
519 	for (i = 15 ; i >= 0 ; i--) {
520 		if (cpu_model0[i] != ' ')
521 			break;
522 		cpu_model0[i] = '\0';
523 	}
524 	cpu_model1[16] = '\0';
525 	for (i = 15 ; i >= 0 ; i--) {
526 		if (cpu_model1[i] != ' ')
527 			break;
528 		cpu_model1[i] = '\0';
529 	}
530 	cpu_ver[8] = '\0';
531 	for (i = 7 ; i >= 0 ; i--) {
532 		if (cpu_ver[i] != ' ')
533 			break;
534 		cpu_ver[i] = '\0';
535 	}
536 
537 	printk(KERN_INFO "M32R-mp information\n");
538 	printk(KERN_INFO "  On-chip CPUs : %d\n", nr_cpu);
539 	printk(KERN_INFO "  CPU model : %s/%s(%s)\n", cpu_model0,
540 		cpu_model1, cpu_ver);
541 }
542 
543 /*
544  * The bootstrap kernel entry code has set these up. Save them for
545  * a given CPU
546  */
smp_store_cpu_info(int cpu_id)547 static void __init smp_store_cpu_info(int cpu_id)
548 {
549 	struct cpuinfo_m32r *ci = cpu_data + cpu_id;
550 
551 	*ci = boot_cpu_data;
552 	ci->loops_per_jiffy = loops_per_jiffy;
553 }
554 
show_cpu_info(int cpu_id)555 static void __init show_cpu_info(int cpu_id)
556 {
557 	struct cpuinfo_m32r *ci = &cpu_data[cpu_id];
558 
559 	printk("CPU#%d : ", cpu_id);
560 
561 #define PRINT_CLOCK(name, value) \
562 	printk(name " clock %d.%02dMHz", \
563 		((value) / 1000000), ((value) % 1000000) / 10000)
564 
565 	PRINT_CLOCK("CPU", (int)ci->cpu_clock);
566 	PRINT_CLOCK(", Bus", (int)ci->bus_clock);
567 	printk(", loops_per_jiffy[%ld]\n", ci->loops_per_jiffy);
568 }
569 
570 /*
571  * the frequency of the profiling timer can be changed
572  * by writing a multiplier value into /proc/profile.
573  */
setup_profiling_timer(unsigned int multiplier)574 int setup_profiling_timer(unsigned int multiplier)
575 {
576 	int i;
577 
578 	/*
579 	 * Sanity check. [at least 500 APIC cycles should be
580 	 * between APIC interrupts as a rule of thumb, to avoid
581 	 * irqs flooding us]
582 	 */
583 	if ( (!multiplier) || (calibration_result / multiplier < 500))
584 		return -EINVAL;
585 
586 	/*
587 	 * Set the new multiplier for each CPU. CPUs don't start using the
588 	 * new values until the next timer interrupt in which they do process
589 	 * accounting. At that time they also adjust their APIC timers
590 	 * accordingly.
591 	 */
592 	for_each_possible_cpu(i)
593 		per_cpu(prof_multiplier, i) = multiplier;
594 
595 	return 0;
596 }
597 
598 /* Initialize all maps between cpu number and apicids */
init_cpu_to_physid(void)599 static void __init init_cpu_to_physid(void)
600 {
601 	int  i;
602 
603 	for (i = 0 ; i < NR_CPUS ; i++) {
604 		cpu_2_physid[i] = -1;
605 		physid_2_cpu[i] = -1;
606 	}
607 }
608 
609 /*
610  * set up a mapping between cpu and apicid. Uses logical apicids for multiquad,
611  * else physical apic ids
612  */
map_cpu_to_physid(int cpu_id,int phys_id)613 static void __init map_cpu_to_physid(int cpu_id, int phys_id)
614 {
615 	physid_2_cpu[phys_id] = cpu_id;
616 	cpu_2_physid[cpu_id] = phys_id;
617 }
618 
619 /*
620  * undo a mapping between cpu and apicid. Uses logical apicids for multiquad,
621  * else physical apic ids
622  */
unmap_cpu_to_physid(int cpu_id,int phys_id)623 static void __init unmap_cpu_to_physid(int cpu_id, int phys_id)
624 {
625 	physid_2_cpu[phys_id] = -1;
626 	cpu_2_physid[cpu_id] = -1;
627 }
628