1 /* $Id: mp.c,v 1.12 2000/08/26 02:38:03 anton Exp $
2  * mp.c:  OpenBoot Prom Multiprocessor support routines.  Don't call
3  *        these on a UP or else you will halt and catch fire. ;)
4  *
5  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6  */
7 
8 #include <linux/types.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 
12 #include <asm/openprom.h>
13 #include <asm/oplib.h>
14 
15 extern void restore_current(void);
16 
17 /* Start cpu with prom-tree node 'cpunode' using context described
18  * by 'ctable_reg' in context 'ctx' at program counter 'pc'.
19  *
20  * XXX Have to look into what the return values mean. XXX
21  */
22 int
prom_startcpu(int cpunode,struct linux_prom_registers * ctable_reg,int ctx,char * pc)23 prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, char *pc)
24 {
25 	int ret;
26 	unsigned long flags;
27 
28 	spin_lock_irqsave(&prom_lock, flags);
29 	switch(prom_vers) {
30 	case PROM_V0:
31 	case PROM_V2:
32 	default:
33 		ret = -1;
34 		break;
35 	case PROM_V3:
36 		ret = (*(romvec->v3_cpustart))(cpunode, (int) ctable_reg, ctx, pc);
37 		break;
38 	};
39 	restore_current();
40 	spin_unlock_irqrestore(&prom_lock, flags);
41 
42 	return ret;
43 }
44 
45 /* Stop CPU with device prom-tree node 'cpunode'.
46  * XXX Again, what does the return value really mean? XXX
47  */
48 int
prom_stopcpu(int cpunode)49 prom_stopcpu(int cpunode)
50 {
51 	int ret;
52 	unsigned long flags;
53 
54 	spin_lock_irqsave(&prom_lock, flags);
55 	switch(prom_vers) {
56 	case PROM_V0:
57 	case PROM_V2:
58 	default:
59 		ret = -1;
60 		break;
61 	case PROM_V3:
62 		ret = (*(romvec->v3_cpustop))(cpunode);
63 		break;
64 	};
65 	restore_current();
66 	spin_unlock_irqrestore(&prom_lock, flags);
67 
68 	return ret;
69 }
70 
71 /* Make CPU with device prom-tree node 'cpunode' idle.
72  * XXX Return value, anyone? XXX
73  */
74 int
prom_idlecpu(int cpunode)75 prom_idlecpu(int cpunode)
76 {
77 	int ret;
78 	unsigned long flags;
79 
80 	spin_lock_irqsave(&prom_lock, flags);
81 	switch(prom_vers) {
82 	case PROM_V0:
83 	case PROM_V2:
84 	default:
85 		ret = -1;
86 		break;
87 	case PROM_V3:
88 		ret = (*(romvec->v3_cpuidle))(cpunode);
89 		break;
90 	};
91 	restore_current();
92 	spin_unlock_irqrestore(&prom_lock, flags);
93 
94 	return ret;
95 }
96 
97 /* Resume the execution of CPU with nodeid 'cpunode'.
98  * XXX Come on, somebody has to know... XXX
99  */
100 int
prom_restartcpu(int cpunode)101 prom_restartcpu(int cpunode)
102 {
103 	int ret;
104 	unsigned long flags;
105 
106 	spin_lock_irqsave(&prom_lock, flags);
107 	switch(prom_vers) {
108 	case PROM_V0:
109 	case PROM_V2:
110 	default:
111 		ret = -1;
112 		break;
113 	case PROM_V3:
114 		ret = (*(romvec->v3_cpuresume))(cpunode);
115 		break;
116 	};
117 	restore_current();
118 	spin_unlock_irqrestore(&prom_lock, flags);
119 
120 	return ret;
121 }
122