xref: /openbmc/linux/arch/sparc/prom/misc_64.c (revision f7b5f55ac1623dfde24ef5319ad77c1746645f3f)
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 
21*f7b5f55aSDavid S. Miller static int prom_service_exists(const char *service_name)
225de18cdeSSam Ravnborg {
2325edd694SDavid S. Miller 	unsigned long args[5];
245de18cdeSSam Ravnborg 
2525edd694SDavid S. Miller 	args[0] = (unsigned long) "test";
2625edd694SDavid S. Miller 	args[1] = 1;
2725edd694SDavid S. Miller 	args[2] = 1;
2825edd694SDavid S. Miller 	args[3] = (unsigned long) service_name;
2925edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
3025edd694SDavid S. Miller 
3125edd694SDavid S. Miller 	p1275_cmd_direct(args);
3225edd694SDavid S. Miller 
3325edd694SDavid 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";
4125edd694SDavid S. Miller 	unsigned long args[3];
425de18cdeSSam Ravnborg 
435de18cdeSSam Ravnborg 	if (!prom_service_exists(svc))
445de18cdeSSam Ravnborg 		return;
4525edd694SDavid S. Miller 	args[0] = (unsigned long) svc;
4625edd694SDavid S. Miller 	args[1] = 0;
4725edd694SDavid S. Miller 	args[2] = 0;
4825edd694SDavid 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 {
5425edd694SDavid S. Miller 	unsigned long args[4];
5525edd694SDavid S. Miller 
565de18cdeSSam Ravnborg #ifdef CONFIG_SUN_LDOMS
575de18cdeSSam Ravnborg 	if (ldom_domaining_enabled)
585de18cdeSSam Ravnborg 		ldom_reboot(bcommand);
595de18cdeSSam Ravnborg #endif
6025edd694SDavid S. Miller 	args[0] = (unsigned long) "boot";
6125edd694SDavid S. Miller 	args[1] = 1;
6225edd694SDavid S. Miller 	args[2] = 0;
6325edd694SDavid S. Miller 	args[3] = (unsigned long) bcommand;
6425edd694SDavid S. Miller 
6525edd694SDavid 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 {
7125edd694SDavid S. Miller 	unsigned long args[5];
7225edd694SDavid S. Miller 
735de18cdeSSam Ravnborg 	if (!fstring || fstring[0] == 0)
745de18cdeSSam Ravnborg 		return;
7525edd694SDavid S. Miller 	args[0] = (unsigned long) "interpret";
7625edd694SDavid S. Miller 	args[1] = 1;
7725edd694SDavid S. Miller 	args[2] = 1;
7825edd694SDavid S. Miller 	args[3] = (unsigned long) fstring;
7925edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
8025edd694SDavid S. Miller 
8125edd694SDavid 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 {
9525edd694SDavid 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 
10425edd694SDavid S. Miller 	args[0] = (unsigned long) "enter";
10525edd694SDavid S. Miller 	args[1] = 0;
10625edd694SDavid S. Miller 	args[2] = 0;
10725edd694SDavid S. Miller 
10825edd694SDavid 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 {
12225edd694SDavid S. Miller 	unsigned long args[3];
12325edd694SDavid 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:
12925edd694SDavid S. Miller 	args[0] = (unsigned long) "exit";
13025edd694SDavid S. Miller 	args[1] = 0;
13125edd694SDavid S. Miller 	args[2] = 0;
13225edd694SDavid 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 {
13825edd694SDavid S. Miller 	unsigned long args[3];
13925edd694SDavid S. Miller 
1405de18cdeSSam Ravnborg #ifdef CONFIG_SUN_LDOMS
1415de18cdeSSam Ravnborg 	if (ldom_domaining_enabled)
1425de18cdeSSam Ravnborg 		ldom_power_off();
1435de18cdeSSam Ravnborg #endif
14425edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,power-off";
14525edd694SDavid S. Miller 	args[1] = 0;
14625edd694SDavid S. Miller 	args[2] = 0;
14725edd694SDavid 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 {
15625edd694SDavid S. Miller 	unsigned long args[5];
1575de18cdeSSam Ravnborg 	if (!funcp)
1585de18cdeSSam Ravnborg 		return;
15925edd694SDavid S. Miller 	args[0] = (unsigned long) "set-callback";
16025edd694SDavid S. Miller 	args[1] = 1;
16125edd694SDavid S. Miller 	args[2] = 1;
16225edd694SDavid S. Miller 	args[3] = (unsigned long) funcp;
16325edd694SDavid S. Miller 	args[4] = (unsigned long) -1;
16425edd694SDavid 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 {
1868d125562SAndres Salomon 	phandle node;
1878d125562SAndres Salomon 	int ret;
1885de18cdeSSam Ravnborg 
1895de18cdeSSam Ravnborg 	if (prom_mmu_ihandle_cache != 0)
1905de18cdeSSam Ravnborg 		return prom_mmu_ihandle_cache;
1915de18cdeSSam Ravnborg 
1925de18cdeSSam Ravnborg 	node = prom_finddevice(prom_chosen_path);
1935de18cdeSSam Ravnborg 	ret = prom_getint(node, prom_mmu_name);
1945de18cdeSSam Ravnborg 	if (ret == -1 || ret == 0)
1955de18cdeSSam Ravnborg 		prom_mmu_ihandle_cache = -1;
1965de18cdeSSam Ravnborg 	else
1975de18cdeSSam Ravnborg 		prom_mmu_ihandle_cache = ret;
1985de18cdeSSam Ravnborg 
1995de18cdeSSam Ravnborg 	return ret;
2005de18cdeSSam Ravnborg }
2015de18cdeSSam Ravnborg 
2025de18cdeSSam Ravnborg static int prom_get_memory_ihandle(void)
2035de18cdeSSam Ravnborg {
2045de18cdeSSam Ravnborg 	static int memory_ihandle_cache;
2058d125562SAndres Salomon 	phandle node;
2068d125562SAndres Salomon 	int ret;
2075de18cdeSSam Ravnborg 
2085de18cdeSSam Ravnborg 	if (memory_ihandle_cache != 0)
2095de18cdeSSam Ravnborg 		return memory_ihandle_cache;
2105de18cdeSSam Ravnborg 
2115de18cdeSSam Ravnborg 	node = prom_finddevice("/chosen");
2125de18cdeSSam Ravnborg 	ret = prom_getint(node, "memory");
2135de18cdeSSam Ravnborg 	if (ret == -1 || ret == 0)
2145de18cdeSSam Ravnborg 		memory_ihandle_cache = -1;
2155de18cdeSSam Ravnborg 	else
2165de18cdeSSam Ravnborg 		memory_ihandle_cache = ret;
2175de18cdeSSam Ravnborg 
2185de18cdeSSam Ravnborg 	return ret;
2195de18cdeSSam Ravnborg }
2205de18cdeSSam Ravnborg 
2215de18cdeSSam Ravnborg /* Load explicit I/D TLB entries. */
22225edd694SDavid S. Miller static long tlb_load(const char *type, unsigned long index,
22325edd694SDavid S. Miller 		     unsigned long tte_data, unsigned long vaddr)
22425edd694SDavid S. Miller {
22525edd694SDavid S. Miller 	unsigned long args[9];
22625edd694SDavid S. Miller 
22725edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
22825edd694SDavid S. Miller 	args[1] = 5;
22925edd694SDavid S. Miller 	args[2] = 1;
23025edd694SDavid S. Miller 	args[3] = (unsigned long) type;
23125edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
23225edd694SDavid S. Miller 	args[5] = vaddr;
23325edd694SDavid S. Miller 	args[6] = tte_data;
23425edd694SDavid S. Miller 	args[7] = index;
23525edd694SDavid S. Miller 	args[8] = (unsigned long) -1;
23625edd694SDavid S. Miller 
23725edd694SDavid S. Miller 	p1275_cmd_direct(args);
23825edd694SDavid S. Miller 
23925edd694SDavid S. Miller 	return (long) args[8];
24025edd694SDavid S. Miller }
24125edd694SDavid S. Miller 
2425de18cdeSSam Ravnborg long prom_itlb_load(unsigned long index,
2435de18cdeSSam Ravnborg 		    unsigned long tte_data,
2445de18cdeSSam Ravnborg 		    unsigned long vaddr)
2455de18cdeSSam Ravnborg {
24625edd694SDavid S. Miller 	return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
2475de18cdeSSam Ravnborg }
2485de18cdeSSam Ravnborg 
2495de18cdeSSam Ravnborg long prom_dtlb_load(unsigned long index,
2505de18cdeSSam Ravnborg 		    unsigned long tte_data,
2515de18cdeSSam Ravnborg 		    unsigned long vaddr)
2525de18cdeSSam Ravnborg {
25325edd694SDavid S. Miller 	return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
2545de18cdeSSam Ravnborg }
2555de18cdeSSam Ravnborg 
2565de18cdeSSam Ravnborg int prom_map(int mode, unsigned long size,
2575de18cdeSSam Ravnborg 	     unsigned long vaddr, unsigned long paddr)
2585de18cdeSSam Ravnborg {
25925edd694SDavid S. Miller 	unsigned long args[11];
26025edd694SDavid S. Miller 	int ret;
2615de18cdeSSam Ravnborg 
26225edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
26325edd694SDavid S. Miller 	args[1] = 7;
26425edd694SDavid S. Miller 	args[2] = 1;
26525edd694SDavid S. Miller 	args[3] = (unsigned long) prom_map_name;
26625edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
26725edd694SDavid S. Miller 	args[5] = (unsigned int) mode;
26825edd694SDavid S. Miller 	args[6] = size;
26925edd694SDavid S. Miller 	args[7] = vaddr;
27025edd694SDavid S. Miller 	args[8] = 0;
27125edd694SDavid S. Miller 	args[9] = paddr;
27225edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
27325edd694SDavid S. Miller 
27425edd694SDavid S. Miller 	p1275_cmd_direct(args);
27525edd694SDavid S. Miller 
27625edd694SDavid S. Miller 	ret = (int) args[10];
2775de18cdeSSam Ravnborg 	if (ret == 0)
2785de18cdeSSam Ravnborg 		ret = -1;
2795de18cdeSSam Ravnborg 	return ret;
2805de18cdeSSam Ravnborg }
2815de18cdeSSam Ravnborg 
2825de18cdeSSam Ravnborg void prom_unmap(unsigned long size, unsigned long vaddr)
2835de18cdeSSam Ravnborg {
28425edd694SDavid S. Miller 	unsigned long args[7];
28525edd694SDavid S. Miller 
28625edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
28725edd694SDavid S. Miller 	args[1] = 4;
28825edd694SDavid S. Miller 	args[2] = 0;
28925edd694SDavid S. Miller 	args[3] = (unsigned long) prom_unmap_name;
29025edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_mmu_ihandle();
29125edd694SDavid S. Miller 	args[5] = size;
29225edd694SDavid S. Miller 	args[6] = vaddr;
29325edd694SDavid S. Miller 
29425edd694SDavid S. Miller 	p1275_cmd_direct(args);
2955de18cdeSSam Ravnborg }
2965de18cdeSSam Ravnborg 
2975de18cdeSSam Ravnborg /* Set aside physical memory which is not touched or modified
2985de18cdeSSam Ravnborg  * across soft resets.
2995de18cdeSSam Ravnborg  */
30025edd694SDavid S. Miller int prom_retain(const char *name, unsigned long size,
30125edd694SDavid S. Miller 		unsigned long align, unsigned long *paddr)
3025de18cdeSSam Ravnborg {
30325edd694SDavid S. Miller 	unsigned long args[11];
3045de18cdeSSam Ravnborg 
30525edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
30625edd694SDavid S. Miller 	args[1] = 5;
30725edd694SDavid S. Miller 	args[2] = 3;
30825edd694SDavid S. Miller 	args[3] = (unsigned long) "SUNW,retain";
30925edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_memory_ihandle();
31025edd694SDavid S. Miller 	args[5] = align;
31125edd694SDavid S. Miller 	args[6] = size;
31225edd694SDavid S. Miller 	args[7] = (unsigned long) name;
31325edd694SDavid S. Miller 	args[8] = (unsigned long) -1;
31425edd694SDavid S. Miller 	args[9] = (unsigned long) -1;
31525edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
31625edd694SDavid S. Miller 
31725edd694SDavid S. Miller 	p1275_cmd_direct(args);
31825edd694SDavid S. Miller 
31925edd694SDavid S. Miller 	if (args[8])
32025edd694SDavid S. Miller 		return (int) args[8];
32125edd694SDavid S. Miller 
32225edd694SDavid S. Miller 	/* Next we get "phys_high" then "phys_low".  On 64-bit
32325edd694SDavid S. Miller 	 * the phys_high cell is don't care since the phys_low
32425edd694SDavid S. Miller 	 * cell has the full value.
3255de18cdeSSam Ravnborg 	 */
32625edd694SDavid S. Miller 	*paddr = args[10];
32725edd694SDavid S. Miller 
32825edd694SDavid S. Miller 	return 0;
3295de18cdeSSam Ravnborg }
3305de18cdeSSam Ravnborg 
3315de18cdeSSam Ravnborg /* Get "Unumber" string for the SIMM at the given
3325de18cdeSSam Ravnborg  * memory address.  Usually this will be of the form
3335de18cdeSSam Ravnborg  * "Uxxxx" where xxxx is a decimal number which is
3345de18cdeSSam Ravnborg  * etched into the motherboard next to the SIMM slot
3355de18cdeSSam Ravnborg  * in question.
3365de18cdeSSam Ravnborg  */
3375de18cdeSSam Ravnborg int prom_getunumber(int syndrome_code,
3385de18cdeSSam Ravnborg 		    unsigned long phys_addr,
3395de18cdeSSam Ravnborg 		    char *buf, int buflen)
3405de18cdeSSam Ravnborg {
34125edd694SDavid S. Miller 	unsigned long args[12];
34225edd694SDavid S. Miller 
34325edd694SDavid S. Miller 	args[0] = (unsigned long) prom_callmethod_name;
34425edd694SDavid S. Miller 	args[1] = 7;
34525edd694SDavid S. Miller 	args[2] = 2;
34625edd694SDavid S. Miller 	args[3] = (unsigned long) "SUNW,get-unumber";
34725edd694SDavid S. Miller 	args[4] = (unsigned int) prom_get_memory_ihandle();
34825edd694SDavid S. Miller 	args[5] = buflen;
34925edd694SDavid S. Miller 	args[6] = (unsigned long) buf;
35025edd694SDavid S. Miller 	args[7] = 0;
35125edd694SDavid S. Miller 	args[8] = phys_addr;
35225edd694SDavid S. Miller 	args[9] = (unsigned int) syndrome_code;
35325edd694SDavid S. Miller 	args[10] = (unsigned long) -1;
35425edd694SDavid S. Miller 	args[11] = (unsigned long) -1;
35525edd694SDavid S. Miller 
35625edd694SDavid S. Miller 	p1275_cmd_direct(args);
35725edd694SDavid S. Miller 
35825edd694SDavid S. Miller 	return (int) args[10];
3595de18cdeSSam Ravnborg }
3605de18cdeSSam Ravnborg 
3615de18cdeSSam Ravnborg /* Power management extensions. */
3625de18cdeSSam Ravnborg void prom_sleepself(void)
3635de18cdeSSam Ravnborg {
36425edd694SDavid S. Miller 	unsigned long args[3];
36525edd694SDavid S. Miller 
36625edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,sleep-self";
36725edd694SDavid S. Miller 	args[1] = 0;
36825edd694SDavid S. Miller 	args[2] = 0;
36925edd694SDavid S. Miller 	p1275_cmd_direct(args);
3705de18cdeSSam Ravnborg }
3715de18cdeSSam Ravnborg 
3725de18cdeSSam Ravnborg int prom_sleepsystem(void)
3735de18cdeSSam Ravnborg {
37425edd694SDavid S. Miller 	unsigned long args[4];
37525edd694SDavid S. Miller 
37625edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,sleep-system";
37725edd694SDavid S. Miller 	args[1] = 0;
37825edd694SDavid S. Miller 	args[2] = 1;
37925edd694SDavid S. Miller 	args[3] = (unsigned long) -1;
38025edd694SDavid S. Miller 	p1275_cmd_direct(args);
38125edd694SDavid S. Miller 
38225edd694SDavid S. Miller 	return (int) args[3];
3835de18cdeSSam Ravnborg }
3845de18cdeSSam Ravnborg 
3855de18cdeSSam Ravnborg int prom_wakeupsystem(void)
3865de18cdeSSam Ravnborg {
38725edd694SDavid S. Miller 	unsigned long args[4];
38825edd694SDavid S. Miller 
38925edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,wakeup-system";
39025edd694SDavid S. Miller 	args[1] = 0;
39125edd694SDavid S. Miller 	args[2] = 1;
39225edd694SDavid S. Miller 	args[3] = (unsigned long) -1;
39325edd694SDavid S. Miller 	p1275_cmd_direct(args);
39425edd694SDavid S. Miller 
39525edd694SDavid S. Miller 	return (int) args[3];
3965de18cdeSSam Ravnborg }
3975de18cdeSSam Ravnborg 
3985de18cdeSSam Ravnborg #ifdef CONFIG_SMP
3995de18cdeSSam Ravnborg void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
4005de18cdeSSam Ravnborg {
40125edd694SDavid S. Miller 	unsigned long args[6];
40225edd694SDavid S. Miller 
40325edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,start-cpu";
40425edd694SDavid S. Miller 	args[1] = 3;
40525edd694SDavid S. Miller 	args[2] = 0;
40625edd694SDavid S. Miller 	args[3] = (unsigned int) cpunode;
40725edd694SDavid S. Miller 	args[4] = pc;
40825edd694SDavid S. Miller 	args[5] = arg;
40925edd694SDavid S. Miller 	p1275_cmd_direct(args);
4105de18cdeSSam Ravnborg }
4115de18cdeSSam Ravnborg 
4125de18cdeSSam Ravnborg void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
4135de18cdeSSam Ravnborg {
41425edd694SDavid S. Miller 	unsigned long args[6];
41525edd694SDavid S. Miller 
41625edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
41725edd694SDavid S. Miller 	args[1] = 3;
41825edd694SDavid S. Miller 	args[2] = 0;
41925edd694SDavid S. Miller 	args[3] = (unsigned int) cpuid;
42025edd694SDavid S. Miller 	args[4] = pc;
42125edd694SDavid S. Miller 	args[5] = arg;
42225edd694SDavid S. Miller 	p1275_cmd_direct(args);
4235de18cdeSSam Ravnborg }
4245de18cdeSSam Ravnborg 
4255de18cdeSSam Ravnborg void prom_stopcpu_cpuid(int cpuid)
4265de18cdeSSam Ravnborg {
42725edd694SDavid S. Miller 	unsigned long args[4];
42825edd694SDavid S. Miller 
42925edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
43025edd694SDavid S. Miller 	args[1] = 1;
43125edd694SDavid S. Miller 	args[2] = 0;
43225edd694SDavid S. Miller 	args[3] = (unsigned int) cpuid;
43325edd694SDavid S. Miller 	p1275_cmd_direct(args);
4345de18cdeSSam Ravnborg }
4355de18cdeSSam Ravnborg 
4365de18cdeSSam Ravnborg void prom_stopself(void)
4375de18cdeSSam Ravnborg {
43825edd694SDavid S. Miller 	unsigned long args[3];
43925edd694SDavid S. Miller 
44025edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,stop-self";
44125edd694SDavid S. Miller 	args[1] = 0;
44225edd694SDavid S. Miller 	args[2] = 0;
44325edd694SDavid S. Miller 	p1275_cmd_direct(args);
4445de18cdeSSam Ravnborg }
4455de18cdeSSam Ravnborg 
4465de18cdeSSam Ravnborg void prom_idleself(void)
4475de18cdeSSam Ravnborg {
44825edd694SDavid S. Miller 	unsigned long args[3];
44925edd694SDavid S. Miller 
45025edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,idle-self";
45125edd694SDavid S. Miller 	args[1] = 0;
45225edd694SDavid S. Miller 	args[2] = 0;
45325edd694SDavid S. Miller 	p1275_cmd_direct(args);
4545de18cdeSSam Ravnborg }
4555de18cdeSSam Ravnborg 
4565de18cdeSSam Ravnborg void prom_resumecpu(int cpunode)
4575de18cdeSSam Ravnborg {
45825edd694SDavid S. Miller 	unsigned long args[4];
45925edd694SDavid S. Miller 
46025edd694SDavid S. Miller 	args[0] = (unsigned long) "SUNW,resume-cpu";
46125edd694SDavid S. Miller 	args[1] = 1;
46225edd694SDavid S. Miller 	args[2] = 0;
46325edd694SDavid S. Miller 	args[3] = (unsigned int) cpunode;
46425edd694SDavid S. Miller 	p1275_cmd_direct(args);
4655de18cdeSSam Ravnborg }
4665de18cdeSSam Ravnborg #endif
467