/[pearpc]/src/io/prom/promosi.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/io/prom/promosi.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 20657 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * promosi.cc
4 *
5 * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <cstring>
22
23 #include "debug/tracers.h"
24 #include "system/display.h"
25 #include "system/arch/sysendian.h"
26 #include "cpu/cpu.h"
27 #include "cpu/mem.h"
28 #include "system/sysclk.h"
29 #include "promdt.h"
30 #include "prommem.h"
31 #include "promosi.h"
32
33 uint32 gPromOSIEntry;
34
35 void prom_service_start_cpu(prom_args *pa)
36 {
37 IO_PROM_ERR("start_cpu()\n");
38 }
39
40 void prom_service_quiesce(prom_args *pa)
41 {
42 IO_PROM_TRACE("quiesce()\n");
43 prom_mem_done();
44 }
45
46 /*
47 * .65
48 * Missing is 0 if the service name exists, and -1 if it does not exist.
49 */
50 void prom_service_test(prom_args *pa)
51 {
52 //; of_test(const char *name, int *missing)
53 String name;
54 prom_get_string(name, pa->args[0]);
55 IO_PROM_ERR("test('%y')\n", &name);
56 }
57
58 /*
59 * .66
60 *
61 */
62 void prom_service_peer(prom_args *pa)
63 {
64 //; of_peer(int phandle, int *sibling_phandle)
65 uint32 phandle = pa->args[0];
66 IO_PROM_TRACE("peer(%08x)\n", phandle);
67 if (!phandle) {
68 pa->args[1] = gPromRoot ? gPromRoot->getPHandle() : 0;
69 } else {
70 PromNode *p = handleToPackage(phandle);
71 if (p) {
72 if (!p->owner) {
73 pa->args[1] = 0;
74 } else {
75 p = p->owner->nextChild(p);
76 pa->args[1] = p ? p->getPHandle() : 0;
77 }
78 } else {
79 pa->args[1] = 0xffffffff;
80 }
81 }
82 IO_PROM_TRACE("= %08x\n", pa->args[1]);
83 }
84 void prom_service_child(prom_args *pa)
85 {
86 //; (int phandle, int *child_phandle)
87 uint32 phandle = pa->args[0];
88 PromNode *p = handleToPackage(phandle);
89 IO_PROM_TRACE("child(%08x, '%s')\n", phandle, p->name);
90 PromNode *pn = p ? p->firstChild() : NULL;
91 if (pn) {
92 pa->args[1] = pn->getPHandle();
93 } else {
94 pa->args[1] = 0;
95 }
96 IO_PROM_TRACE("= %08x\n", pa->args[1]);
97 }
98 void prom_service_parent(prom_args *pa)
99 {
100 //; of_parent(int phandle, int *parent_phandle)
101 uint32 phandle = pa->args[0];
102 PromNode *p = handleToPackage(phandle);
103 IO_PROM_TRACE("parent(%08x)\n", phandle);
104 PromNode *owner = p ? p->owner : NULL;
105 pa->args[1] = owner ? owner->getPHandle() : 0;
106 IO_PROM_TRACE("= %08x\n", pa->args[1]);
107 }
108 void prom_service_instance_to_package(prom_args *pa)
109 {
110 //; of_instance_to_package(int ihandle, int *phandle)
111 uint32 ihandle = pa->args[0];
112 IO_PROM_TRACE("instance-to-package(%08x)\n", ihandle);
113 PromInstance *pi = handleToInstance(ihandle);
114 if (pi) {
115 pa->args[1] = pi->getType()->getPHandle();
116 } else {
117 pa->args[1] = 0xffffffff;
118 }
119 IO_PROM_TRACE("= %08x\n", pa->args[1]);
120 }
121
122 void prom_service_finddevice(prom_args *pa)
123 {
124 //; of_finddevice(const char *device_specifier, int *phandle)
125 String device;
126 prom_get_string(device, pa->args[0]);
127 IO_PROM_TRACE("finddevice('%y')\n", &device);
128 PromNode *node = findDevice(device.contentChar(), FIND_DEVICE_FIND, NULL);
129 if (node) {
130 pa->args[1] = node->getPHandle();
131 } else {
132 pa->args[1] = 0xffffffff;
133 }
134 IO_PROM_TRACE("= %08x\n", pa->args[1]);
135 }
136 void prom_service_getproplen(prom_args *pa)
137 {
138 //; of_getproplen(int phandle, const char *name, int *proplen)
139 uint32 phandle = pa->args[0];
140 PromNode *p = handleToPackage(phandle);
141 String name;
142 prom_get_string(name, pa->args[1]);
143 IO_PROM_TRACE("getproplen(%08x, '%y')\n", phandle, &name);
144 PromProp *prop = p ? p->findProp(name.contentChar()) : 0;
145 if (!prop) {
146 pa->args[2] = 0xffffffff;
147 } else {
148 pa->args[2] = prop->getValueLen();
149 }
150 IO_PROM_TRACE("= %08x\n", pa->args[2]);
151 }
152 void prom_service_getprop(prom_args *pa)
153 {
154 //; of_getprop(int phandle, const char *name, void *buf, int buflen, int *size)
155 uint32 phandle = pa->args[0];
156 String name;
157 prom_get_string(name, pa->args[1]);
158 uint32 buf = pa->args[2];
159 uint32 buflen = pa->args[3];
160 IO_PROM_TRACE("getprop(%08x, '%y', %08x, %08x)\n", phandle, &name, buf, buflen);
161 PromNode *p = handleToPackage(phandle);
162 PromProp *prop = p ? p->findProp(name.contentChar()) : 0;
163 if (!prop) {
164 pa->args[4] = 0xffffffff;
165 } else {
166 pa->args[4] = prop->getValue(buf, buflen);
167 }
168 IO_PROM_TRACE("= %08x\n", pa->args[4]);
169 }
170 void prom_service_nextprop(prom_args *pa)
171 {
172 //; of_nextprop(int phandle, const char *previous, void *buf, int *flag)
173 uint32 phandle = pa->args[0];
174 String previous;
175 prom_get_string(previous, pa->args[1]);
176 uint32 buf = pa->args[2];
177 uint32 *flag = &pa->args[3];
178 IO_PROM_TRACE("nextprop(%08x, %08x:'%y', %08x)\n", phandle, pa->args[1], &previous, buf);
179 PromNode *pn = handleToPackage(phandle);
180 PromProp *prop = NULL;
181 if (previous.isEmpty() || !pn) {
182 prop = pn ? pn->firstProp() : 0;
183 if (!prop) {
184 *flag = 0;
185 } else {
186 *flag = 1;
187 }
188 } else {
189 prop = pn->findProp(previous.contentChar());
190 if (prop) {
191 prop = pn->nextProp(prop);
192 if (prop) {
193 *flag = 1;
194 } else {
195 *flag = 0;
196 }
197 } else {
198 *flag = 0xffffffff;
199 }
200 }
201 uint32 phys;
202 if (ppc_prom_effective_to_physical(phys, buf)) {
203 if (prop) {
204 char b[32];
205 ht_snprintf(b, sizeof b, "%s", prop->name);
206 ppc_dma_write(phys, b, strlen(b)+1);
207 } else {
208 char b=0;
209 ppc_dma_write(phys, &b, 1);
210 }
211 } else {
212 IO_PROM_ERR("can't access memory in %s\n", __FUNCTION__);
213 }
214 IO_PROM_TRACE("= %08x\n", *flag);
215 }
216 void prom_service_setprop(prom_args *pa)
217 {
218 //; of_setprop(int phandle, const char *name, void *buf, int len, int *size)
219 uint32 phandle = pa->args[0];
220 String name;
221 prom_get_string(name, pa->args[1]);
222 uint32 buf = pa->args[2];
223 String value;
224 uint32 len = pa->args[3];
225 uint32 phys;
226 if (buf && len && ppc_prom_effective_to_physical(phys, buf)) {
227 byte *p = (byte *)malloc(len);
228 if (ppc_dma_read(p, phys, len)) {
229 value.assign(p, len);
230 }
231 free(p);
232 }
233 PromNode *p = handleToPackage(phandle);
234 IO_PROM_TRACE("setprop(%x=='%s', '%y', '%y', %d)\n", phandle, p->name, &name, &value, len);
235 /* if (phandle == 0xdeadbee1) {
236 pa->args[4] = len;
237 // gSinglestep = true;
238 return;
239 }*/
240 if (p) {
241 PromProp *prop = p->findProp(name.contentChar());
242 if (!prop) {
243 if (buf) {
244 p->addProp(new PromPropMemory(name.contentChar(), value.content(), len));
245 } else {
246 p->addProp(new PromPropString(name.contentChar(), ""));
247 }
248 pa->args[4] = len;
249 } else {
250 //if (!buf && len) IO_PROM_ERR("setprop null bla\n");
251 if (buf && len)
252 pa->args[4] = prop->setValue(buf, len);
253 else
254 pa->args[4] = prop->setValue(0, 0);
255 }
256 } else {
257 pa->args[4] = 0;
258 }
259 IO_PROM_TRACE("= %08x\n", pa->args[4]);
260 }
261 void prom_service_canon(prom_args *pa)
262 {
263 //; of_canon(const char *device_specifier, void *buf, int buflen, int *length)
264 String device;
265 prom_get_string(device, pa->args[0]);
266 uint32 buf = pa->args[1];
267 uint32 buflen = pa->args[2];
268 IO_PROM_TRACE("canon('%y', %08x, %08x)\n", &device, buf, buflen);
269
270 uint32 phys;
271 if (ppc_prom_effective_to_physical(phys, buf)) {
272 if (buflen) buflen--;
273 device.crop(buflen);
274 ppc_dma_write(phys, device.contentChar(), device.length()+1);
275 pa->args[3] = device.length();
276 } else {
277 pa->args[3] = 0;
278 }
279 IO_PROM_TRACE("= %08x\n", pa->args[3]);
280 }
281 void prom_service_instance_to_path(prom_args *pa)
282 {
283 //; of_instance_to_path(int ihandle, void *buf, int buflen, int *length)
284 uint32 ihandle = pa->args[0];
285 uint32 buf = pa->args[1];
286 uint32 buflen = pa->args[2];
287 PromInstance *pi = handleToInstance(ihandle);
288 IO_PROM_TRACE("instance-to-path(%08x, %08x, %08x)\n", ihandle, buf, buflen);
289 uint32 phys;
290 if (pi && buflen && ppc_prom_effective_to_physical(phys, buf)) {
291 PromNode *pn = pi->getType();
292 char *s = (char *)malloc(buflen);
293 pa->args[3] = pn->toPath(s, buflen);
294 ppc_dma_write(phys, s, pa->args[3]+1);
295 free(s);
296 } else {
297 pa->args[3] = 0;
298 }
299 IO_PROM_TRACE("= %08x\n", pa->args[3]);
300 }
301 void prom_service_package_to_path(prom_args *pa)
302 {
303 //; of_package_to_path(int phandle, void *buf, int buflen, int *length)
304 uint32 phandle = pa->args[0];
305 uint32 buf = pa->args[1];
306 uint32 buflen = pa->args[2];
307 PromNode *p = handleToPackage(phandle);
308 IO_PROM_TRACE("package-to-path(%08x, %08x, %08x)\n", phandle, buf, buflen);
309 uint32 phys;
310 if (p && ppc_prom_effective_to_physical(phys, buf)) {
311 char *s = (char *)malloc(buflen);
312 pa->args[3] = p->toPath(s, buflen);
313 ppc_dma_write(phys, s, pa->args[3]+1);
314 free(s);
315 } else {
316 pa->args[3] = 0;
317 }
318 // IO_PROM_TRACE("%s\n", prom_ea_string(buf));
319 IO_PROM_TRACE("= %08x\n", pa->args[3]);
320 }
321 void prom_service_call_method(prom_args *pa)
322 {
323 //; int of_call_method(const char *method, int ihandle, ...); */
324 String method;
325 prom_get_string(method, pa->args[0]);
326 uint32 ihandle = pa->args[1];
327 PromInstance *pi = handleToInstance(ihandle);
328 IO_PROM_TRACE("call-method('%y', %08x, ...)\n", &method, ihandle);
329 if (ihandle == 0xdeadbee2) {
330 if (method == "slw_emit") {
331 // gDisplay->printf("%c", pa->args[2]);
332 } else if (method == "slw_cr") {
333 // gDisplay->print("\n");
334 } else if (method == "slw_init_keymap") {
335 uint32 a = prom_mem_malloc(20);
336 prom_mem_set(a, 0x00, 20);
337 pa->args[4] = prom_mem_phys_to_virt(a);
338 pa->args[3] = 0;
339 } else if (method == "slw_update_keymap") {
340 } else if (method == "slw_set_output_level") {
341 } else if (method == "slw_spin_init") {
342 } else if (method == "slw_spin") {
343 } else if (method == "slw_pwd") {
344 uint32 phandle = pa->args[4];
345 uint32 buf = pa->args[3];
346 uint32 buflen = pa->args[2];
347 PromNode *obj = handleToPackage(phandle);
348 pa->args[5] = 0;
349 uint32 phys;
350 if (obj && ppc_prom_effective_to_physical(phys, buf)) {
351 char *s = (char *)malloc(buflen);
352 pa->args[6] = obj->toPath(s, buflen);
353 ppc_dma_write(phys, s, pa->args[6]+1);
354 free(s);
355 } else {
356 pa->args[6] = 0;
357 }
358 } else {
359 IO_PROM_ERR("slw: %y not impl\n", &method);
360 }
361 } else {
362 if (pi) pi->callMethod(method.contentChar(), pa);
363 }
364 }
365 void prom_service_open(prom_args *pa)
366 {
367 //; of_open(const char *device_specifier, int *ihandle)
368 String device;
369 prom_get_string(device, pa->args[0]);
370 IO_PROM_TRACE("open('%y')\n", &device);
371 PromInstanceHandle ih;
372 PromNode *node = findDevice(device.contentChar(), FIND_DEVICE_OPEN, &ih);
373 if (node) {
374 pa->args[1] = ih;
375 } else {
376 pa->args[1] = 0xffffffff;
377 }
378 IO_PROM_TRACE("= %08x\n", pa->args[1]);
379 }
380 void prom_service_close(prom_args *pa)
381 {
382 //; of_close(int ihandle)
383 uint32 ihandle = pa->args[0];
384 IO_PROM_TRACE("close(%x)\n", ihandle);
385 PromInstance *pi = handleToInstance(ihandle);
386 if (pi) {
387 pi->getType()->close(ihandle);
388 }
389 }
390 void prom_service_read(prom_args *pa)
391 {
392 //; of_read(int ihandle, void *addr, int len, int *actual)
393 uint32 ihandle = pa->args[0];
394 uint32 addr = pa->args[1];
395 uint32 len = pa->args[2];
396 IO_PROM_TRACE("read(%08x, %08x, %08x)\n", ihandle, addr, len);
397 PromInstance *pi = handleToInstance(ihandle);
398 pa->args[3] = pi ? pi->read(addr, len) : 0;
399 IO_PROM_TRACE("= %08x\n", pa->args[3]);
400 }
401 void prom_service_write(prom_args *pa)
402 {
403 //; of_write(int ihandle, void *addr, int len, int *actual)
404 uint32 ihandle = pa->args[0];
405 uint32 addr = pa->args[1];
406 uint32 len = pa->args[2];
407 IO_PROM_TRACE("write(%08x, %08x, %08x)\n", ihandle, addr, len);
408 PromInstance *pi = handleToInstance(ihandle);
409 pa->args[3] = pi ? pi->write(addr, len) : 0;
410 IO_PROM_TRACE("= %08x\n", pa->args[3]);
411 }
412 void prom_service_seek(prom_args *pa)
413 {
414 //; of_seek(int ihandle, int pos_hi, int pos_lo, int *status)
415 uint32 ihandle = pa->args[0];
416 uint32 pos_hi = pa->args[1];
417 uint32 pos_lo = pa->args[2];
418 IO_PROM_TRACE("seek(%x, %x%032x)\n", ihandle, pos_hi, pos_lo);
419 PromInstance *pi = handleToInstance(ihandle);
420 pa->args[3] = pi ? pi->seek((((uint64)pos_hi) << 32) | pos_lo) : 0;
421 IO_PROM_TRACE("= %08x\n", pa->args[3]);
422 }
423 void prom_service_claim(prom_args *pa)
424 {
425 //; of_claim(void *virt, int size, int align, void **baseaddr)
426 uint32 virt = pa->args[0];
427 uint32 size = pa->args[1];
428 uint32 align = pa->args[2];
429 IO_PROM_TRACE("claim(%x, %x, %x)\n", virt, size, align);
430 if (!align) {
431 pa->args[3] = prom_allocate_mem(size, align, virt);
432 IO_PROM_TRACE("= %08x\n", pa->args[3]);
433 } else {
434 pa->args[3] = prom_allocate_mem(size, align, virt);
435 IO_PROM_TRACE("= %08x\n", pa->args[3]);
436 }
437 }
438 void prom_service_release(prom_args *pa)
439 {
440 //; of_release(void *virt, int size)
441 IO_PROM_ERR("release()\n");
442 }
443 void prom_service_boot(prom_args *pa)
444 {
445 //; of_boot(const char *bootspec)
446 IO_PROM_ERR("boot()\n");
447 }
448 void prom_service_enter(prom_args *pa)
449 {
450 //; of_enter(void)
451 uint64 start = sys_get_hiresclk_ticks();
452 uint64 end = start+(sys_get_hiresclk_ticks_per_second()*3);
453 while (sys_get_hiresclk_ticks() < end);
454 //IO_PROM_ERR("enter()\n");
455 }
456 void prom_service_exit(prom_args *pa)
457 {
458 //; of_exit(void)
459 IO_PROM_ERR("exit()\n");
460 /* while (1);
461 exit(1);*/
462 }
463 void prom_service_chain(prom_args *pa)
464 {
465 //; of_chain(void *virt, int size, void *entry, void *args, int len);
466 IO_PROM_ERR("chain()\n");
467 }
468 #include "io/graphic/gcard.h"
469 void prom_service_interpret(prom_args *pa)
470 {
471 //; of_(const char *arg, ...);
472 String arg;
473 prom_get_string(arg, pa->args[0]);
474 IO_PROM_TRACE("interpret(%d, %08x, %08x, %08x, %08x, '%y' ...)\n", arg.length(), pa->args[1], pa->args[2], pa->args[3], pa->args[4], &arg);
475 switch (arg.length()) {
476 case 6: {
477 // " 10 ms"
478 void prom_service_milliseconds(prom_args *pa);
479 uint32 start = (prom_service_milliseconds(pa), pa->args[0]);
480 while ((prom_service_milliseconds(pa),pa->args[0]) < start+10);
481 break;
482 }
483 case 32: {
484 // GetPackageProperty
485 uint32 phandle = pa->args[1];
486 uint32 proplen UNUSED = pa->args[2];
487 uint32 propname = pa->args[3];
488 String n;
489 prom_get_string(n, propname);
490 PromNode *pn = handleToPackage(phandle);
491 IO_PROM_TRACE("GetPackageProperty('%y', %08x:%s)\n", &n, phandle, pn->name);
492 PromProp *prop = pn->findProp(n.contentChar());
493 if (!prop) {
494 pa->args[4] = 0;
495 pa->args[5] = 0;
496 pa->args[6] = 0;
497 } else {
498 uint32 m = prom_mem_phys_to_virt(prom_mem_malloc(100));
499 IO_PROM_TRACE("m = %08x\n", m);
500 int s = prop->getValue(m, 100);
501 pa->args[4] = 0;
502 pa->args[5] = s;
503 pa->args[6] = m;
504 }
505 break;
506 // IO_PROM_ERR("-1\n");
507 }
508 case 39:
509 case 81:
510 case 89:
511 pa->args[2] = 0;
512 break;
513 case 75: {
514 // InitMemoryMap
515 PromNode *chosen = (PromNode*)gPromRoot->findNode("chosen");
516 PromNode *mm = new PromNode("memory-map");
517 chosen->addNode(mm);
518 pa->args[1] = 0;
519 pa->args[2] = mm->getPHandle();
520 break;
521 }
522 case 593:
523 case 648:
524 // InitDisplay
525 pa->args[4] = 0;
526 pa->args[5] = IO_GCARD_FRAMEBUFFER_PA_START;
527 // gSinglestep = true;
528 break;
529 case 1967:
530 case 1644:
531 // Init SLW
532 pa->args[1] = 0;
533 pa->args[2] = 0xdeadbee2;
534 break;
535 case 1972: // older BootX
536 pa->args[1] = 0;
537 pa->args[2] = 0;
538 pa->args[3] = 0xdeadbee2;
539 break;
540 case 47:
541 case 11:
542 case 21:
543 case 36:
544 case 116:
545 case 152:
546 case 10722:
547 pa->args[1] = 0;
548 pa->args[2] = 0;
549 break;
550 default:
551 IO_PROM_ERR("unknown interpret size %d\ninterpret: %y\n", arg.length(), &arg);
552 break;
553 }
554 }
555 void prom_service_set_callback(prom_args *pa)
556 {
557 //; of_set_callback(void *newfunc, void **oldfunc)
558 IO_PROM_ERR("callback()\n");
559 }
560 void prom_service_set_symbol_lookup(prom_args *pa)
561 {
562 //; of_set_symbol_lookup(void *sym_to_value, void *value_to_sym)
563 IO_PROM_ERR("symbol-lookup()\n");
564 }
565 void prom_service_milliseconds(prom_args *pa)
566 {
567 static uint32 start = (sys_get_hiresclk_ticks() / (sys_get_hiresclk_ticks_per_second()/1000));
568 //; of_milliseconds(int *ms)
569 uint32 millis = (uint32)(sys_get_hiresclk_ticks() / (sys_get_hiresclk_ticks_per_second()/1000)) - start;
570 IO_PROM_TRACE("milliseconds()\n");
571 pa->args[0] = millis;
572 IO_PROM_TRACE("= %08x\n", pa->args[0]);
573 }
574
575 typedef void (*prom_service_function)(prom_args *pa);
576
577 struct prom_service_desc {
578 const char *name;
579 prom_service_function f;
580 };
581
582 prom_service_desc prom_service_table[] = {
583 {"start-cpu", &prom_service_start_cpu},
584 {"quiesce", &prom_service_quiesce},
585 /* 6.3.2.1 Client interface */
586 {"test", &prom_service_test}, //; of_test(const char *name, int *missing)
587 /* 6.3.2.2 Device tree */
588 {"peer", &prom_service_peer}, //; of_peer(int phandle, int *sibling_phandle)
589 {"child", &prom_service_child}, //; (int phandle, int *child_phandle)
590 {"parent", &prom_service_parent}, //; of_parent(int phandle, int *parent_phandle)
591 {"instance-to-package", &prom_service_instance_to_package}, //; of_instance_to_package(int ihandle, int *phandle)
592 {"getproplen", &prom_service_getproplen}, //; of_getproplen(int phandle, const char *name, int *proplen)
593 {"getprop", &prom_service_getprop}, //; of_getprop(int phandle, const char *name, void *buf, int buflen, int *size)
594 {"nextprop", &prom_service_nextprop}, //; of_nextprop(int phandle, const char *previous, void *buf, int *flag)
595 {"setprop", &prom_service_setprop}, //; of_setprop(int phandle, const char *name, void *buf, int len, int *size)
596 {"canon", &prom_service_canon}, //; of_canon(const char *device_specifier, void *buf, int buflen, int *length)
597 {"finddevice", &prom_service_finddevice}, //; of_finddevice(const char *device_specifier, int *phandle)
598 {"instance-to-path", &prom_service_instance_to_path}, //; of_instance_to_path(int ihandle, void *buf, int buflen, int *length)
599 {"package-to-path", &prom_service_package_to_path}, //; of_package_to_path(int phandle, void *buf, int buflen, int *length)
600 {"call-method", &prom_service_call_method}, //; int of_call_method(const char *method, int ihandle, ...); */
601 /* 6.3.2.3 Device I/O */
602 {"open", &prom_service_open}, //; of_open(const char *device_specifier, int *ihandle)
603 {"close", &prom_service_close}, //; of_close(int ihandle)
604 {"read", &prom_service_read}, //; of_read(int ihandle, void *addr, int len, int *actual)
605 {"write", &prom_service_write}, //; of_write(int ihandle, void *addr, int len, int *actual)
606 {"seek", &prom_service_seek}, //; of_seek(int ihandle, int pos_hi, int pos_lo, int *status)
607 /* 6.3.2.4 Memory */
608 {"claim", &prom_service_claim}, //; of_claim(void *virt, int size, int align, void **baseaddr)
609 {"release", &prom_service_release}, //; of_release(void *virt, int size)
610 /* 6.3.2.5 Control transfer */
611 {"boot", &prom_service_boot}, //; of_boot(const char *bootspec)
612 {"enter", &prom_service_enter}, //; of_enter(void)
613 {"exit", &prom_service_exit}, //; of_exit(void)
614 {"chain", &prom_service_chain}, //; of_chain(void *virt, int size, void *entry, void *args, int len);
615 /* 6.3.2.6 User interface */
616 {"interpret", &prom_service_interpret}, //; of_(const char *arg, ...);
617 {"set-callback", &prom_service_set_callback}, //; of_set_callback(void *newfunc, void **oldfunc)
618 {"set-symbol-lookup", &prom_service_set_symbol_lookup}, //; of_set_symbol_lookup(void *sym_to_value, void *value_to_sym)
619 /* 6.3.2.7 Time */
620 {"milliseconds", &prom_service_milliseconds}, //; of_milliseconds(int *ms)
621 {"get-msecs", &prom_service_milliseconds}, //; of_milliseconds(int *ms)
622 {NULL, NULL}
623 };
624
625 void call_prom_osi()
626 {
627 prom_args pa;
628 memset(&pa, 0, sizeof pa);
629 uint32 pa_s = ppc_cpu_get_gpr(0, 3);
630 uint32 phys;
631 if (!ppc_prom_effective_to_physical(phys, pa_s)
632 || !ppc_dma_read(&pa.service, phys+0, 4)
633 || !ppc_dma_read(&pa.nargs, phys+4, 4)
634 || !ppc_dma_read(&pa.nret, phys+8, 4)) {
635 IO_PROM_ERR("can't read memory at %08x-%08x\n", pa_s+0, pa_s+8);
636 }
637 pa.service = ppc_word_from_BE(pa.service);
638 pa.nargs = ppc_word_from_BE(pa.nargs);
639 pa.nret = ppc_word_from_BE(pa.nret);
640 phys += 12;
641 for (uint i=0; i<pa.nargs; i++) {
642 if (!ppc_dma_read(&pa.args[i], phys, 4)) {
643 IO_PROM_ERR("can't read memory at %08x\n", pa.args[i]);
644 }
645 pa.args[i] = ppc_word_from_BE(pa.args[i]);
646 phys += 4;
647 }
648 String service;
649 prom_get_string(service, pa.service);
650 int i=0;
651 while (prom_service_table[i].name) {
652 if (strcmp(prom_service_table[i].name, service.contentChar())==0) {
653 prom_service_table[i].f(&pa);
654 goto ok;
655 }
656 i++;
657 }
658 // error
659 IO_PROM_ERR("unknown service '%y'\n", &service);
660 ok:
661 // write values back
662 pa_s = ppc_cpu_get_gpr(0, 3);
663 pa_s += 12;
664 for (uint i=0; i<(pa.nargs+pa.nret); i++) {
665 uint32 phys;
666 if (!ppc_prom_effective_to_physical(phys, pa_s)) {
667 IO_PROM_ERR("can't write memory at %08x\n", pa.args[i]);
668 }
669 uint32 w = ppc_word_to_BE(pa.args[i]);
670 if (!ppc_dma_write(phys, &w, 4)) {
671 IO_PROM_ERR("can't write memory at %08x\n", pa.args[i]);
672 }
673 pa_s += 4;
674 }
675 ppc_cpu_set_gpr(0, 3, 0);
676 // return
677 // gCPU.npc = gCPU.lr;
678 }

  ViewVC Help
Powered by ViewVC 1.1.26