Root/
Source at commit 1406 created 12 years 10 months ago. By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. Added some comments about it too. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * The contents of this file constitute Original Code as defined in and␊ |
7 | * are subject to the Apple Public Source License Version 1.1 (the␊ |
8 | * "License"). You may not use this file except in compliance with the␊ |
9 | * License. Please obtain a copy of the License at␊ |
10 | * http://www.apple.com/publicsource and read it before using this file.␊ |
11 | * ␊ |
12 | * This Original Code and all software distributed under the License are␊ |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER␊ |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,␊ |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,␊ |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the␊ |
17 | * License for the specific language governing rights and limitations␊ |
18 | * under the License.␊ |
19 | * ␊ |
20 | * @APPLE_LICENSE_HEADER_END@␊ |
21 | */␊ |
22 | /*␊ |
23 | * ci.c - Functions for accessing Open Firmware's Client Interface␊ |
24 | *␊ |
25 | * Copyright (c) 1998-2002 Apple Computer, Inc.␊ |
26 | *␊ |
27 | * DRI: Josh de Cesare␊ |
28 | */␊ |
29 | ␊ |
30 | #include <sl.h>␊ |
31 | ␊ |
32 | static ClientInterfacePtr gCIPtr;␊ |
33 | ␊ |
34 | long InitCI(ClientInterfacePtr ciPtr)␊ |
35 | {␊ |
36 | gCIPtr = ciPtr;␊ |
37 | ␊ |
38 | return 0;␊ |
39 | }␊ |
40 | ␊ |
41 | long CallCI(CIArgs *ciArgsPtr)␊ |
42 | {␊ |
43 | long ret;␊ |
44 | ␊ |
45 | ret = (*gCIPtr)(ciArgsPtr);␊ |
46 | return ret;␊ |
47 | }␊ |
48 | ␊ |
49 | ␊ |
50 | // Device Tree␊ |
51 | ␊ |
52 | // Peer take a phandle and returns the next peer.␊ |
53 | // It returns zero of there are no more peers.␊ |
54 | CICell Peer(CICell phandle)␊ |
55 | {␊ |
56 | CIArgs ciArgs;␊ |
57 | CICell peer_ph;␊ |
58 | long ret;␊ |
59 | ␊ |
60 | ciArgs.service = "peer";␊ |
61 | ciArgs.nArgs = 1;␊ |
62 | ciArgs.nReturns = 1;␊ |
63 | ciArgs.args.peer.phandle = phandle;␊ |
64 | ␊ |
65 | ret = CallCI(&ciArgs);␊ |
66 | if (ret != 0) return kCIError;␊ |
67 | ␊ |
68 | peer_ph = ciArgs.args.peer.peerPhandle;␊ |
69 | ␊ |
70 | return peer_ph;␊ |
71 | }␊ |
72 | ␊ |
73 | // Child take a phandle and returns the first child.␊ |
74 | // It returns zero of there in no child.␊ |
75 | CICell Child(CICell phandle)␊ |
76 | {␊ |
77 | CIArgs ciArgs;␊ |
78 | CICell child_ph;␊ |
79 | long ret;␊ |
80 | ␊ |
81 | ciArgs.service = "child";␊ |
82 | ciArgs.nArgs = 1;␊ |
83 | ciArgs.nReturns = 1;␊ |
84 | ciArgs.args.child.phandle = phandle;␊ |
85 | ␊ |
86 | ret = CallCI(&ciArgs);␊ |
87 | if (ret != 0) return kCIError;␊ |
88 | ␊ |
89 | child_ph = ciArgs.args.child.childPhandle;␊ |
90 | ␊ |
91 | return child_ph;␊ |
92 | }␊ |
93 | ␊ |
94 | // Parent take a phandle and returns the parent node.␊ |
95 | // It returns zero of if the phandle is the root node.␊ |
96 | CICell Parent(CICell phandle)␊ |
97 | {␊ |
98 | CIArgs ciArgs;␊ |
99 | CICell parent_ph;␊ |
100 | long ret;␊ |
101 | ␊ |
102 | ciArgs.service = "parent";␊ |
103 | ciArgs.nArgs = 1;␊ |
104 | ciArgs.nReturns = 1;␊ |
105 | ciArgs.args.parent.childPhandle = phandle;␊ |
106 | ␊ |
107 | ret = CallCI(&ciArgs);␊ |
108 | if (ret != 0) return kCIError;␊ |
109 | ␊ |
110 | parent_ph = ciArgs.args.parent.parentPhandle;␊ |
111 | ␊ |
112 | return parent_ph;␊ |
113 | }␊ |
114 | ␊ |
115 | // FindDevice take a device spec and returns the phandle.␊ |
116 | // It returns zero of if the device was not found.␊ |
117 | CICell FindDevice(char *devSpec)␊ |
118 | {␊ |
119 | CIArgs ciArgs;␊ |
120 | CICell phandle;␊ |
121 | long ret;␊ |
122 | ␊ |
123 | ciArgs.service = "finddevice";␊ |
124 | ciArgs.nArgs = 1;␊ |
125 | ciArgs.nReturns = 1;␊ |
126 | ciArgs.args.finddevice.devSpec = devSpec;␊ |
127 | ␊ |
128 | ret = CallCI(&ciArgs);␊ |
129 | if (ret != 0) return kCIError;␊ |
130 | ␊ |
131 | phandle = ciArgs.args.finddevice.phandle;␊ |
132 | ␊ |
133 | return phandle;␊ |
134 | }␊ |
135 | ␊ |
136 | // InstanceToPath take an ihandle, buf and buflen. Set the device path␊ |
137 | // to the package in buf upto buflen characters and returns the length␊ |
138 | // Length will be -1 if the ihandle is invalid.␊ |
139 | CICell InstanceToPath(CICell ihandle, char *buf, long buflen)␊ |
140 | {␊ |
141 | CIArgs ciArgs;␊ |
142 | CICell length;␊ |
143 | long ret;␊ |
144 | ␊ |
145 | ciArgs.service = "instance-to-path";␊ |
146 | ciArgs.nArgs = 3;␊ |
147 | ciArgs.nReturns = 1;␊ |
148 | ciArgs.args.instanceToPath.ihandle = ihandle;␊ |
149 | ciArgs.args.instanceToPath.buf = buf;␊ |
150 | ciArgs.args.instanceToPath.buflen = buflen;␊ |
151 | ␊ |
152 | ret = CallCI(&ciArgs);␊ |
153 | if (ret != 0) return kCIError;␊ |
154 | ␊ |
155 | length = ciArgs.args.instanceToPath.length;␊ |
156 | ␊ |
157 | return length;␊ |
158 | }␊ |
159 | ␊ |
160 | // InstanceToPackage take an ihandle and returns the phandle for it.␊ |
161 | // returns -1 if the phandle can't be found.␊ |
162 | CICell InstanceToPackage(CICell ihandle)␊ |
163 | {␊ |
164 | CIArgs ciArgs;␊ |
165 | CICell phandle;␊ |
166 | long ret;␊ |
167 | ␊ |
168 | ciArgs.service = "instance-to-package";␊ |
169 | ciArgs.nArgs = 1;␊ |
170 | ciArgs.nReturns = 1;␊ |
171 | ciArgs.args.instanceToPackage.ihandle = ihandle;␊ |
172 | ␊ |
173 | ret = CallCI(&ciArgs);␊ |
174 | if (ret != 0) return kCIError;␊ |
175 | ␊ |
176 | phandle = ciArgs.args.instanceToPackage.phandle;␊ |
177 | ␊ |
178 | return phandle;␊ |
179 | }␊ |
180 | ␊ |
181 | // InstanceToPackages␊ |
182 | ␊ |
183 | // PackageToPath take a phandle, buf and buflen. Set the device path␊ |
184 | // to the package in buf upto buflen characters and returns the length␊ |
185 | // Length will be -1 if the phandle is invalid.␊ |
186 | CICell PackageToPath(CICell phandle, char *buf, long buflen)␊ |
187 | {␊ |
188 | CIArgs ciArgs;␊ |
189 | CICell length;␊ |
190 | long ret;␊ |
191 | ␊ |
192 | if (gOFVersion >= kOFVersion2x) {␊ |
193 | ciArgs.service = "package-to-path";␊ |
194 | ciArgs.nArgs = 3;␊ |
195 | ciArgs.nReturns = 1;␊ |
196 | ciArgs.args.packageToPath.phandle = phandle;␊ |
197 | ciArgs.args.packageToPath.buf = buf;␊ |
198 | ciArgs.args.packageToPath.buflen = buflen;␊ |
199 | ␊ |
200 | ret = CallCI(&ciArgs);␊ |
201 | if (ret != 0) return kCIError;␊ |
202 | ␊ |
203 | length = ciArgs.args.packageToPath.length;␊ |
204 | } else {␊ |
205 | ret = CallMethod(3, 1, SLWordsIH, "slw_pwd", phandle,␊ |
206 | ␉␉ (CICell)buf, buflen, &length);␊ |
207 | if (ret != 0) return kCIError;␊ |
208 | ␊ |
209 | buf[length] = '\0';␊ |
210 | }␊ |
211 | ␊ |
212 | return length;␊ |
213 | }␊ |
214 | ␊ |
215 | // Canon␊ |
216 | ␊ |
217 | // GetPropLen takes a phandle and prop name␊ |
218 | // and returns the size of the property␊ |
219 | // or -1 if the property is not valid.␊ |
220 | CICell GetPropLen(CICell phandle, char *name)␊ |
221 | {␊ |
222 | CIArgs ciArgs;␊ |
223 | CICell size;␊ |
224 | long ret;␊ |
225 | ␊ |
226 | ciArgs.service = "getproplen";␊ |
227 | ciArgs.nArgs = 2;␊ |
228 | ciArgs.nReturns = 1;␊ |
229 | ciArgs.args.getproplen.phandle = phandle;␊ |
230 | ciArgs.args.getproplen.name = name;␊ |
231 | ␊ |
232 | ret = CallCI(&ciArgs);␊ |
233 | if (ret != 0) return kCIError;␊ |
234 | ␊ |
235 | size = ciArgs.args.getproplen.size;␊ |
236 | ␊ |
237 | return size;␊ |
238 | }␊ |
239 | ␊ |
240 | // GetProp takes a phandle, prop name, buffer and length␊ |
241 | // and copied the property value in to the buffer.␊ |
242 | // returns -1 if the property is not valid.␊ |
243 | CICell GetProp(CICell phandle, char *name, char *buf, long buflen)␊ |
244 | {␊ |
245 | CIArgs ciArgs;␊ |
246 | CICell size;␊ |
247 | long ret;␊ |
248 | ␊ |
249 | ciArgs.service = "getprop";␊ |
250 | ciArgs.nArgs = 4;␊ |
251 | ciArgs.nReturns = 1;␊ |
252 | ciArgs.args.getprop.phandle = phandle;␊ |
253 | ciArgs.args.getprop.name = name;␊ |
254 | ciArgs.args.getprop.buf = buf;␊ |
255 | ciArgs.args.getprop.buflen = buflen;␊ |
256 | ␊ |
257 | ret = CallCI(&ciArgs);␊ |
258 | if (ret != 0) return kCIError;␊ |
259 | ␊ |
260 | size = ciArgs.args.getprop.size;␊ |
261 | ␊ |
262 | return size;␊ |
263 | }␊ |
264 | ␊ |
265 | // NextProp takes a phandle, prev name, and a buffer␊ |
266 | // and copied the next property name in to the buffer.␊ |
267 | // returns -1 if the property is not valid.␊ |
268 | // returns 0 if the prev was the last property.␊ |
269 | // returns 1 otherwise.␊ |
270 | CICell NextProp(CICell phandle, char *previous, char *buf)␊ |
271 | {␊ |
272 | CIArgs ciArgs;␊ |
273 | CICell flag;␊ |
274 | long ret;␊ |
275 | ␊ |
276 | ciArgs.service = "nextprop";␊ |
277 | ciArgs.nArgs = 3;␊ |
278 | ciArgs.nReturns = 1;␊ |
279 | ciArgs.args.nextprop.phandle = phandle;␊ |
280 | ciArgs.args.nextprop.previous = previous;␊ |
281 | ciArgs.args.nextprop.buf = buf;␊ |
282 | ␊ |
283 | ret = CallCI(&ciArgs);␊ |
284 | if (ret != 0) return kCIError;␊ |
285 | ␊ |
286 | flag = ciArgs.args.nextprop.flag;␊ |
287 | ␊ |
288 | return flag;␊ |
289 | }␊ |
290 | ␊ |
291 | // SetProp takes a phandle, prop name, buffer and length␊ |
292 | // and copied the buffer in to the property value.␊ |
293 | // returns -1 if the property could not be set or created.␊ |
294 | CICell SetProp(CICell phandle, char *name, char *buf, long buflen)␊ |
295 | {␊ |
296 | CIArgs ciArgs;␊ |
297 | CICell size;␊ |
298 | long ret;␊ |
299 | ␊ |
300 | ciArgs.service = "setprop";␊ |
301 | ciArgs.nArgs = 4;␊ |
302 | ciArgs.nReturns = 1;␊ |
303 | ciArgs.args.setprop.phandle = phandle;␊ |
304 | ciArgs.args.setprop.name = name;␊ |
305 | ciArgs.args.setprop.buf = buf;␊ |
306 | ciArgs.args.setprop.buflen = buflen;␊ |
307 | ␊ |
308 | ret = CallCI(&ciArgs);␊ |
309 | if (ret != 0) return kCIError;␊ |
310 | ␊ |
311 | size = ciArgs.args.setprop.size;␊ |
312 | ␊ |
313 | return size;␊ |
314 | }␊ |
315 | ␊ |
316 | ␊ |
317 | // Device I/O␊ |
318 | ␊ |
319 | // Open takes a device specifier and returns an iHandle␊ |
320 | // It returns zero if the device can not be found or opened.␊ |
321 | CICell Open(char *devSpec)␊ |
322 | {␊ |
323 | CIArgs ciArgs;␊ |
324 | CICell ihandle;␊ |
325 | long ret;␊ |
326 | ␊ |
327 | ciArgs.service = "open";␊ |
328 | ciArgs.nArgs = 1;␊ |
329 | ciArgs.nReturns = 1;␊ |
330 | ciArgs.args.open.devSpec = devSpec;␊ |
331 | ␊ |
332 | ret = CallCI(&ciArgs);␊ |
333 | if (ret != 0) return 0;␊ |
334 | ␊ |
335 | ihandle = ciArgs.args.open.ihandle;␊ |
336 | ␊ |
337 | return ihandle;␊ |
338 | }␊ |
339 | ␊ |
340 | // Close takes an iHandle and closes the device.␊ |
341 | void Close(CICell ihandle)␊ |
342 | {␊ |
343 | CIArgs ciArgs;␊ |
344 | ␊ |
345 | ciArgs.service = "close";␊ |
346 | ciArgs.nArgs = 1;␊ |
347 | ciArgs.nReturns = 0;␊ |
348 | ciArgs.args.close.ihandle = ihandle;␊ |
349 | ␊ |
350 | CallCI(&ciArgs);␊ |
351 | }␊ |
352 | ␊ |
353 | // Read takes an iHandle, an address and a length and return the actual␊ |
354 | // Length read. Returns -1 if the operaction failed.␊ |
355 | CICell Read(CICell ihandle, long addr, long length)␊ |
356 | {␊ |
357 | CIArgs ciArgs;␊ |
358 | long actual;␊ |
359 | long ret;␊ |
360 | ␊ |
361 | ciArgs.service = "read";␊ |
362 | ciArgs.nArgs = 3;␊ |
363 | ciArgs.nReturns = 1;␊ |
364 | ciArgs.args.read.ihandle = ihandle;␊ |
365 | ciArgs.args.read.addr = addr;␊ |
366 | ciArgs.args.read.length = length;␊ |
367 | ␊ |
368 | ret = CallCI(&ciArgs);␊ |
369 | if (ret != 0) return kCIError;␊ |
370 | ␊ |
371 | actual = ciArgs.args.read.actual;␊ |
372 | ␊ |
373 | // Spin the wait cursor.␊ |
374 | Spin();␊ |
375 | ␊ |
376 | return actual;␊ |
377 | }␊ |
378 | ␊ |
379 | // Write takes an iHandle, an address and a length and return the actual␊ |
380 | // Length written. Returns -1 if the operaction failed.␊ |
381 | CICell Write(CICell ihandle, long addr, long length)␊ |
382 | {␊ |
383 | CIArgs ciArgs;␊ |
384 | long actual;␊ |
385 | long ret;␊ |
386 | ␊ |
387 | ciArgs.service = "write";␊ |
388 | ciArgs.nArgs = 3;␊ |
389 | ciArgs.nReturns = 1;␊ |
390 | ciArgs.args.write.ihandle = ihandle;␊ |
391 | ciArgs.args.write.addr = addr;␊ |
392 | ciArgs.args.write.length = length;␊ |
393 | ␊ |
394 | ret = CallCI(&ciArgs);␊ |
395 | if (ret != 0) return kCIError;␊ |
396 | ␊ |
397 | actual = ciArgs.args.write.actual;␊ |
398 | ␊ |
399 | return actual;␊ |
400 | }␊ |
401 | ␊ |
402 | // Seek takes an iHandle, and a 64 bit position␊ |
403 | // and moves to that address in file.␊ |
404 | // returns seeks result, or -1 if seek is not supported.␊ |
405 | CICell Seek(CICell ihandle, long long position)␊ |
406 | {␊ |
407 | CIArgs ciArgs;␊ |
408 | long ret;␊ |
409 | ␊ |
410 | ciArgs.service = "seek";␊ |
411 | ciArgs.nArgs = 3;␊ |
412 | ciArgs.nReturns = 1;␊ |
413 | ciArgs.args.seek.ihandle = ihandle;␊ |
414 | ciArgs.args.seek.pos_high = position >> 32;␊ |
415 | ciArgs.args.seek.pos_low = position & 0x00000000FFFFFFFFULL;␊ |
416 | ␊ |
417 | ret = CallCI(&ciArgs);␊ |
418 | if (ret != 0) return kCIError;␊ |
419 | ␊ |
420 | ret = ciArgs.args.seek.result;␊ |
421 | ␊ |
422 | return ret;␊ |
423 | }␊ |
424 | ␊ |
425 | ␊ |
426 | // Other Device Method Invocation␊ |
427 | ␊ |
428 | // Call the specified method on the given iHandle with the listed arguments.␊ |
429 | long CallMethod(long args, long rets, CICell iHandle, const char *method, ...)␊ |
430 | {␊ |
431 | va_list argList;␊ |
432 | CIArgs ciArgs;␊ |
433 | long ret, cnt, error = kCINoError;␊ |
434 | ␊ |
435 | va_start(argList, method);␊ |
436 | ␊ |
437 | ciArgs.service = "call-method";␊ |
438 | ciArgs.nArgs = args + 2;␊ |
439 | ciArgs.nReturns = rets + 1;␊ |
440 | ciArgs.args.callMethod.iHandle = iHandle;␊ |
441 | ciArgs.args.callMethod.method = method;␊ |
442 | ␊ |
443 | for (cnt = 0; cnt < args; cnt++) {␊ |
444 | ciArgs.args.callMethod.cells[args - cnt - 1] = va_arg(argList, CICell);␊ |
445 | }␊ |
446 | ␊ |
447 | ret = CallCI(&ciArgs);␊ |
448 | if (ret != 0) error = kCIError;␊ |
449 | else if (ciArgs.args.callMethod.cells[args] != 0) error = kCICatch;␊ |
450 | ␊ |
451 | if (error == kCINoError) {␊ |
452 | for (cnt = 0; cnt < rets; cnt++) {␊ |
453 | *(va_arg(argList, CICell *)) =␊ |
454 | ␉ciArgs.args.callMethod.cells[args + rets - cnt];␊ |
455 | }␊ |
456 | }␊ |
457 | ␊ |
458 | va_end(argList);␊ |
459 | ␊ |
460 | return error;␊ |
461 | }␊ |
462 | ␊ |
463 | ␊ |
464 | // Memory␊ |
465 | ␊ |
466 | // Claim takes a virt address, a size, and an alignment.␊ |
467 | // It return baseaddr or -1 for claim failed.␊ |
468 | CICell Claim(CICell virt, CICell size, CICell align)␊ |
469 | {␊ |
470 | CIArgs ciArgs;␊ |
471 | CICell baseaddr;␊ |
472 | long ret;␊ |
473 | ␊ |
474 | if (gOFVersion >= kOFVersion2x) {␊ |
475 | // Claim actually works, so use it.␊ |
476 | ciArgs.service = "claim";␊ |
477 | ciArgs.nArgs = 3;␊ |
478 | ciArgs.nReturns = 1;␊ |
479 | ciArgs.args.claim.virt = virt;␊ |
480 | ciArgs.args.claim.size = size;␊ |
481 | ciArgs.args.claim.align = align;␊ |
482 | ␊ |
483 | ret = CallCI(&ciArgs);␊ |
484 | if (ret != 0) return kCIError;␊ |
485 | ␊ |
486 | baseaddr = ciArgs.args.claim.baseaddr;␊ |
487 | } else {␊ |
488 | // Claim does not work. Do it by hand.␊ |
489 | if ((gMMUIH == 0) || (gMMUIH == 0)) return kCIError;␊ |
490 | ␊ |
491 | // Get the physical memory␊ |
492 | ret = CallMethod(3, 1, gMemoryIH, "claim", virt, size, 0, &baseaddr);␊ |
493 | if ((ret != kCINoError) || (virt != baseaddr)) return kCIError;␊ |
494 | ␊ |
495 | // Get the logical memory␊ |
496 | ret = CallMethod(3, 1, gMMUIH, "claim", virt, size, 0, &baseaddr);␊ |
497 | if ((ret != kCINoError) || (virt != baseaddr)) return kCIError;␊ |
498 | ␊ |
499 | // Map them together.␊ |
500 | ret = CallMethod(4, 0, gMMUIH, "map", virt, virt, size, 0);␊ |
501 | if (ret != kCINoError) return kCIError;␊ |
502 | }␊ |
503 | ␊ |
504 | return baseaddr;␊ |
505 | }␊ |
506 | ␊ |
507 | // Release takes a virt address, a size␊ |
508 | void Release(CICell virt, CICell size)␊ |
509 | {␊ |
510 | CIArgs ciArgs;␊ |
511 | ␊ |
512 | ciArgs.service = "release";␊ |
513 | ciArgs.nArgs = 2;␊ |
514 | ciArgs.nReturns = 0;␊ |
515 | ciArgs.args.claim.virt = virt;␊ |
516 | ciArgs.args.claim.size = size;␊ |
517 | ␊ |
518 | CallCI(&ciArgs);␊ |
519 | }␊ |
520 | ␊ |
521 | ␊ |
522 | // Control Transfer␊ |
523 | ␊ |
524 | // Boot trys to boot the bootspec␊ |
525 | void Boot(char *bootspec)␊ |
526 | {␊ |
527 | CIArgs ciArgs;␊ |
528 | ␊ |
529 | ciArgs.service = "boot";␊ |
530 | ciArgs.nArgs = 1;␊ |
531 | ciArgs.nReturns = 0;␊ |
532 | ciArgs.args.boot.bootspec = bootspec;␊ |
533 | ␊ |
534 | CallCI(&ciArgs);␊ |
535 | }␊ |
536 | ␊ |
537 | // Enter the user interface.␊ |
538 | // Executing the 'go' command returns to the client.␊ |
539 | void Enter(void)␊ |
540 | {␊ |
541 | CIArgs ciArgs;␊ |
542 | ␊ |
543 | ciArgs.service = "enter";␊ |
544 | ciArgs.nArgs = 0;␊ |
545 | ciArgs.nReturns = 0;␊ |
546 | ␊ |
547 | CallCI(&ciArgs);␊ |
548 | }␊ |
549 | ␊ |
550 | // Exit the client program.␊ |
551 | void Exit(void)␊ |
552 | {␊ |
553 | CIArgs ciArgs;␊ |
554 | ␊ |
555 | ciArgs.service = "exit";␊ |
556 | ciArgs.nArgs = 0;␊ |
557 | ciArgs.nReturns = 0;␊ |
558 | ␊ |
559 | CallCI(&ciArgs);␊ |
560 | }␊ |
561 | ␊ |
562 | // Clain␊ |
563 | ␊ |
564 | // Quiesce stops any async tasks in Open Firmware.␊ |
565 | void Quiesce(void)␊ |
566 | {␊ |
567 | CIArgs ciArgs;␊ |
568 | ␊ |
569 | ciArgs.service = "quiesce";␊ |
570 | ciArgs.nArgs = 0;␊ |
571 | ciArgs.nReturns = 0;␊ |
572 | ␊ |
573 | CallCI(&ciArgs);␊ |
574 | }␊ |
575 | ␊ |
576 | ␊ |
577 | // User Interface␊ |
578 | ␊ |
579 | // Interpret the given forth string with the listed arguments.␊ |
580 | long Interpret(long args, long rets, const char *forthString, ...)␊ |
581 | {␊ |
582 | va_list argList;␊ |
583 | CIArgs ciArgs;␊ |
584 | long ret, cnt, error = kCINoError;␊ |
585 | ␊ |
586 | va_start(argList, forthString);␊ |
587 | ␊ |
588 | ciArgs.service = "interpret";␊ |
589 | ciArgs.nArgs = args + 1;␊ |
590 | ciArgs.nReturns = rets + 1;␊ |
591 | ciArgs.args.interpret.forth = forthString;␊ |
592 | ␊ |
593 | for (cnt = 0; cnt < args; cnt++) {␊ |
594 | ciArgs.args.interpret.cells[args - cnt - 1] = va_arg(argList, CICell);␊ |
595 | }␊ |
596 | ␊ |
597 | ret = CallCI(&ciArgs);␊ |
598 | if (ret != 0) error = kCIError;␊ |
599 | else if (ciArgs.args.interpret.cells[args] != 0) error = kCICatch;␊ |
600 | ␊ |
601 | if (error == kCINoError) {␊ |
602 | for (cnt = 0; cnt < rets; cnt++) {␊ |
603 | *(va_arg(argList, CICell *)) =␊ |
604 | ␉ciArgs.args.interpret.cells[args + rets - cnt];␊ |
605 | }␊ |
606 | }␊ |
607 | ␊ |
608 | va_end(argList);␊ |
609 | ␊ |
610 | return error;␊ |
611 | }␊ |
612 |