xref: /kernel/linux/linux-6.6/arch/sparc/prom/misc_64.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * misc.c:  Miscellaneous prom functions that don't belong
462306a36Sopenharmony_ci *          anywhere else.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
762306a36Sopenharmony_ci * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/sched.h>
1362306a36Sopenharmony_ci#include <linux/interrupt.h>
1462306a36Sopenharmony_ci#include <linux/delay.h>
1562306a36Sopenharmony_ci#include <linux/module.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <asm/openprom.h>
1862306a36Sopenharmony_ci#include <asm/oplib.h>
1962306a36Sopenharmony_ci#include <asm/ldc.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic int prom_service_exists(const char *service_name)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	unsigned long args[5];
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	args[0] = (unsigned long) "test";
2662306a36Sopenharmony_ci	args[1] = 1;
2762306a36Sopenharmony_ci	args[2] = 1;
2862306a36Sopenharmony_ci	args[3] = (unsigned long) service_name;
2962306a36Sopenharmony_ci	args[4] = (unsigned long) -1;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	p1275_cmd_direct(args);
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	if (args[4])
3462306a36Sopenharmony_ci		return 0;
3562306a36Sopenharmony_ci	return 1;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_civoid prom_sun4v_guest_soft_state(void)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	const char *svc = "SUNW,soft-state-supported";
4162306a36Sopenharmony_ci	unsigned long args[3];
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (!prom_service_exists(svc))
4462306a36Sopenharmony_ci		return;
4562306a36Sopenharmony_ci	args[0] = (unsigned long) svc;
4662306a36Sopenharmony_ci	args[1] = 0;
4762306a36Sopenharmony_ci	args[2] = 0;
4862306a36Sopenharmony_ci	p1275_cmd_direct(args);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* Reset and reboot the machine with the command 'bcommand'. */
5262306a36Sopenharmony_civoid prom_reboot(const char *bcommand)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	unsigned long args[4];
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS
5762306a36Sopenharmony_ci	if (ldom_domaining_enabled)
5862306a36Sopenharmony_ci		ldom_reboot(bcommand);
5962306a36Sopenharmony_ci#endif
6062306a36Sopenharmony_ci	args[0] = (unsigned long) "boot";
6162306a36Sopenharmony_ci	args[1] = 1;
6262306a36Sopenharmony_ci	args[2] = 0;
6362306a36Sopenharmony_ci	args[3] = (unsigned long) bcommand;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	p1275_cmd_direct(args);
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/* Forth evaluate the expression contained in 'fstring'. */
6962306a36Sopenharmony_civoid prom_feval(const char *fstring)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	unsigned long args[5];
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	if (!fstring || fstring[0] == 0)
7462306a36Sopenharmony_ci		return;
7562306a36Sopenharmony_ci	args[0] = (unsigned long) "interpret";
7662306a36Sopenharmony_ci	args[1] = 1;
7762306a36Sopenharmony_ci	args[2] = 1;
7862306a36Sopenharmony_ci	args[3] = (unsigned long) fstring;
7962306a36Sopenharmony_ci	args[4] = (unsigned long) -1;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	p1275_cmd_direct(args);
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ciEXPORT_SYMBOL(prom_feval);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/* Drop into the prom, with the chance to continue with the 'go'
8662306a36Sopenharmony_ci * prom command.
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_civoid prom_cmdline(void)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	unsigned long args[3];
9162306a36Sopenharmony_ci	unsigned long flags;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	local_irq_save(flags);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#ifdef CONFIG_SMP
9662306a36Sopenharmony_ci	smp_capture();
9762306a36Sopenharmony_ci#endif
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	args[0] = (unsigned long) "enter";
10062306a36Sopenharmony_ci	args[1] = 0;
10162306a36Sopenharmony_ci	args[2] = 0;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	p1275_cmd_direct(args);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#ifdef CONFIG_SMP
10662306a36Sopenharmony_ci	smp_release();
10762306a36Sopenharmony_ci#endif
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	local_irq_restore(flags);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/* Drop into the prom, but completely terminate the program.
11362306a36Sopenharmony_ci * No chance of continuing.
11462306a36Sopenharmony_ci */
11562306a36Sopenharmony_civoid notrace prom_halt(void)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	unsigned long args[3];
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS
12062306a36Sopenharmony_ci	if (ldom_domaining_enabled)
12162306a36Sopenharmony_ci		ldom_power_off();
12262306a36Sopenharmony_ci#endif
12362306a36Sopenharmony_ciagain:
12462306a36Sopenharmony_ci	args[0] = (unsigned long) "exit";
12562306a36Sopenharmony_ci	args[1] = 0;
12662306a36Sopenharmony_ci	args[2] = 0;
12762306a36Sopenharmony_ci	p1275_cmd_direct(args);
12862306a36Sopenharmony_ci	goto again; /* PROM is out to get me -DaveM */
12962306a36Sopenharmony_ci}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_civoid prom_halt_power_off(void)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	unsigned long args[3];
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS
13662306a36Sopenharmony_ci	if (ldom_domaining_enabled)
13762306a36Sopenharmony_ci		ldom_power_off();
13862306a36Sopenharmony_ci#endif
13962306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,power-off";
14062306a36Sopenharmony_ci	args[1] = 0;
14162306a36Sopenharmony_ci	args[2] = 0;
14262306a36Sopenharmony_ci	p1275_cmd_direct(args);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	/* if nothing else helps, we just halt */
14562306a36Sopenharmony_ci	prom_halt();
14662306a36Sopenharmony_ci}
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
14962306a36Sopenharmony_ci * format type.  'num_bytes' is the number of bytes that your idbuf
15062306a36Sopenharmony_ci * has space for.  Returns 0xff on error.
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_ciunsigned char prom_get_idprom(char *idbuf, int num_bytes)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	int len;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	len = prom_getproplen(prom_root_node, "idprom");
15762306a36Sopenharmony_ci	if ((len >num_bytes) || (len == -1))
15862306a36Sopenharmony_ci		return 0xff;
15962306a36Sopenharmony_ci	if (!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
16062306a36Sopenharmony_ci		return idbuf[0];
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci	return 0xff;
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ciint prom_get_mmu_ihandle(void)
16662306a36Sopenharmony_ci{
16762306a36Sopenharmony_ci	phandle node;
16862306a36Sopenharmony_ci	int ret;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	if (prom_mmu_ihandle_cache != 0)
17162306a36Sopenharmony_ci		return prom_mmu_ihandle_cache;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	node = prom_finddevice(prom_chosen_path);
17462306a36Sopenharmony_ci	ret = prom_getint(node, prom_mmu_name);
17562306a36Sopenharmony_ci	if (ret == -1 || ret == 0)
17662306a36Sopenharmony_ci		prom_mmu_ihandle_cache = -1;
17762306a36Sopenharmony_ci	else
17862306a36Sopenharmony_ci		prom_mmu_ihandle_cache = ret;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	return ret;
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic int prom_get_memory_ihandle(void)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	static int memory_ihandle_cache;
18662306a36Sopenharmony_ci	phandle node;
18762306a36Sopenharmony_ci	int ret;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	if (memory_ihandle_cache != 0)
19062306a36Sopenharmony_ci		return memory_ihandle_cache;
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci	node = prom_finddevice("/chosen");
19362306a36Sopenharmony_ci	ret = prom_getint(node, "memory");
19462306a36Sopenharmony_ci	if (ret == -1 || ret == 0)
19562306a36Sopenharmony_ci		memory_ihandle_cache = -1;
19662306a36Sopenharmony_ci	else
19762306a36Sopenharmony_ci		memory_ihandle_cache = ret;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return ret;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* Load explicit I/D TLB entries. */
20362306a36Sopenharmony_cistatic long tlb_load(const char *type, unsigned long index,
20462306a36Sopenharmony_ci		     unsigned long tte_data, unsigned long vaddr)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci	unsigned long args[9];
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	args[0] = (unsigned long) prom_callmethod_name;
20962306a36Sopenharmony_ci	args[1] = 5;
21062306a36Sopenharmony_ci	args[2] = 1;
21162306a36Sopenharmony_ci	args[3] = (unsigned long) type;
21262306a36Sopenharmony_ci	args[4] = (unsigned int) prom_get_mmu_ihandle();
21362306a36Sopenharmony_ci	args[5] = vaddr;
21462306a36Sopenharmony_ci	args[6] = tte_data;
21562306a36Sopenharmony_ci	args[7] = index;
21662306a36Sopenharmony_ci	args[8] = (unsigned long) -1;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	p1275_cmd_direct(args);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	return (long) args[8];
22162306a36Sopenharmony_ci}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cilong prom_itlb_load(unsigned long index,
22462306a36Sopenharmony_ci		    unsigned long tte_data,
22562306a36Sopenharmony_ci		    unsigned long vaddr)
22662306a36Sopenharmony_ci{
22762306a36Sopenharmony_ci	return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_cilong prom_dtlb_load(unsigned long index,
23162306a36Sopenharmony_ci		    unsigned long tte_data,
23262306a36Sopenharmony_ci		    unsigned long vaddr)
23362306a36Sopenharmony_ci{
23462306a36Sopenharmony_ci	return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
23562306a36Sopenharmony_ci}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ciint prom_map(int mode, unsigned long size,
23862306a36Sopenharmony_ci	     unsigned long vaddr, unsigned long paddr)
23962306a36Sopenharmony_ci{
24062306a36Sopenharmony_ci	unsigned long args[11];
24162306a36Sopenharmony_ci	int ret;
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	args[0] = (unsigned long) prom_callmethod_name;
24462306a36Sopenharmony_ci	args[1] = 7;
24562306a36Sopenharmony_ci	args[2] = 1;
24662306a36Sopenharmony_ci	args[3] = (unsigned long) prom_map_name;
24762306a36Sopenharmony_ci	args[4] = (unsigned int) prom_get_mmu_ihandle();
24862306a36Sopenharmony_ci	args[5] = (unsigned int) mode;
24962306a36Sopenharmony_ci	args[6] = size;
25062306a36Sopenharmony_ci	args[7] = vaddr;
25162306a36Sopenharmony_ci	args[8] = 0;
25262306a36Sopenharmony_ci	args[9] = paddr;
25362306a36Sopenharmony_ci	args[10] = (unsigned long) -1;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	p1275_cmd_direct(args);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	ret = (int) args[10];
25862306a36Sopenharmony_ci	if (ret == 0)
25962306a36Sopenharmony_ci		ret = -1;
26062306a36Sopenharmony_ci	return ret;
26162306a36Sopenharmony_ci}
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_civoid prom_unmap(unsigned long size, unsigned long vaddr)
26462306a36Sopenharmony_ci{
26562306a36Sopenharmony_ci	unsigned long args[7];
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	args[0] = (unsigned long) prom_callmethod_name;
26862306a36Sopenharmony_ci	args[1] = 4;
26962306a36Sopenharmony_ci	args[2] = 0;
27062306a36Sopenharmony_ci	args[3] = (unsigned long) prom_unmap_name;
27162306a36Sopenharmony_ci	args[4] = (unsigned int) prom_get_mmu_ihandle();
27262306a36Sopenharmony_ci	args[5] = size;
27362306a36Sopenharmony_ci	args[6] = vaddr;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	p1275_cmd_direct(args);
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci/* Set aside physical memory which is not touched or modified
27962306a36Sopenharmony_ci * across soft resets.
28062306a36Sopenharmony_ci */
28162306a36Sopenharmony_ciint prom_retain(const char *name, unsigned long size,
28262306a36Sopenharmony_ci		unsigned long align, unsigned long *paddr)
28362306a36Sopenharmony_ci{
28462306a36Sopenharmony_ci	unsigned long args[11];
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	args[0] = (unsigned long) prom_callmethod_name;
28762306a36Sopenharmony_ci	args[1] = 5;
28862306a36Sopenharmony_ci	args[2] = 3;
28962306a36Sopenharmony_ci	args[3] = (unsigned long) "SUNW,retain";
29062306a36Sopenharmony_ci	args[4] = (unsigned int) prom_get_memory_ihandle();
29162306a36Sopenharmony_ci	args[5] = align;
29262306a36Sopenharmony_ci	args[6] = size;
29362306a36Sopenharmony_ci	args[7] = (unsigned long) name;
29462306a36Sopenharmony_ci	args[8] = (unsigned long) -1;
29562306a36Sopenharmony_ci	args[9] = (unsigned long) -1;
29662306a36Sopenharmony_ci	args[10] = (unsigned long) -1;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	p1275_cmd_direct(args);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	if (args[8])
30162306a36Sopenharmony_ci		return (int) args[8];
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	/* Next we get "phys_high" then "phys_low".  On 64-bit
30462306a36Sopenharmony_ci	 * the phys_high cell is don't care since the phys_low
30562306a36Sopenharmony_ci	 * cell has the full value.
30662306a36Sopenharmony_ci	 */
30762306a36Sopenharmony_ci	*paddr = args[10];
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci	return 0;
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci/* Get "Unumber" string for the SIMM at the given
31362306a36Sopenharmony_ci * memory address.  Usually this will be of the form
31462306a36Sopenharmony_ci * "Uxxxx" where xxxx is a decimal number which is
31562306a36Sopenharmony_ci * etched into the motherboard next to the SIMM slot
31662306a36Sopenharmony_ci * in question.
31762306a36Sopenharmony_ci */
31862306a36Sopenharmony_ciint prom_getunumber(int syndrome_code,
31962306a36Sopenharmony_ci		    unsigned long phys_addr,
32062306a36Sopenharmony_ci		    char *buf, int buflen)
32162306a36Sopenharmony_ci{
32262306a36Sopenharmony_ci	unsigned long args[12];
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	args[0] = (unsigned long) prom_callmethod_name;
32562306a36Sopenharmony_ci	args[1] = 7;
32662306a36Sopenharmony_ci	args[2] = 2;
32762306a36Sopenharmony_ci	args[3] = (unsigned long) "SUNW,get-unumber";
32862306a36Sopenharmony_ci	args[4] = (unsigned int) prom_get_memory_ihandle();
32962306a36Sopenharmony_ci	args[5] = buflen;
33062306a36Sopenharmony_ci	args[6] = (unsigned long) buf;
33162306a36Sopenharmony_ci	args[7] = 0;
33262306a36Sopenharmony_ci	args[8] = phys_addr;
33362306a36Sopenharmony_ci	args[9] = (unsigned int) syndrome_code;
33462306a36Sopenharmony_ci	args[10] = (unsigned long) -1;
33562306a36Sopenharmony_ci	args[11] = (unsigned long) -1;
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ci	p1275_cmd_direct(args);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	return (int) args[10];
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci/* Power management extensions. */
34362306a36Sopenharmony_civoid prom_sleepself(void)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	unsigned long args[3];
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,sleep-self";
34862306a36Sopenharmony_ci	args[1] = 0;
34962306a36Sopenharmony_ci	args[2] = 0;
35062306a36Sopenharmony_ci	p1275_cmd_direct(args);
35162306a36Sopenharmony_ci}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ciint prom_sleepsystem(void)
35462306a36Sopenharmony_ci{
35562306a36Sopenharmony_ci	unsigned long args[4];
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,sleep-system";
35862306a36Sopenharmony_ci	args[1] = 0;
35962306a36Sopenharmony_ci	args[2] = 1;
36062306a36Sopenharmony_ci	args[3] = (unsigned long) -1;
36162306a36Sopenharmony_ci	p1275_cmd_direct(args);
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	return (int) args[3];
36462306a36Sopenharmony_ci}
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ciint prom_wakeupsystem(void)
36762306a36Sopenharmony_ci{
36862306a36Sopenharmony_ci	unsigned long args[4];
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,wakeup-system";
37162306a36Sopenharmony_ci	args[1] = 0;
37262306a36Sopenharmony_ci	args[2] = 1;
37362306a36Sopenharmony_ci	args[3] = (unsigned long) -1;
37462306a36Sopenharmony_ci	p1275_cmd_direct(args);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	return (int) args[3];
37762306a36Sopenharmony_ci}
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci#ifdef CONFIG_SMP
38062306a36Sopenharmony_civoid prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
38162306a36Sopenharmony_ci{
38262306a36Sopenharmony_ci	unsigned long args[6];
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,start-cpu";
38562306a36Sopenharmony_ci	args[1] = 3;
38662306a36Sopenharmony_ci	args[2] = 0;
38762306a36Sopenharmony_ci	args[3] = (unsigned int) cpunode;
38862306a36Sopenharmony_ci	args[4] = pc;
38962306a36Sopenharmony_ci	args[5] = arg;
39062306a36Sopenharmony_ci	p1275_cmd_direct(args);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_civoid prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
39462306a36Sopenharmony_ci{
39562306a36Sopenharmony_ci	unsigned long args[6];
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
39862306a36Sopenharmony_ci	args[1] = 3;
39962306a36Sopenharmony_ci	args[2] = 0;
40062306a36Sopenharmony_ci	args[3] = (unsigned int) cpuid;
40162306a36Sopenharmony_ci	args[4] = pc;
40262306a36Sopenharmony_ci	args[5] = arg;
40362306a36Sopenharmony_ci	p1275_cmd_direct(args);
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_civoid prom_stopcpu_cpuid(int cpuid)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	unsigned long args[4];
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
41162306a36Sopenharmony_ci	args[1] = 1;
41262306a36Sopenharmony_ci	args[2] = 0;
41362306a36Sopenharmony_ci	args[3] = (unsigned int) cpuid;
41462306a36Sopenharmony_ci	p1275_cmd_direct(args);
41562306a36Sopenharmony_ci}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_civoid prom_stopself(void)
41862306a36Sopenharmony_ci{
41962306a36Sopenharmony_ci	unsigned long args[3];
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,stop-self";
42262306a36Sopenharmony_ci	args[1] = 0;
42362306a36Sopenharmony_ci	args[2] = 0;
42462306a36Sopenharmony_ci	p1275_cmd_direct(args);
42562306a36Sopenharmony_ci}
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_civoid prom_idleself(void)
42862306a36Sopenharmony_ci{
42962306a36Sopenharmony_ci	unsigned long args[3];
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,idle-self";
43262306a36Sopenharmony_ci	args[1] = 0;
43362306a36Sopenharmony_ci	args[2] = 0;
43462306a36Sopenharmony_ci	p1275_cmd_direct(args);
43562306a36Sopenharmony_ci}
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_civoid prom_resumecpu(int cpunode)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	unsigned long args[4];
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	args[0] = (unsigned long) "SUNW,resume-cpu";
44262306a36Sopenharmony_ci	args[1] = 1;
44362306a36Sopenharmony_ci	args[2] = 0;
44462306a36Sopenharmony_ci	args[3] = (unsigned int) cpunode;
44562306a36Sopenharmony_ci	p1275_cmd_direct(args);
44662306a36Sopenharmony_ci}
44762306a36Sopenharmony_ci#endif
448