xref: /openbmc/linux/arch/sparc/prom/misc_64.c (revision 25edd6946a1d74e5e77813c2324a0908c68bcf9e)
15de18cdeSSam Ravnborg /*
25de18cdeSSam Ravnborg  * misc.c:  Miscellaneous prom functions that don't belong
35de18cdeSSam Ravnborg  *          anywhere else.
45de18cdeSSam Ravnborg  *
55de18cdeSSam Ravnborg  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
65de18cdeSSam Ravnborg  * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
75de18cdeSSam Ravnborg  */
85de18cdeSSam Ravnborg 
95de18cdeSSam Ravnborg #include <linux/types.h>
105de18cdeSSam Ravnborg #include <linux/kernel.h>
115de18cdeSSam Ravnborg #include <linux/sched.h>
125de18cdeSSam Ravnborg #include <linux/interrupt.h>
135de18cdeSSam Ravnborg #include <linux/delay.h>
14917c3660SSam Ravnborg #include <linux/module.h>
15917c3660SSam Ravnborg 
165de18cdeSSam Ravnborg #include <asm/openprom.h>
175de18cdeSSam Ravnborg #include <asm/oplib.h>
185de18cdeSSam Ravnborg #include <asm/system.h>
195de18cdeSSam Ravnborg #include <asm/ldc.h>
205de18cdeSSam Ravnborg 
215de18cdeSSam Ravnborg int prom_service_exists(const char *service_name)
225de18cdeSSam Ravnborg {
23*25edd694SDavid S. Miller 	unsigned long args[5];
245de18cdeSSam Ravnborg 
25*25edd694SDavid S. Miller 	args[0] = (unsigned long) "test";
26*25edd694SDavid S. Miller 	args[1] = 1;
27*25edd694SDavid S. Miller 	args[2] = 1;
28*25edd694SDavid S. Miller 	args[3] = (unsigned long) service_name;
29*25edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
30*25edd694SDavid S. Miller 
31*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
32*25edd694SDavid S. Miller 
33*25edd694SDavid S. Miller 	if (args[4])
345de18cdeSSam Ravnborg 		return 0;
355de18cdeSSam Ravnborg 	return 1;
365de18cdeSSam Ravnborg }
375de18cdeSSam Ravnborg 
385de18cdeSSam Ravnborg void prom_sun4v_guest_soft_state(void)
395de18cdeSSam Ravnborg {
405de18cdeSSam Ravnborg 	const char *svc = "SUNW,soft-state-supported";
41*25edd694SDavid S. Miller 	unsigned long args[3];
425de18cdeSSam Ravnborg 
435de18cdeSSam Ravnborg 	if (!prom_service_exists(svc))
445de18cdeSSam Ravnborg 		return;
45*25edd694SDavid S. Miller 	args[0] = (unsigned long) svc;
46*25edd694SDavid S. Miller 	args[1] = 0;
47*25edd694SDavid S. Miller 	args[2] = 0;
48*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
495de18cdeSSam Ravnborg }
505de18cdeSSam Ravnborg 
515de18cdeSSam Ravnborg /* Reset and reboot the machine with the command 'bcommand'. */
525de18cdeSSam Ravnborg void prom_reboot(const char *bcommand)
535de18cdeSSam Ravnborg {
54*25edd694SDavid S. Miller 	unsigned long args[4];
55*25edd694SDavid S. Miller 
565de18cdeSSam Ravnborg #ifdef CONFIG_SUN_LDOMS
575de18cdeSSam Ravnborg 	if (ldom_domaining_enabled)
585de18cdeSSam Ravnborg 		ldom_reboot(bcommand);
595de18cdeSSam Ravnborg #endif
60*25edd694SDavid S. Miller 	args[0] = (unsigned long) "boot";
61*25edd694SDavid S. Miller 	args[1] = 1;
62*25edd694SDavid S. Miller 	args[2] = 0;
63*25edd694SDavid S. Miller 	args[3] = (unsigned long) bcommand;
64*25edd694SDavid S. Miller 
65*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
665de18cdeSSam Ravnborg }
675de18cdeSSam Ravnborg 
685de18cdeSSam Ravnborg /* Forth evaluate the expression contained in 'fstring'. */
695de18cdeSSam Ravnborg void prom_feval(const char *fstring)
705de18cdeSSam Ravnborg {
71*25edd694SDavid S. Miller 	unsigned long args[5];
72*25edd694SDavid S. Miller 
735de18cdeSSam Ravnborg 	if (!fstring || fstring[0] == 0)
745de18cdeSSam Ravnborg 		return;
75*25edd694SDavid S. Miller 	args[0] = (unsigned long) "interpret";
76*25edd694SDavid S. Miller 	args[1] = 1;
77*25edd694SDavid S. Miller 	args[2] = 1;
78*25edd694SDavid S. Miller 	args[3] = (unsigned long) fstring;
79*25edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
80*25edd694SDavid S. Miller 
81*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
825de18cdeSSam Ravnborg }
83917c3660SSam Ravnborg EXPORT_SYMBOL(prom_feval);
845de18cdeSSam Ravnborg 
855de18cdeSSam Ravnborg #ifdef CONFIG_SMP
865de18cdeSSam Ravnborg extern void smp_capture(void);
875de18cdeSSam Ravnborg extern void smp_release(void);
885de18cdeSSam Ravnborg #endif
895de18cdeSSam Ravnborg 
905de18cdeSSam Ravnborg /* Drop into the prom, with the chance to continue with the 'go'
915de18cdeSSam Ravnborg  * prom command.
925de18cdeSSam Ravnborg  */
935de18cdeSSam Ravnborg void prom_cmdline(void)
945de18cdeSSam Ravnborg {
95*25edd694SDavid S. Miller 	unsigned long args[3];
965de18cdeSSam Ravnborg 	unsigned long flags;
975de18cdeSSam Ravnborg 
985de18cdeSSam Ravnborg 	local_irq_save(flags);
995de18cdeSSam Ravnborg 
1005de18cdeSSam Ravnborg #ifdef CONFIG_SMP
1015de18cdeSSam Ravnborg 	smp_capture();
1025de18cdeSSam Ravnborg #endif
1035de18cdeSSam Ravnborg 
104*25edd694SDavid S. Miller 	args[0] = (unsigned long) "enter";
105*25edd694SDavid S. Miller 	args[1] = 0;
106*25edd694SDavid S. Miller 	args[2] = 0;
107*25edd694SDavid S. Miller 
108*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
1095de18cdeSSam Ravnborg 
1105de18cdeSSam Ravnborg #ifdef CONFIG_SMP
1115de18cdeSSam Ravnborg 	smp_release();
1125de18cdeSSam Ravnborg #endif
1135de18cdeSSam Ravnborg 
1145de18cdeSSam Ravnborg 	local_irq_restore(flags);
1155de18cdeSSam Ravnborg }
1165de18cdeSSam Ravnborg 
1175de18cdeSSam Ravnborg /* Drop into the prom, but completely terminate the program.
1185de18cdeSSam Ravnborg  * No chance of continuing.
1195de18cdeSSam Ravnborg  */
120bd4352caSDavid S. Miller void notrace prom_halt(void)
1215de18cdeSSam Ravnborg {
122*25edd694SDavid S. Miller 	unsigned long args[3];
123*25edd694SDavid S. Miller 
1245de18cdeSSam Ravnborg #ifdef CONFIG_SUN_LDOMS
1255de18cdeSSam Ravnborg 	if (ldom_domaining_enabled)
1265de18cdeSSam Ravnborg 		ldom_power_off();
1275de18cdeSSam Ravnborg #endif
1285de18cdeSSam Ravnborg again:
129*25edd694SDavid S. Miller 	args[0] = (unsigned long) "exit";
130*25edd694SDavid S. Miller 	args[1] = 0;
131*25edd694SDavid S. Miller 	args[2] = 0;
132*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
1335de18cdeSSam Ravnborg 	goto again; /* PROM is out to get me -DaveM */
1345de18cdeSSam Ravnborg }
1355de18cdeSSam Ravnborg 
1365de18cdeSSam Ravnborg void prom_halt_power_off(void)
1375de18cdeSSam Ravnborg {
138*25edd694SDavid S. Miller 	unsigned long args[3];
139*25edd694SDavid S. Miller 
1405de18cdeSSam Ravnborg #ifdef CONFIG_SUN_LDOMS
1415de18cdeSSam Ravnborg 	if (ldom_domaining_enabled)
1425de18cdeSSam Ravnborg 		ldom_power_off();
1435de18cdeSSam Ravnborg #endif
144*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,power-off";
145*25edd694SDavid S. Miller 	args[1] = 0;
146*25edd694SDavid S. Miller 	args[2] = 0;
147*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
1485de18cdeSSam Ravnborg 
1495de18cdeSSam Ravnborg 	/* if nothing else helps, we just halt */
1505de18cdeSSam Ravnborg 	prom_halt();
1515de18cdeSSam Ravnborg }
1525de18cdeSSam Ravnborg 
1535de18cdeSSam Ravnborg /* Set prom sync handler to call function 'funcp'. */
1545de18cdeSSam Ravnborg void prom_setcallback(callback_func_t funcp)
1555de18cdeSSam Ravnborg {
156*25edd694SDavid S. Miller 	unsigned long args[5];
1575de18cdeSSam Ravnborg 	if (!funcp)
1585de18cdeSSam Ravnborg 		return;
159*25edd694SDavid S. Miller 	args[0] = (unsigned long) "set-callback";
160*25edd694SDavid S. Miller 	args[1] = 1;
161*25edd694SDavid S. Miller 	args[2] = 1;
162*25edd694SDavid S. Miller 	args[3] = (unsigned long) funcp;
163*25edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
164*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
1655de18cdeSSam Ravnborg }
1665de18cdeSSam Ravnborg 
1675de18cdeSSam Ravnborg /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
1685de18cdeSSam Ravnborg  * format type.  'num_bytes' is the number of bytes that your idbuf
1695de18cdeSSam Ravnborg  * has space for.  Returns 0xff on error.
1705de18cdeSSam Ravnborg  */
1715de18cdeSSam Ravnborg unsigned char prom_get_idprom(char *idbuf, int num_bytes)
1725de18cdeSSam Ravnborg {
1735de18cdeSSam Ravnborg 	int len;
1745de18cdeSSam Ravnborg 
1755de18cdeSSam Ravnborg 	len = prom_getproplen(prom_root_node, "idprom");
1765de18cdeSSam Ravnborg 	if ((len >num_bytes) || (len == -1))
1775de18cdeSSam Ravnborg 		return 0xff;
1785de18cdeSSam Ravnborg 	if (!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
1795de18cdeSSam Ravnborg 		return idbuf[0];
1805de18cdeSSam Ravnborg 
1815de18cdeSSam Ravnborg 	return 0xff;
1825de18cdeSSam Ravnborg }
1835de18cdeSSam Ravnborg 
1845de18cdeSSam Ravnborg int prom_get_mmu_ihandle(void)
1855de18cdeSSam Ravnborg {
1865de18cdeSSam Ravnborg 	int node, ret;
1875de18cdeSSam Ravnborg 
1885de18cdeSSam Ravnborg 	if (prom_mmu_ihandle_cache != 0)
1895de18cdeSSam Ravnborg 		return prom_mmu_ihandle_cache;
1905de18cdeSSam Ravnborg 
1915de18cdeSSam Ravnborg 	node = prom_finddevice(prom_chosen_path);
1925de18cdeSSam Ravnborg 	ret = prom_getint(node, prom_mmu_name);
1935de18cdeSSam Ravnborg 	if (ret == -1 || ret == 0)
1945de18cdeSSam Ravnborg 		prom_mmu_ihandle_cache = -1;
1955de18cdeSSam Ravnborg 	else
1965de18cdeSSam Ravnborg 		prom_mmu_ihandle_cache = ret;
1975de18cdeSSam Ravnborg 
1985de18cdeSSam Ravnborg 	return ret;
1995de18cdeSSam Ravnborg }
2005de18cdeSSam Ravnborg 
2015de18cdeSSam Ravnborg static int prom_get_memory_ihandle(void)
2025de18cdeSSam Ravnborg {
2035de18cdeSSam Ravnborg 	static int memory_ihandle_cache;
2045de18cdeSSam Ravnborg 	int node, ret;
2055de18cdeSSam Ravnborg 
2065de18cdeSSam Ravnborg 	if (memory_ihandle_cache != 0)
2075de18cdeSSam Ravnborg 		return memory_ihandle_cache;
2085de18cdeSSam Ravnborg 
2095de18cdeSSam Ravnborg 	node = prom_finddevice("/chosen");
2105de18cdeSSam Ravnborg 	ret = prom_getint(node, "memory");
2115de18cdeSSam Ravnborg 	if (ret == -1 || ret == 0)
2125de18cdeSSam Ravnborg 		memory_ihandle_cache = -1;
2135de18cdeSSam Ravnborg 	else
2145de18cdeSSam Ravnborg 		memory_ihandle_cache = ret;
2155de18cdeSSam Ravnborg 
2165de18cdeSSam Ravnborg 	return ret;
2175de18cdeSSam Ravnborg }
2185de18cdeSSam Ravnborg 
2195de18cdeSSam Ravnborg /* Load explicit I/D TLB entries. */
220*25edd694SDavid S. Miller static long tlb_load(const char *type, unsigned long index,
221*25edd694SDavid S. Miller 		     unsigned long tte_data, unsigned long vaddr)
222*25edd694SDavid S. Miller {
223*25edd694SDavid S. Miller 	unsigned long args[9];
224*25edd694SDavid S. Miller 
225*25edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
226*25edd694SDavid S. Miller 	args[1] = 5;
227*25edd694SDavid S. Miller 	args[2] = 1;
228*25edd694SDavid S. Miller 	args[3] = (unsigned long) type;
229*25edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
230*25edd694SDavid S. Miller 	args[5] = vaddr;
231*25edd694SDavid S. Miller 	args[6] = tte_data;
232*25edd694SDavid S. Miller 	args[7] = index;
233*25edd694SDavid S. Miller 	args[8] = (unsigned long) -1;
234*25edd694SDavid S. Miller 
235*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
236*25edd694SDavid S. Miller 
237*25edd694SDavid S. Miller 	return (long) args[8];
238*25edd694SDavid S. Miller }
239*25edd694SDavid S. Miller 
2405de18cdeSSam Ravnborg long prom_itlb_load(unsigned long index,
2415de18cdeSSam Ravnborg 		    unsigned long tte_data,
2425de18cdeSSam Ravnborg 		    unsigned long vaddr)
2435de18cdeSSam Ravnborg {
244*25edd694SDavid S. Miller 	return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
2455de18cdeSSam Ravnborg }
2465de18cdeSSam Ravnborg 
2475de18cdeSSam Ravnborg long prom_dtlb_load(unsigned long index,
2485de18cdeSSam Ravnborg 		    unsigned long tte_data,
2495de18cdeSSam Ravnborg 		    unsigned long vaddr)
2505de18cdeSSam Ravnborg {
251*25edd694SDavid S. Miller 	return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
2525de18cdeSSam Ravnborg }
2535de18cdeSSam Ravnborg 
2545de18cdeSSam Ravnborg int prom_map(int mode, unsigned long size,
2555de18cdeSSam Ravnborg 	     unsigned long vaddr, unsigned long paddr)
2565de18cdeSSam Ravnborg {
257*25edd694SDavid S. Miller 	unsigned long args[11];
258*25edd694SDavid S. Miller 	int ret;
2595de18cdeSSam Ravnborg 
260*25edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
261*25edd694SDavid S. Miller 	args[1] = 7;
262*25edd694SDavid S. Miller 	args[2] = 1;
263*25edd694SDavid S. Miller 	args[3] = (unsigned long) prom_map_name;
264*25edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
265*25edd694SDavid S. Miller 	args[5] = (unsigned int) mode;
266*25edd694SDavid S. Miller 	args[6] = size;
267*25edd694SDavid S. Miller 	args[7] = vaddr;
268*25edd694SDavid S. Miller 	args[8] = 0;
269*25edd694SDavid S. Miller 	args[9] = paddr;
270*25edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
271*25edd694SDavid S. Miller 
272*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
273*25edd694SDavid S. Miller 
274*25edd694SDavid S. Miller 	ret = (int) args[10];
2755de18cdeSSam Ravnborg 	if (ret == 0)
2765de18cdeSSam Ravnborg 		ret = -1;
2775de18cdeSSam Ravnborg 	return ret;
2785de18cdeSSam Ravnborg }
2795de18cdeSSam Ravnborg 
2805de18cdeSSam Ravnborg void prom_unmap(unsigned long size, unsigned long vaddr)
2815de18cdeSSam Ravnborg {
282*25edd694SDavid S. Miller 	unsigned long args[7];
283*25edd694SDavid S. Miller 
284*25edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
285*25edd694SDavid S. Miller 	args[1] = 4;
286*25edd694SDavid S. Miller 	args[2] = 0;
287*25edd694SDavid S. Miller 	args[3] = (unsigned long) prom_unmap_name;
288*25edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
289*25edd694SDavid S. Miller 	args[5] = size;
290*25edd694SDavid S. Miller 	args[6] = vaddr;
291*25edd694SDavid S. Miller 
292*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
2935de18cdeSSam Ravnborg }
2945de18cdeSSam Ravnborg 
2955de18cdeSSam Ravnborg /* Set aside physical memory which is not touched or modified
2965de18cdeSSam Ravnborg  * across soft resets.
2975de18cdeSSam Ravnborg  */
298*25edd694SDavid S. Miller int prom_retain(const char *name, unsigned long size,
299*25edd694SDavid S. Miller 		unsigned long align, unsigned long *paddr)
3005de18cdeSSam Ravnborg {
301*25edd694SDavid S. Miller 	unsigned long args[11];
3025de18cdeSSam Ravnborg 
303*25edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
304*25edd694SDavid S. Miller 	args[1] = 5;
305*25edd694SDavid S. Miller 	args[2] = 3;
306*25edd694SDavid S. Miller 	args[3] = (unsigned long) "SUNW,retain";
307*25edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_memory_ihandle();
308*25edd694SDavid S. Miller 	args[5] = align;
309*25edd694SDavid S. Miller 	args[6] = size;
310*25edd694SDavid S. Miller 	args[7] = (unsigned long) name;
311*25edd694SDavid S. Miller 	args[8] = (unsigned long) -1;
312*25edd694SDavid S. Miller 	args[9] = (unsigned long) -1;
313*25edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
314*25edd694SDavid S. Miller 
315*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
316*25edd694SDavid S. Miller 
317*25edd694SDavid S. Miller 	if (args[8])
318*25edd694SDavid S. Miller 		return (int) args[8];
319*25edd694SDavid S. Miller 
320*25edd694SDavid S. Miller 	/* Next we get "phys_high" then "phys_low".  On 64-bit
321*25edd694SDavid S. Miller 	 * the phys_high cell is don't care since the phys_low
322*25edd694SDavid S. Miller 	 * cell has the full value.
3235de18cdeSSam Ravnborg 	 */
324*25edd694SDavid S. Miller 	*paddr = args[10];
325*25edd694SDavid S. Miller 
326*25edd694SDavid S. Miller 	return 0;
3275de18cdeSSam Ravnborg }
3285de18cdeSSam Ravnborg 
3295de18cdeSSam Ravnborg /* Get "Unumber" string for the SIMM at the given
3305de18cdeSSam Ravnborg  * memory address.  Usually this will be of the form
3315de18cdeSSam Ravnborg  * "Uxxxx" where xxxx is a decimal number which is
3325de18cdeSSam Ravnborg  * etched into the motherboard next to the SIMM slot
3335de18cdeSSam Ravnborg  * in question.
3345de18cdeSSam Ravnborg  */
3355de18cdeSSam Ravnborg int prom_getunumber(int syndrome_code,
3365de18cdeSSam Ravnborg 		    unsigned long phys_addr,
3375de18cdeSSam Ravnborg 		    char *buf, int buflen)
3385de18cdeSSam Ravnborg {
339*25edd694SDavid S. Miller 	unsigned long args[12];
340*25edd694SDavid S. Miller 
341*25edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
342*25edd694SDavid S. Miller 	args[1] = 7;
343*25edd694SDavid S. Miller 	args[2] = 2;
344*25edd694SDavid S. Miller 	args[3] = (unsigned long) "SUNW,get-unumber";
345*25edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_memory_ihandle();
346*25edd694SDavid S. Miller 	args[5] = buflen;
347*25edd694SDavid S. Miller 	args[6] = (unsigned long) buf;
348*25edd694SDavid S. Miller 	args[7] = 0;
349*25edd694SDavid S. Miller 	args[8] = phys_addr;
350*25edd694SDavid S. Miller 	args[9] = (unsigned int) syndrome_code;
351*25edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
352*25edd694SDavid S. Miller 	args[11] = (unsigned long) -1;
353*25edd694SDavid S. Miller 
354*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
355*25edd694SDavid S. Miller 
356*25edd694SDavid S. Miller 	return (int) args[10];
3575de18cdeSSam Ravnborg }
3585de18cdeSSam Ravnborg 
3595de18cdeSSam Ravnborg /* Power management extensions. */
3605de18cdeSSam Ravnborg void prom_sleepself(void)
3615de18cdeSSam Ravnborg {
362*25edd694SDavid S. Miller 	unsigned long args[3];
363*25edd694SDavid S. Miller 
364*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,sleep-self";
365*25edd694SDavid S. Miller 	args[1] = 0;
366*25edd694SDavid S. Miller 	args[2] = 0;
367*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
3685de18cdeSSam Ravnborg }
3695de18cdeSSam Ravnborg 
3705de18cdeSSam Ravnborg int prom_sleepsystem(void)
3715de18cdeSSam Ravnborg {
372*25edd694SDavid S. Miller 	unsigned long args[4];
373*25edd694SDavid S. Miller 
374*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,sleep-system";
375*25edd694SDavid S. Miller 	args[1] = 0;
376*25edd694SDavid S. Miller 	args[2] = 1;
377*25edd694SDavid S. Miller 	args[3] = (unsigned long) -1;
378*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
379*25edd694SDavid S. Miller 
380*25edd694SDavid S. Miller 	return (int) args[3];
3815de18cdeSSam Ravnborg }
3825de18cdeSSam Ravnborg 
3835de18cdeSSam Ravnborg int prom_wakeupsystem(void)
3845de18cdeSSam Ravnborg {
385*25edd694SDavid S. Miller 	unsigned long args[4];
386*25edd694SDavid S. Miller 
387*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,wakeup-system";
388*25edd694SDavid S. Miller 	args[1] = 0;
389*25edd694SDavid S. Miller 	args[2] = 1;
390*25edd694SDavid S. Miller 	args[3] = (unsigned long) -1;
391*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
392*25edd694SDavid S. Miller 
393*25edd694SDavid S. Miller 	return (int) args[3];
3945de18cdeSSam Ravnborg }
3955de18cdeSSam Ravnborg 
3965de18cdeSSam Ravnborg #ifdef CONFIG_SMP
3975de18cdeSSam Ravnborg void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
3985de18cdeSSam Ravnborg {
399*25edd694SDavid S. Miller 	unsigned long args[6];
400*25edd694SDavid S. Miller 
401*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,start-cpu";
402*25edd694SDavid S. Miller 	args[1] = 3;
403*25edd694SDavid S. Miller 	args[2] = 0;
404*25edd694SDavid S. Miller 	args[3] = (unsigned int) cpunode;
405*25edd694SDavid S. Miller 	args[4] = pc;
406*25edd694SDavid S. Miller 	args[5] = arg;
407*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4085de18cdeSSam Ravnborg }
4095de18cdeSSam Ravnborg 
4105de18cdeSSam Ravnborg void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
4115de18cdeSSam Ravnborg {
412*25edd694SDavid S. Miller 	unsigned long args[6];
413*25edd694SDavid S. Miller 
414*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
415*25edd694SDavid S. Miller 	args[1] = 3;
416*25edd694SDavid S. Miller 	args[2] = 0;
417*25edd694SDavid S. Miller 	args[3] = (unsigned int) cpuid;
418*25edd694SDavid S. Miller 	args[4] = pc;
419*25edd694SDavid S. Miller 	args[5] = arg;
420*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4215de18cdeSSam Ravnborg }
4225de18cdeSSam Ravnborg 
4235de18cdeSSam Ravnborg void prom_stopcpu_cpuid(int cpuid)
4245de18cdeSSam Ravnborg {
425*25edd694SDavid S. Miller 	unsigned long args[4];
426*25edd694SDavid S. Miller 
427*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
428*25edd694SDavid S. Miller 	args[1] = 1;
429*25edd694SDavid S. Miller 	args[2] = 0;
430*25edd694SDavid S. Miller 	args[3] = (unsigned int) cpuid;
431*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4325de18cdeSSam Ravnborg }
4335de18cdeSSam Ravnborg 
4345de18cdeSSam Ravnborg void prom_stopself(void)
4355de18cdeSSam Ravnborg {
436*25edd694SDavid S. Miller 	unsigned long args[3];
437*25edd694SDavid S. Miller 
438*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,stop-self";
439*25edd694SDavid S. Miller 	args[1] = 0;
440*25edd694SDavid S. Miller 	args[2] = 0;
441*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4425de18cdeSSam Ravnborg }
4435de18cdeSSam Ravnborg 
4445de18cdeSSam Ravnborg void prom_idleself(void)
4455de18cdeSSam Ravnborg {
446*25edd694SDavid S. Miller 	unsigned long args[3];
447*25edd694SDavid S. Miller 
448*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,idle-self";
449*25edd694SDavid S. Miller 	args[1] = 0;
450*25edd694SDavid S. Miller 	args[2] = 0;
451*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4525de18cdeSSam Ravnborg }
4535de18cdeSSam Ravnborg 
4545de18cdeSSam Ravnborg void prom_resumecpu(int cpunode)
4555de18cdeSSam Ravnborg {
456*25edd694SDavid S. Miller 	unsigned long args[4];
457*25edd694SDavid S. Miller 
458*25edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,resume-cpu";
459*25edd694SDavid S. Miller 	args[1] = 1;
460*25edd694SDavid S. Miller 	args[2] = 0;
461*25edd694SDavid S. Miller 	args[3] = (unsigned int) cpunode;
462*25edd694SDavid S. Miller 	p1275_cmd_direct(args);
4635de18cdeSSam Ravnborg }
4645de18cdeSSam Ravnborg #endif
465