/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide 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 dpavlin 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