summaryrefslogtreecommitdiffstats
path: root/arch/sparc/prom/mp.c
blob: 8f07f9d40502fba554be40ba8724d54cd087e52a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* $Id: mp.c,v 1.9 1997/05/14 20:45:01 davem Exp $
 * mp.c:  OpenBoot Prom Multiprocessor support routines.  Don't call
 *        these on a UP or else you will halt and catch fire. ;)
 *
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>

#include <asm/openprom.h>
#include <asm/oplib.h>

/* XXX Let's get rid of this thing if we can... */
extern struct task_struct *current_set[NR_CPUS];

/* Start cpu with prom-tree node 'cpunode' using context described
 * by 'ctable_reg' in context 'ctx' at program counter 'pc'.
 *
 * XXX Have to look into what the return values mean. XXX
 */
int
prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, char *pc)
{
	int ret;
	unsigned long flags;

	save_flags(flags); cli();
	switch(prom_vers) {
	case PROM_V0:
	case PROM_V2:
	case PROM_AP1000:
	default:
		ret = -1;
		break;
	case PROM_V3:
		ret = (*(romvec->v3_cpustart))(cpunode, (int) ctable_reg, ctx, pc);
		break;
	};
	__asm__ __volatile__("ld [%0], %%g6\n\t" : :
			     "r" (&current_set[hard_smp_processor_id()]) :
			     "memory");
	restore_flags(flags);

	return ret;
}

/* Stop CPU with device prom-tree node 'cpunode'.
 * XXX Again, what does the return value really mean? XXX
 */
int
prom_stopcpu(int cpunode)
{
	int ret;
	unsigned long flags;

	save_flags(flags); cli();
	switch(prom_vers) {
	case PROM_V0:
	case PROM_V2:
	case PROM_AP1000:
	default:
		ret = -1;
		break;
	case PROM_V3:
		ret = (*(romvec->v3_cpustop))(cpunode);
		break;
	};
	__asm__ __volatile__("ld [%0], %%g6\n\t" : :
			     "r" (&current_set[hard_smp_processor_id()]) :
			     "memory");
	restore_flags(flags);

	return ret;
}

/* Make CPU with device prom-tree node 'cpunode' idle.
 * XXX Return value, anyone? XXX
 */
int
prom_idlecpu(int cpunode)
{
	int ret;
	unsigned long flags;

	save_flags(flags); cli();
	switch(prom_vers) {
	case PROM_V0:
	case PROM_V2:
	case PROM_AP1000:
	default:
		ret = -1;
		break;
	case PROM_V3:
		ret = (*(romvec->v3_cpuidle))(cpunode);
		break;
	};
	__asm__ __volatile__("ld [%0], %%g6\n\t" : :
			     "r" (&current_set[hard_smp_processor_id()]) :
			     "memory");
	restore_flags(flags);

	return ret;
}

/* Resume the execution of CPU with nodeid 'cpunode'.
 * XXX Come on, somebody has to know... XXX
 */
int
prom_restartcpu(int cpunode)
{
	int ret;
	unsigned long flags;

	save_flags(flags); cli();
	switch(prom_vers) {
	case PROM_V0:
	case PROM_V2:
	case PROM_AP1000:
	default:
		ret = -1;
		break;
	case PROM_V3:
		ret = (*(romvec->v3_cpuresume))(cpunode);
		break;
	};
	__asm__ __volatile__("ld [%0], %%g6\n\t" : :
			     "r" (&current_set[hard_smp_processor_id()]) :
			     "memory");
	restore_flags(flags);

	return ret;
}