Import 2.3.18pre1
[davej-history.git] / arch / sparc64 / prom / misc.c
blob2a45a4bb5ae76bcd9db945008296ff99f607945b
1 /* $Id: misc.c,v 1.15 1999/08/31 19:25:41 davem Exp $
2 * misc.c: Miscellaneous prom functions that don't belong
3 * anywhere else.
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7 */
9 #include <linux/config.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <asm/openprom.h>
14 #include <asm/oplib.h>
16 /* Reset and reboot the machine with the command 'bcommand'. */
17 void
18 prom_reboot(char *bcommand)
20 p1275_cmd ("boot", P1275_ARG(0,P1275_ARG_IN_STRING)|
21 P1275_INOUT(1,0), bcommand);
24 /* Forth evaluate the expression contained in 'fstring'. */
25 void
26 prom_feval(char *fstring)
28 if(!fstring || fstring[0] == 0)
29 return;
30 p1275_cmd ("interpret", P1275_ARG(0,P1275_ARG_IN_STRING)|
31 P1275_INOUT(1,1), fstring);
34 /* We want to do this more nicely some day. */
35 #ifdef CONFIG_SUN_CONSOLE
36 extern void (*prom_palette)(int);
37 extern int serial_console;
38 #endif
40 /* Drop into the prom, with the chance to continue with the 'go'
41 * prom command.
43 void
44 prom_cmdline(void)
46 unsigned long flags;
48 #ifdef CONFIG_SUN_CONSOLE
49 if(!serial_console && prom_palette)
50 prom_palette (1);
51 #endif
52 __save_and_cli(flags);
53 p1275_cmd ("enter", P1275_INOUT(0,0));
54 __restore_flags(flags);
55 #ifdef CONFIG_SUN_CONSOLE
56 if(!serial_console && prom_palette)
57 prom_palette (0);
58 #endif
61 /* Drop into the prom, but completely terminate the program.
62 * No chance of continuing.
64 void
65 prom_halt(void)
67 again:
68 p1275_cmd ("exit", P1275_INOUT(0,0));
69 goto again; /* PROM is out to get me -DaveM */
72 /* Set prom sync handler to call function 'funcp'. */
73 void
74 prom_setcallback(callback_func_t funcp)
76 if(!funcp) return;
77 p1275_cmd ("set-callback", P1275_ARG(0,P1275_ARG_IN_FUNCTION)|
78 P1275_INOUT(1,1), funcp);
81 /* Get the idprom and stuff it into buffer 'idbuf'. Returns the
82 * format type. 'num_bytes' is the number of bytes that your idbuf
83 * has space for. Returns 0xff on error.
85 unsigned char
86 prom_get_idprom(char *idbuf, int num_bytes)
88 int len;
90 len = prom_getproplen(prom_root_node, "idprom");
91 if((len>num_bytes) || (len==-1)) return 0xff;
92 if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
93 return idbuf[0];
95 return 0xff;
98 /* Get the major prom version number. */
99 int
100 prom_version(void)
102 return PROM_P1275;
105 /* Get the prom plugin-revision. */
107 prom_getrev(void)
109 return prom_rev;
112 /* Get the prom firmware print revision. */
114 prom_getprev(void)
116 return prom_prev;
119 /* Install Linux trap table so PROM uses that instead of it's own. */
120 void prom_set_trap_table(unsigned long tba)
122 p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba);
125 /* This is only used internally below. */
126 static int prom_get_mmu_ihandle(void)
128 static int mmu_ihandle_cache = 0;
129 int node, ret;
131 if (mmu_ihandle_cache != 0)
132 return mmu_ihandle_cache;
134 node = prom_finddevice("/chosen");
135 ret = prom_getint(node, "mmu");
136 if(ret == -1 || ret == 0)
137 mmu_ihandle_cache = -1;
138 else
139 mmu_ihandle_cache = ret;
141 return ret;
144 static int prom_get_memory_ihandle(void)
146 static int memory_ihandle_cache = 0;
147 int node, ret;
149 if (memory_ihandle_cache != 0)
150 return memory_ihandle_cache;
152 node = prom_finddevice("/chosen");
153 ret = prom_getint(node, "memory");
154 if (ret == -1 || ret == 0)
155 memory_ihandle_cache = -1;
156 else
157 memory_ihandle_cache = ret;
159 return ret;
162 /* Load explicit I/D TLB entries. */
163 long prom_itlb_load(unsigned long index,
164 unsigned long tte_data,
165 unsigned long vaddr)
167 return p1275_cmd("call-method",
168 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 1)),
169 "SUNW,itlb-load",
170 prom_get_mmu_ihandle(),
171 /* And then our actual args are pushed backwards. */
172 vaddr,
173 tte_data,
174 index);
177 long prom_dtlb_load(unsigned long index,
178 unsigned long tte_data,
179 unsigned long vaddr)
181 return p1275_cmd("call-method",
182 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 1)),
183 "SUNW,dtlb-load",
184 prom_get_mmu_ihandle(),
185 /* And then our actual args are pushed backwards. */
186 vaddr,
187 tte_data,
188 index);
191 /* Set aside physical memory which is not touched or modified
192 * across soft resets.
194 unsigned long prom_retain(char *name,
195 unsigned long pa_low, unsigned long pa_high,
196 long size, long align)
198 /* XXX I don't think we return multiple values correctly.
199 * XXX OBP supposedly returns pa_low/pa_high here, how does
200 * XXX it work?
203 /* If align is zero, the pa_low/pa_high args are passed,
204 * else they are not.
206 if(align == 0)
207 return p1275_cmd("SUNW,retain",
208 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
209 name, pa_low, pa_high, size, align);
210 else
211 return p1275_cmd("SUNW,retain",
212 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
213 name, size, align);
216 /* Get "Unumber" string for the SIMM at the given
217 * memory address. Usually this will be of the form
218 * "Uxxxx" where xxxx is a decimal number which is
219 * etched into the motherboard next to the SIMM slot
220 * in question.
222 int prom_getunumber(int syndrome_code,
223 unsigned long phys_addr,
224 char *buf, int buflen)
226 return p1275_cmd("call-method",
227 (P1275_ARG(0, P1275_ARG_IN_STRING) |
228 P1275_ARG(3, P1275_ARG_OUT_BUF) |
229 P1275_ARG(5, P1275_ARG_IN_64B) |
230 P1275_INOUT(8, 2)),
231 "SUNW,get-unumber", prom_get_memory_ihandle(),
232 buflen, buf, P1275_SIZE(buflen),
233 0, phys_addr, syndrome_code);
236 /* Power management extensions. */
237 void prom_sleepself(void)
239 p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
242 int prom_sleepsystem(void)
244 return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
247 int prom_wakeupsystem(void)
249 return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
252 #ifdef __SMP__
253 void prom_startcpu(int cpunode, unsigned long pc, unsigned long o0)
255 p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, o0);
258 void prom_stopself(void)
260 p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
263 void prom_idleself(void)
265 p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
268 void prom_resumecpu(int cpunode)
270 p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
272 #endif