18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * misc.c: Miscellaneous prom functions that don't belong 48c2ecf20Sopenharmony_ci * anywhere else. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 78c2ecf20Sopenharmony_ci * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/types.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/sched.h> 138c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 148c2ecf20Sopenharmony_ci#include <linux/delay.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <asm/openprom.h> 188c2ecf20Sopenharmony_ci#include <asm/oplib.h> 198c2ecf20Sopenharmony_ci#include <asm/ldc.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic int prom_service_exists(const char *service_name) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci unsigned long args[5]; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci args[0] = (unsigned long) "test"; 268c2ecf20Sopenharmony_ci args[1] = 1; 278c2ecf20Sopenharmony_ci args[2] = 1; 288c2ecf20Sopenharmony_ci args[3] = (unsigned long) service_name; 298c2ecf20Sopenharmony_ci args[4] = (unsigned long) -1; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci if (args[4]) 348c2ecf20Sopenharmony_ci return 0; 358c2ecf20Sopenharmony_ci return 1; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_civoid prom_sun4v_guest_soft_state(void) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci const char *svc = "SUNW,soft-state-supported"; 418c2ecf20Sopenharmony_ci unsigned long args[3]; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (!prom_service_exists(svc)) 448c2ecf20Sopenharmony_ci return; 458c2ecf20Sopenharmony_ci args[0] = (unsigned long) svc; 468c2ecf20Sopenharmony_ci args[1] = 0; 478c2ecf20Sopenharmony_ci args[2] = 0; 488c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/* Reset and reboot the machine with the command 'bcommand'. */ 528c2ecf20Sopenharmony_civoid prom_reboot(const char *bcommand) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci unsigned long args[4]; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS 578c2ecf20Sopenharmony_ci if (ldom_domaining_enabled) 588c2ecf20Sopenharmony_ci ldom_reboot(bcommand); 598c2ecf20Sopenharmony_ci#endif 608c2ecf20Sopenharmony_ci args[0] = (unsigned long) "boot"; 618c2ecf20Sopenharmony_ci args[1] = 1; 628c2ecf20Sopenharmony_ci args[2] = 0; 638c2ecf20Sopenharmony_ci args[3] = (unsigned long) bcommand; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* Forth evaluate the expression contained in 'fstring'. */ 698c2ecf20Sopenharmony_civoid prom_feval(const char *fstring) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci unsigned long args[5]; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci if (!fstring || fstring[0] == 0) 748c2ecf20Sopenharmony_ci return; 758c2ecf20Sopenharmony_ci args[0] = (unsigned long) "interpret"; 768c2ecf20Sopenharmony_ci args[1] = 1; 778c2ecf20Sopenharmony_ci args[2] = 1; 788c2ecf20Sopenharmony_ci args[3] = (unsigned long) fstring; 798c2ecf20Sopenharmony_ci args[4] = (unsigned long) -1; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ciEXPORT_SYMBOL(prom_feval); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci/* Drop into the prom, with the chance to continue with the 'go' 868c2ecf20Sopenharmony_ci * prom command. 878c2ecf20Sopenharmony_ci */ 888c2ecf20Sopenharmony_civoid prom_cmdline(void) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci unsigned long args[3]; 918c2ecf20Sopenharmony_ci unsigned long flags; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci local_irq_save(flags); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 968c2ecf20Sopenharmony_ci smp_capture(); 978c2ecf20Sopenharmony_ci#endif 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci args[0] = (unsigned long) "enter"; 1008c2ecf20Sopenharmony_ci args[1] = 0; 1018c2ecf20Sopenharmony_ci args[2] = 0; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1068c2ecf20Sopenharmony_ci smp_release(); 1078c2ecf20Sopenharmony_ci#endif 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci local_irq_restore(flags); 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/* Drop into the prom, but completely terminate the program. 1138c2ecf20Sopenharmony_ci * No chance of continuing. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_civoid notrace prom_halt(void) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci unsigned long args[3]; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS 1208c2ecf20Sopenharmony_ci if (ldom_domaining_enabled) 1218c2ecf20Sopenharmony_ci ldom_power_off(); 1228c2ecf20Sopenharmony_ci#endif 1238c2ecf20Sopenharmony_ciagain: 1248c2ecf20Sopenharmony_ci args[0] = (unsigned long) "exit"; 1258c2ecf20Sopenharmony_ci args[1] = 0; 1268c2ecf20Sopenharmony_ci args[2] = 0; 1278c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 1288c2ecf20Sopenharmony_ci goto again; /* PROM is out to get me -DaveM */ 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_civoid prom_halt_power_off(void) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci unsigned long args[3]; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#ifdef CONFIG_SUN_LDOMS 1368c2ecf20Sopenharmony_ci if (ldom_domaining_enabled) 1378c2ecf20Sopenharmony_ci ldom_power_off(); 1388c2ecf20Sopenharmony_ci#endif 1398c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,power-off"; 1408c2ecf20Sopenharmony_ci args[1] = 0; 1418c2ecf20Sopenharmony_ci args[2] = 0; 1428c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci /* if nothing else helps, we just halt */ 1458c2ecf20Sopenharmony_ci prom_halt(); 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* Get the idprom and stuff it into buffer 'idbuf'. Returns the 1498c2ecf20Sopenharmony_ci * format type. 'num_bytes' is the number of bytes that your idbuf 1508c2ecf20Sopenharmony_ci * has space for. Returns 0xff on error. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_ciunsigned char prom_get_idprom(char *idbuf, int num_bytes) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci int len; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci len = prom_getproplen(prom_root_node, "idprom"); 1578c2ecf20Sopenharmony_ci if ((len >num_bytes) || (len == -1)) 1588c2ecf20Sopenharmony_ci return 0xff; 1598c2ecf20Sopenharmony_ci if (!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes)) 1608c2ecf20Sopenharmony_ci return idbuf[0]; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci return 0xff; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciint prom_get_mmu_ihandle(void) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci phandle node; 1688c2ecf20Sopenharmony_ci int ret; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci if (prom_mmu_ihandle_cache != 0) 1718c2ecf20Sopenharmony_ci return prom_mmu_ihandle_cache; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci node = prom_finddevice(prom_chosen_path); 1748c2ecf20Sopenharmony_ci ret = prom_getint(node, prom_mmu_name); 1758c2ecf20Sopenharmony_ci if (ret == -1 || ret == 0) 1768c2ecf20Sopenharmony_ci prom_mmu_ihandle_cache = -1; 1778c2ecf20Sopenharmony_ci else 1788c2ecf20Sopenharmony_ci prom_mmu_ihandle_cache = ret; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci return ret; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic int prom_get_memory_ihandle(void) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci static int memory_ihandle_cache; 1868c2ecf20Sopenharmony_ci phandle node; 1878c2ecf20Sopenharmony_ci int ret; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci if (memory_ihandle_cache != 0) 1908c2ecf20Sopenharmony_ci return memory_ihandle_cache; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci node = prom_finddevice("/chosen"); 1938c2ecf20Sopenharmony_ci ret = prom_getint(node, "memory"); 1948c2ecf20Sopenharmony_ci if (ret == -1 || ret == 0) 1958c2ecf20Sopenharmony_ci memory_ihandle_cache = -1; 1968c2ecf20Sopenharmony_ci else 1978c2ecf20Sopenharmony_ci memory_ihandle_cache = ret; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci return ret; 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci/* Load explicit I/D TLB entries. */ 2038c2ecf20Sopenharmony_cistatic long tlb_load(const char *type, unsigned long index, 2048c2ecf20Sopenharmony_ci unsigned long tte_data, unsigned long vaddr) 2058c2ecf20Sopenharmony_ci{ 2068c2ecf20Sopenharmony_ci unsigned long args[9]; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci args[0] = (unsigned long) prom_callmethod_name; 2098c2ecf20Sopenharmony_ci args[1] = 5; 2108c2ecf20Sopenharmony_ci args[2] = 1; 2118c2ecf20Sopenharmony_ci args[3] = (unsigned long) type; 2128c2ecf20Sopenharmony_ci args[4] = (unsigned int) prom_get_mmu_ihandle(); 2138c2ecf20Sopenharmony_ci args[5] = vaddr; 2148c2ecf20Sopenharmony_ci args[6] = tte_data; 2158c2ecf20Sopenharmony_ci args[7] = index; 2168c2ecf20Sopenharmony_ci args[8] = (unsigned long) -1; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci return (long) args[8]; 2218c2ecf20Sopenharmony_ci} 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_cilong prom_itlb_load(unsigned long index, 2248c2ecf20Sopenharmony_ci unsigned long tte_data, 2258c2ecf20Sopenharmony_ci unsigned long vaddr) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci return tlb_load("SUNW,itlb-load", index, tte_data, vaddr); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cilong prom_dtlb_load(unsigned long index, 2318c2ecf20Sopenharmony_ci unsigned long tte_data, 2328c2ecf20Sopenharmony_ci unsigned long vaddr) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr); 2358c2ecf20Sopenharmony_ci} 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ciint prom_map(int mode, unsigned long size, 2388c2ecf20Sopenharmony_ci unsigned long vaddr, unsigned long paddr) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci unsigned long args[11]; 2418c2ecf20Sopenharmony_ci int ret; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci args[0] = (unsigned long) prom_callmethod_name; 2448c2ecf20Sopenharmony_ci args[1] = 7; 2458c2ecf20Sopenharmony_ci args[2] = 1; 2468c2ecf20Sopenharmony_ci args[3] = (unsigned long) prom_map_name; 2478c2ecf20Sopenharmony_ci args[4] = (unsigned int) prom_get_mmu_ihandle(); 2488c2ecf20Sopenharmony_ci args[5] = (unsigned int) mode; 2498c2ecf20Sopenharmony_ci args[6] = size; 2508c2ecf20Sopenharmony_ci args[7] = vaddr; 2518c2ecf20Sopenharmony_ci args[8] = 0; 2528c2ecf20Sopenharmony_ci args[9] = paddr; 2538c2ecf20Sopenharmony_ci args[10] = (unsigned long) -1; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci ret = (int) args[10]; 2588c2ecf20Sopenharmony_ci if (ret == 0) 2598c2ecf20Sopenharmony_ci ret = -1; 2608c2ecf20Sopenharmony_ci return ret; 2618c2ecf20Sopenharmony_ci} 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_civoid prom_unmap(unsigned long size, unsigned long vaddr) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci unsigned long args[7]; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci args[0] = (unsigned long) prom_callmethod_name; 2688c2ecf20Sopenharmony_ci args[1] = 4; 2698c2ecf20Sopenharmony_ci args[2] = 0; 2708c2ecf20Sopenharmony_ci args[3] = (unsigned long) prom_unmap_name; 2718c2ecf20Sopenharmony_ci args[4] = (unsigned int) prom_get_mmu_ihandle(); 2728c2ecf20Sopenharmony_ci args[5] = size; 2738c2ecf20Sopenharmony_ci args[6] = vaddr; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* Set aside physical memory which is not touched or modified 2798c2ecf20Sopenharmony_ci * across soft resets. 2808c2ecf20Sopenharmony_ci */ 2818c2ecf20Sopenharmony_ciint prom_retain(const char *name, unsigned long size, 2828c2ecf20Sopenharmony_ci unsigned long align, unsigned long *paddr) 2838c2ecf20Sopenharmony_ci{ 2848c2ecf20Sopenharmony_ci unsigned long args[11]; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci args[0] = (unsigned long) prom_callmethod_name; 2878c2ecf20Sopenharmony_ci args[1] = 5; 2888c2ecf20Sopenharmony_ci args[2] = 3; 2898c2ecf20Sopenharmony_ci args[3] = (unsigned long) "SUNW,retain"; 2908c2ecf20Sopenharmony_ci args[4] = (unsigned int) prom_get_memory_ihandle(); 2918c2ecf20Sopenharmony_ci args[5] = align; 2928c2ecf20Sopenharmony_ci args[6] = size; 2938c2ecf20Sopenharmony_ci args[7] = (unsigned long) name; 2948c2ecf20Sopenharmony_ci args[8] = (unsigned long) -1; 2958c2ecf20Sopenharmony_ci args[9] = (unsigned long) -1; 2968c2ecf20Sopenharmony_ci args[10] = (unsigned long) -1; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci if (args[8]) 3018c2ecf20Sopenharmony_ci return (int) args[8]; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* Next we get "phys_high" then "phys_low". On 64-bit 3048c2ecf20Sopenharmony_ci * the phys_high cell is don't care since the phys_low 3058c2ecf20Sopenharmony_ci * cell has the full value. 3068c2ecf20Sopenharmony_ci */ 3078c2ecf20Sopenharmony_ci *paddr = args[10]; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci return 0; 3108c2ecf20Sopenharmony_ci} 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci/* Get "Unumber" string for the SIMM at the given 3138c2ecf20Sopenharmony_ci * memory address. Usually this will be of the form 3148c2ecf20Sopenharmony_ci * "Uxxxx" where xxxx is a decimal number which is 3158c2ecf20Sopenharmony_ci * etched into the motherboard next to the SIMM slot 3168c2ecf20Sopenharmony_ci * in question. 3178c2ecf20Sopenharmony_ci */ 3188c2ecf20Sopenharmony_ciint prom_getunumber(int syndrome_code, 3198c2ecf20Sopenharmony_ci unsigned long phys_addr, 3208c2ecf20Sopenharmony_ci char *buf, int buflen) 3218c2ecf20Sopenharmony_ci{ 3228c2ecf20Sopenharmony_ci unsigned long args[12]; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci args[0] = (unsigned long) prom_callmethod_name; 3258c2ecf20Sopenharmony_ci args[1] = 7; 3268c2ecf20Sopenharmony_ci args[2] = 2; 3278c2ecf20Sopenharmony_ci args[3] = (unsigned long) "SUNW,get-unumber"; 3288c2ecf20Sopenharmony_ci args[4] = (unsigned int) prom_get_memory_ihandle(); 3298c2ecf20Sopenharmony_ci args[5] = buflen; 3308c2ecf20Sopenharmony_ci args[6] = (unsigned long) buf; 3318c2ecf20Sopenharmony_ci args[7] = 0; 3328c2ecf20Sopenharmony_ci args[8] = phys_addr; 3338c2ecf20Sopenharmony_ci args[9] = (unsigned int) syndrome_code; 3348c2ecf20Sopenharmony_ci args[10] = (unsigned long) -1; 3358c2ecf20Sopenharmony_ci args[11] = (unsigned long) -1; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci return (int) args[10]; 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci/* Power management extensions. */ 3438c2ecf20Sopenharmony_civoid prom_sleepself(void) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci unsigned long args[3]; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,sleep-self"; 3488c2ecf20Sopenharmony_ci args[1] = 0; 3498c2ecf20Sopenharmony_ci args[2] = 0; 3508c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ciint prom_sleepsystem(void) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci unsigned long args[4]; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,sleep-system"; 3588c2ecf20Sopenharmony_ci args[1] = 0; 3598c2ecf20Sopenharmony_ci args[2] = 1; 3608c2ecf20Sopenharmony_ci args[3] = (unsigned long) -1; 3618c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ci return (int) args[3]; 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ciint prom_wakeupsystem(void) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci unsigned long args[4]; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,wakeup-system"; 3718c2ecf20Sopenharmony_ci args[1] = 0; 3728c2ecf20Sopenharmony_ci args[2] = 1; 3738c2ecf20Sopenharmony_ci args[3] = (unsigned long) -1; 3748c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci return (int) args[3]; 3778c2ecf20Sopenharmony_ci} 3788c2ecf20Sopenharmony_ci 3798c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 3808c2ecf20Sopenharmony_civoid prom_startcpu(int cpunode, unsigned long pc, unsigned long arg) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci unsigned long args[6]; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,start-cpu"; 3858c2ecf20Sopenharmony_ci args[1] = 3; 3868c2ecf20Sopenharmony_ci args[2] = 0; 3878c2ecf20Sopenharmony_ci args[3] = (unsigned int) cpunode; 3888c2ecf20Sopenharmony_ci args[4] = pc; 3898c2ecf20Sopenharmony_ci args[5] = arg; 3908c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_civoid prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci unsigned long args[6]; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid"; 3988c2ecf20Sopenharmony_ci args[1] = 3; 3998c2ecf20Sopenharmony_ci args[2] = 0; 4008c2ecf20Sopenharmony_ci args[3] = (unsigned int) cpuid; 4018c2ecf20Sopenharmony_ci args[4] = pc; 4028c2ecf20Sopenharmony_ci args[5] = arg; 4038c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_civoid prom_stopcpu_cpuid(int cpuid) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci unsigned long args[4]; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid"; 4118c2ecf20Sopenharmony_ci args[1] = 1; 4128c2ecf20Sopenharmony_ci args[2] = 0; 4138c2ecf20Sopenharmony_ci args[3] = (unsigned int) cpuid; 4148c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 4158c2ecf20Sopenharmony_ci} 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_civoid prom_stopself(void) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci unsigned long args[3]; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,stop-self"; 4228c2ecf20Sopenharmony_ci args[1] = 0; 4238c2ecf20Sopenharmony_ci args[2] = 0; 4248c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_civoid prom_idleself(void) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci unsigned long args[3]; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,idle-self"; 4328c2ecf20Sopenharmony_ci args[1] = 0; 4338c2ecf20Sopenharmony_ci args[2] = 0; 4348c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 4358c2ecf20Sopenharmony_ci} 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_civoid prom_resumecpu(int cpunode) 4388c2ecf20Sopenharmony_ci{ 4398c2ecf20Sopenharmony_ci unsigned long args[4]; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci args[0] = (unsigned long) "SUNW,resume-cpu"; 4428c2ecf20Sopenharmony_ci args[1] = 1; 4438c2ecf20Sopenharmony_ci args[2] = 0; 4448c2ecf20Sopenharmony_ci args[3] = (unsigned int) cpunode; 4458c2ecf20Sopenharmony_ci p1275_cmd_direct(args); 4468c2ecf20Sopenharmony_ci} 4478c2ecf20Sopenharmony_ci#endif 448