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
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
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'. */
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'. */
26 prom_feval(char *fstring
)
28 if(!fstring
|| fstring
[0] == 0)
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
;
40 /* Drop into the prom, with the chance to continue with the 'go'
48 #ifdef CONFIG_SUN_CONSOLE
49 if(!serial_console
&& prom_palette
)
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
)
61 /* Drop into the prom, but completely terminate the program.
62 * No chance of continuing.
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'. */
74 prom_setcallback(callback_func_t funcp
)
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.
86 prom_get_idprom(char *idbuf
, int num_bytes
)
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
))
98 /* Get the major prom version number. */
105 /* Get the prom plugin-revision. */
112 /* Get the prom firmware print revision. */
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;
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;
139 mmu_ihandle_cache
= ret
;
144 static int prom_get_memory_ihandle(void)
146 static int memory_ihandle_cache
= 0;
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;
157 memory_ihandle_cache
= ret
;
162 /* Load explicit I/D TLB entries. */
163 long prom_itlb_load(unsigned long index
,
164 unsigned long tte_data
,
167 return p1275_cmd("call-method",
168 (P1275_ARG(0, P1275_ARG_IN_BUF
) | P1275_INOUT(5, 1)),
170 prom_get_mmu_ihandle(),
171 /* And then our actual args are pushed backwards. */
177 long prom_dtlb_load(unsigned long index
,
178 unsigned long tte_data
,
181 return p1275_cmd("call-method",
182 (P1275_ARG(0, P1275_ARG_IN_BUF
) | P1275_INOUT(5, 1)),
184 prom_get_mmu_ihandle(),
185 /* And then our actual args are pushed backwards. */
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
203 /* If align is zero, the pa_low/pa_high args are passed,
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
);
211 return p1275_cmd("SUNW,retain",
212 (P1275_ARG(0, P1275_ARG_IN_BUF
) | P1275_INOUT(3, 2)),
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
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
) |
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));
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
);