/[gxemul]/trunk/src/promemul/of.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/promemul/of.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 21 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: of.c,v 1.3 2005/09/01 13:27:13 debug Exp $   *  $Id: of.c,v 1.18 2006/02/16 05:57:10 debug Exp $
29   *   *
30   *  OpenFirmware emulation.   *  OpenFirmware emulation.
31   *   *
32   *  Development notes: Care must be taken so that the code in here works   *  NOTE: OpenFirmware is used on quite a variety of different hardware archs,
33   *  with (at least) POWER/PowerPC, ARM, and SPARC.   *        at least POWER/PowerPC, ARM, and SPARC, so the code in this module
34     *        must always remain architecture agnostic.
35     *
36     *  NOTE: Some things, e.g. 32-bit integers as returned by the "getprop"
37     *        service, are always fixed to big-endian. (According to the standard.)
38     *
39     *  TODO: o) 64-bit OpenFirmware?
40     *        o) More devices...
41   */   */
42    
43  #include <stdio.h>  #include <stdio.h>
# Line 38  Line 45 
45  #include <string.h>  #include <string.h>
46  #include <sys/types.h>  #include <sys/types.h>
47    
48    #define OF_C
49    
50  #include "console.h"  #include "console.h"
51  #include "cpu.h"  #include "cpu.h"
52    #include "device.h"
53    #include "devices.h"
54    #include "diskimage.h"
55  #include "machine.h"  #include "machine.h"
56  #include "memory.h"  #include "memory.h"
57  #include "misc.h"  #include "misc.h"
58    #include "of.h"
59    
60    
61  #define N_MAX_ARGS      10  /*  #define debug fatal  */
 #define ARG_MAX_LEN     4096  
62    
63  extern int quiet_mode;  extern int quiet_mode;
64    extern int verbose;
 /*  TODO: IMPORTANT! Change this into something else, to allow multiple  
         opens of the same device:  */  
 #define HANDLE_STDIN    0  
 #define HANDLE_STDOUT   1  
 #define HANDLE_STDERR   2  
 #define HANDLE_MMU      3  
 #define HANDLE_MEMORY   4  
 #define HANDLE_CHOSEN   5  
65    
66    
67  /*  /*
# Line 86  static void readstr(struct cpu *cpu, uin Line 90  static void readstr(struct cpu *cpu, uin
90    
91    
92  /*  /*
93     *  of_store_32bit_in_host():
94     *
95     *  Store big-endian. OpenFirmware properties returned by getprop etc are
96     *  always big-endian, even on little-endian machines.
97     */
98    static void of_store_32bit_in_host(unsigned char *d, uint32_t x)
99    {
100            d[0] = x >> 24; d[1] = x >> 16;
101            d[2] = x >>  8; d[3] = x;
102    }
103    
104    
105    /*
106     *  find_device_handle():
107     *
108     *  name may consist of multiple names, separaed with slashes.
109     */
110    static int find_device_handle(struct of_data *ofd, char *name)
111    {
112            int handle = 1, cur_parent = 1;
113    
114            if (name[0] == 0)
115                    return 0;
116    
117            for (;;) {
118                    struct of_device *od = ofd->of_devices;
119                    char tmp[200];
120                    int i;
121    
122                    while (name[0] == '/')
123                            name++;
124                    if (name[0] == '\0')
125                            break;
126                    snprintf(tmp, sizeof(tmp), "%s", name);
127                    i = 0;
128                    while (tmp[i] != '\0' && tmp[i] != '/')
129                            i++;
130                    tmp[i] = '\0';
131    
132                    OF_FIND(od, strcmp(od->name, tmp) == 0 &&
133                        od->parent == cur_parent);
134                    if (od == NULL)
135                            return -1;
136    
137                    handle = cur_parent = od->handle;
138                    name += strlen(tmp);
139            }
140    
141            return handle;
142    }
143    
144    
145    /*****************************************************************************/
146    
147    
148    OF_SERVICE(call_method_2_2)
149    {
150            fatal("[ of: call_method_2_2('%s'): TODO ]\n", arg[0]);
151            return -1;
152    }
153    
154    
155    OF_SERVICE(call_method_3_4)
156    {
157            fatal("[ of: call_method_3_4('%s'): TODO ]\n", arg[0]);
158            return -1;
159    }
160    
161    
162    OF_SERVICE(call_method_5_2)
163    {
164            if (strcmp(arg[0], "set-colors") == 0) {
165                    /*  Used by OpenBSD/macppc:  */
166                    struct vfb_data *v = cpu->machine->of_data->vfb_data;
167                    int color = OF_GET_ARG(3);
168                    uint64_t ptr = OF_GET_ARG(4);
169                    unsigned char rgb[3];
170                    cpu->memory_rw(cpu, cpu->mem, ptr, rgb, 3, MEM_READ,
171                        CACHE_DATA | NO_EXCEPTIONS);
172                    if (v != NULL) {
173                            memcpy(v->rgb_palette + 3 * color, rgb, 3);
174                            v->update_x1 = v->update_y1 = 0;
175                            v->update_x2 = v->xsize - 1;
176                            v->update_y2 = v->ysize - 1;
177                    }
178            } else {
179                    fatal("[ of: call_method_5_2('%s'): TODO ]\n", arg[0]);
180                    return -1;
181            }
182            return 0;
183    }
184    
185    
186    OF_SERVICE(call_method_6_1)
187    {
188            fatal("[ of: call_method_6_1('%s'): TODO ]\n", arg[0]);
189            return -1;
190    }
191    
192    
193    OF_SERVICE(call_method_6_2)
194    {
195            fatal("[ of: call_method_6_2('%s'): TODO ]\n", arg[0]);
196            return -1;
197    }
198    
199    
200    OF_SERVICE(child)
201    {
202            struct of_device *od = cpu->machine->of_data->of_devices;
203            int handle = OF_GET_ARG(0);
204            OF_FIND(od, od->parent == handle);
205            store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->handle);
206            return 0;
207    }
208    
209    
210    OF_SERVICE(exit)
211    {
212            cpu->running = 0;
213            return 0;
214    }
215    
216    
217    OF_SERVICE(finddevice)
218    {
219            int h = find_device_handle(cpu->machine->of_data, arg[0]);
220            store_32bit_word(cpu, base + retofs, h);
221            return h>0? 0 : -1;
222    }
223    
224    
225    OF_SERVICE(getprop)
226    {
227            struct of_device *od = cpu->machine->of_data->of_devices;
228            struct of_device_property *pr;
229            int handle = OF_GET_ARG(0), i, len_returned = 0;
230            uint64_t buf = OF_GET_ARG(2);
231            uint64_t max = OF_GET_ARG(3);
232    
233            OF_FIND(od, od->handle == handle);
234            if (od == NULL) {
235                    fatal("[ of: WARNING: getprop handle=%i; no such handle ]\n",
236                        handle);
237                    return -1;
238            }
239    
240            pr = od->properties;
241            OF_FIND(pr, strcmp(pr->name, arg[1]) == 0);
242            if (pr == NULL) {
243                    fatal("[ of: WARNING: getprop: no property '%s' at handle"
244                        " %i (device '%s') ]\n", arg[1], handle, od->name);
245                    /*  exit(1);  */
246                    return -1;
247            }
248    
249            if (pr->data == NULL) {
250                    fatal("[ of: WARNING: property '%s' of '%s' has no data! ]\n",
251                        arg[1], od->name);
252                    goto ret;
253            }
254    
255            /*  Return the property into emulated RAM:  */
256            len_returned = pr->len <= max? pr->len : max;
257    
258            for (i=0; i<len_returned; i++) {
259                    if (!cpu->memory_rw(cpu, cpu->mem, buf + i, pr->data + i,
260                        1, MEM_WRITE, CACHE_DATA | NO_EXCEPTIONS)) {
261                            fatal("[ of: getprop memory_rw() error ]\n");
262                            exit(1);
263                    }
264            }
265    
266    ret:
267            store_32bit_word(cpu, base + retofs, len_returned);
268            return 0;
269    }
270    
271    
272    OF_SERVICE(getproplen)
273    {
274            struct of_device *od = cpu->machine->of_data->of_devices;
275            struct of_device_property *pr;
276            int handle = OF_GET_ARG(0);
277    
278            OF_FIND(od, od->handle == handle);
279            if (od == NULL) {
280                    fatal("[ of: WARNING: getproplen handle=%i; no such handle ]\n",
281                        handle);
282                    exit(1);
283                    /*  return -1;  */
284            }
285    
286            pr = od->properties;
287            OF_FIND(pr, strcmp(pr->name, arg[1]) == 0);
288            if (pr == NULL) {
289                    fatal("[ of: WARNING: getproplen: no property '%s' at handle"
290                        " %i (device '%s') ]\n", arg[1], handle, od->name);
291                    exit(1);
292            }
293    
294            store_32bit_word(cpu, base + retofs, pr->len);
295            return 0;
296    }
297    
298    
299    OF_SERVICE(instance_to_package)
300    {
301            int handle = OF_GET_ARG(0);
302            /*  TODO: actually do something here? :-)  */
303            store_32bit_word(cpu, base + retofs, handle);
304            return 0;
305    }
306    
307    
308    OF_SERVICE(interpret_1)
309    {
310            if (strcmp(arg[0], "#lines 2 - to line#") == 0) {
311            } else {
312                    fatal("[ of: interpret_1('%s'): TODO ]\n", arg[0]);
313                    return -1;
314            }
315            return 0;
316    }
317    
318    
319    OF_SERVICE(interpret_2)
320    {
321            store_32bit_word(cpu, base + retofs, 0);        /*  ?  TODO  */
322            if (strcmp(arg[0], "#columns") == 0) {
323                    store_32bit_word(cpu, base + retofs + 4, 80);
324            } else if (strcmp(arg[0], "#lines") == 0) {
325                    store_32bit_word(cpu, base + retofs + 4, 40);
326            } else if (strcmp(arg[0], "char-height") == 0) {
327                    store_32bit_word(cpu, base + retofs + 4, 15);
328            } else if (strcmp(arg[0], "char-width") == 0) {
329                    store_32bit_word(cpu, base + retofs + 4, 10);
330            } else if (strcmp(arg[0], "line#") == 0) {
331                    store_32bit_word(cpu, base + retofs + 4, 0);
332            } else if (strcmp(arg[0], "font-adr") == 0) {
333                    store_32bit_word(cpu, base + retofs + 4, 0);
334            } else {
335                    fatal("[ of: interpret_2('%s'): TODO ]\n", arg[0]);
336                    return -1;
337            }
338            return 0;
339    }
340    
341    
342    OF_SERVICE(package_to_path)
343    {
344            fatal("[ of: package-to-path: TODO ]\n");
345            return -1;
346    }
347    
348    
349    OF_SERVICE(parent)
350    {
351            struct of_device *od = cpu->machine->of_data->of_devices;
352            int handle = OF_GET_ARG(0);
353            OF_FIND(od, od->handle == handle);
354            store_32bit_word(cpu, base + retofs, od == NULL? 0 : od->parent);
355            return 0;
356    }
357    
358    
359    OF_SERVICE(peer)
360    {
361            struct of_device *od = cpu->machine->of_data->of_devices;
362            int handle = OF_GET_ARG(0), parent = 0, peer = 0, seen_self = 1;
363    
364            if (handle == 0) {
365                    /*  Return the handle of the root node (1):  */
366                    store_32bit_word(cpu, base + retofs, 1);
367                    return 0;
368            }
369    
370            OF_FIND(od, od->handle == handle);
371            if (od == NULL) {
372                    fatal("[ of: peer(): can't find handle %i ]\n", handle);
373                    exit(1);
374            }
375            parent = od->parent;
376            seen_self = 0;
377    
378            od = cpu->machine->of_data->of_devices;
379    
380            while (od != NULL) {
381                    if (od->parent == parent) {
382                            if (seen_self) {
383                                    peer = od->handle;
384                                    break;
385                            }
386                            if (od->handle == handle)
387                                    seen_self = 1;
388                    }
389                    od = od->next;
390            }
391            store_32bit_word(cpu, base + retofs, peer);
392            return 0;
393    }
394    
395    
396    OF_SERVICE(read)
397    {
398            /*  int handle = OF_GET_ARG(0);  */
399            uint64_t ptr = OF_GET_ARG(1);
400            /*  int len = OF_GET_ARG(2);  */
401            int c;
402            unsigned char ch;
403    
404            /*  TODO: check handle! This just reads chars from the console!  */
405            /*  TODO: This is blocking!  */
406    
407            c = console_readchar(cpu->machine->main_console_handle);
408            ch = c;
409            if (!cpu->memory_rw(cpu, cpu->mem, ptr, &ch, 1, MEM_WRITE,
410                CACHE_DATA | NO_EXCEPTIONS)) {
411                    fatal("[ of: read: memory_rw() error ]\n");
412                    exit(1);
413            }
414    
415            store_32bit_word(cpu, base + retofs, c == -1? 0 : 1);
416            return c == -1? -1 : 0;
417    }
418    
419    
420    OF_SERVICE(write)
421    {
422            /*  int handle = OF_GET_ARG(0);  */
423            uint64_t ptr = OF_GET_ARG(1);
424            int n_written = 0, i, len = OF_GET_ARG(2);
425    
426            /*  TODO: check handle! This just dumps the data to the console!  */
427    
428            for (i=0; i<len; i++) {
429                    unsigned char ch;
430                    if (!cpu->memory_rw(cpu, cpu->mem, ptr + i, &ch,
431                        1, MEM_READ, CACHE_DATA | NO_EXCEPTIONS)) {
432                            fatal("[ of: write: memory_rw() error ]\n");
433                            exit(1);
434                    }
435                    if (ch != 7)
436                            console_putchar(cpu->machine->main_console_handle, ch);
437                    n_written ++;
438            }
439    
440            store_32bit_word(cpu, base + retofs, n_written);
441            return 0;
442    }
443    
444    
445    /*****************************************************************************/
446    
447    
448    /*
449     *  of_get_unused_device_handle():
450     *
451     *  Returns an unused device handle number (1 or higher).
452     */
453    static int of_get_unused_device_handle(struct of_data *of_data)
454    {
455            int max_handle = 0;
456            struct of_device *od = of_data->of_devices;
457    
458            while (od != NULL) {
459                    if (od->handle > max_handle)
460                            max_handle = od->handle;
461                    od = od->next;
462            }
463    
464            return max_handle + 1;
465    }
466    
467    
468    /*
469     *  of_add_device():
470     *
471     *  Adds a device.
472     */
473    static struct of_device *of_add_device(struct of_data *of_data, char *name,
474            char *parentname)
475    {
476            struct of_device *od = malloc(sizeof(struct of_device));
477            if (od == NULL)
478                    goto bad;
479            memset(od, 0, sizeof(struct of_device));
480    
481            od->name = strdup(name);
482            if (od->name == NULL)
483                    goto bad;
484    
485            od->handle = of_get_unused_device_handle(of_data);
486            od->parent = find_device_handle(of_data, parentname);
487            if (od->parent < 0) {
488                    fatal("of_add_device(): adding '%s' to parent '%s' failed: "
489                        "parent not found!\n", name, parentname);
490                    exit(1);
491            }
492    
493            od->next = of_data->of_devices;
494            of_data->of_devices = od;
495            return od;
496    
497    bad:
498            fatal("of_add_device(): out of memory\n");
499            exit(1);
500    }
501    
502    
503    /*
504     *  of_add_prop():
505     *
506     *  Adds a property to a device.
507     */
508    static void of_add_prop(struct of_data *of_data, char *devname,
509            char *propname, unsigned char *data, uint32_t len, int flags)
510    {
511            struct of_device_property *pr =
512                malloc(sizeof(struct of_device_property));
513            struct of_device *od = of_data->of_devices;
514            int h = find_device_handle(of_data, devname);
515    
516            OF_FIND(od, od->handle == h);
517            if (od == NULL) {
518                    fatal("of_add_prop(): device '%s' not registered\n", devname);
519                    exit(1);
520            }
521    
522            if (pr == NULL)
523                    goto bad;
524            memset(pr, 0, sizeof(struct of_device_property));
525    
526            pr->name = strdup(propname);
527            if (pr->name == NULL)
528                    goto bad;
529            pr->data = data;
530            pr->len = len;
531            pr->flags = flags;
532    
533            pr->next = od->properties;
534            od->properties = pr;
535            return;
536    
537    bad:
538            fatal("of_add_device(): out of memory\n");
539            exit(1);
540    }
541    
542    
543    /*
544     *  of_add_service():
545     *
546     *  Adds a service.
547     */
548    static void of_add_service(struct of_data *of_data, char *name,
549            int (*f)(OF_SERVICE_ARGS), int n_args, int n_ret_args)
550    {
551            struct of_service *os = malloc(sizeof(struct of_service));
552            if (os == NULL)
553                    goto bad;
554            memset(os, 0, sizeof(struct of_service));
555    
556            os->name = strdup(name);
557            if (os->name == NULL)
558                    goto bad;
559    
560            os->f = f;
561            os->n_args = n_args;
562            os->n_ret_args = n_ret_args;
563    
564            os->next = of_data->of_services;
565            of_data->of_services = os;
566            return;
567    
568    bad:
569            fatal("of_add_service(): out of memory\n");
570            exit(1);
571    }
572    
573    
574    /*
575     *  of_dump_devices():
576     *
577     *  Debug dump helper.
578     */
579    static void of_dump_devices(struct of_data *ofd, int parent)
580    {
581            int iadd = DEBUG_INDENTATION;
582            struct of_device *od = ofd->of_devices;
583    
584            while (od != NULL) {
585                    struct of_device_property *pr = od->properties;
586                    if (od->parent != parent) {
587                            od = od->next;
588                            continue;
589                    }
590                    debug("\"%s\"\n", od->name, od->handle);
591                    debug_indentation(iadd);
592                    while (pr != NULL) {
593                            debug("(%s: ", pr->name);
594                            if (pr->flags == OF_PROP_STRING)
595                                    debug("\"%s\"", pr->data);
596                            else
597                                    debug("%i bytes", pr->len);
598                            debug(")\n");
599                            pr = pr->next;
600                    }
601                    of_dump_devices(ofd, od->handle);
602                    debug_indentation(-iadd);
603                    od = od->next;
604            }
605    }
606    
607    
608    /*
609     *  of_dump_all():
610     *
611     *  Debug dump.
612     */
613    static void of_dump_all(struct of_data *ofd)
614    {
615            int iadd = DEBUG_INDENTATION;
616            struct of_service *os;
617    
618            debug("openfirmware debug dump:\n");
619            debug_indentation(iadd);
620    
621            /*  Devices:  */
622            of_dump_devices(ofd, 0);
623    
624            /*  Services:  */
625            os = ofd->of_services;
626            while (os != NULL) {
627                    debug("service '%s'", os->name);
628                    if (os->n_ret_args > 0 || os->n_args > 0) {
629                            debug(" (");
630                            if (os->n_args > 0) {
631                                    debug("%i arg%s", os->n_args,
632                                        os->n_args > 1? "s" : "");
633                                    if (os->n_ret_args > 0)
634                                            debug(", ");
635                            }
636                            if (os->n_ret_args > 0)
637                                    debug("%i return value%s", os->n_ret_args,
638                                        os->n_ret_args > 1? "s" : "");
639                            debug(")");
640                    }
641                    debug("\n");
642                    os = os->next;
643            }
644    
645            debug_indentation(-iadd);
646    }
647    
648    
649    /*
650     *  of_add_prop_int32():
651     *
652     *  Helper function.
653     */
654    static void of_add_prop_int32(struct of_data *ofd,
655            char *devname, char *propname, uint32_t x)
656    {
657            unsigned char *p = malloc(sizeof(int32_t));
658            if (p == NULL) {
659                    fatal("of_add_prop_int32(): out of memory\n");
660                    exit(1);
661            }
662            of_store_32bit_in_host(p, x);
663            of_add_prop(ofd, devname, propname, p, sizeof(int32_t),
664                OF_PROP_INT);
665    }
666    
667    
668    /*
669     *  of_add_prop_str():
670     *
671     *  Helper function.
672     */
673    static void of_add_prop_str(struct machine *machine, struct of_data *ofd,
674            char *devname, char *propname, char *data)
675    {
676            char *p = strdup(data);
677            if (p == NULL) {
678                    fatal("of_add_prop_str(): out of memory\n");
679                    exit(1);
680            }
681    
682            of_add_prop(ofd, devname, propname, (unsigned char *)p, strlen(p) + 1,
683                OF_PROP_STRING);
684    }
685    
686    
687    /*
688     *  of_emul_init_isa():
689     */
690    void of_emul_init_isa(struct machine *machine)
691    {
692            struct of_data *ofd = machine->of_data;
693            unsigned char *isa_ranges;
694    
695            of_add_device(ofd, "isa", "/");
696            isa_ranges = malloc(32);
697            if (isa_ranges == NULL)
698                    goto bad;
699            memset(isa_ranges, 0, 32);
700            /*  2 *: isa_phys_hi, isa_phys_lo, parent_phys_start, size  */
701            /*  MEM space:  */
702            of_store_32bit_in_host(isa_ranges + 0, 0);
703            of_store_32bit_in_host(isa_ranges + 4, 0xc0000000);
704            /*  I/O space: low bit if isa_phys_hi set  */
705            of_store_32bit_in_host(isa_ranges + 16, 1);
706            of_store_32bit_in_host(isa_ranges + 20, 0xd0000000);
707    
708            of_add_prop(ofd, "/isa", "ranges", isa_ranges, 32, 0);
709    
710            return;
711    
712    bad:
713            fatal("of_emul_init_isa(): out of memory\n");
714            exit(1);
715    }
716    
717    
718    /*
719     *  of_emul_init_adb():
720     */
721    void of_emul_init_adb(struct machine *machine)
722    {
723            struct of_data *ofd = machine->of_data;
724            unsigned char *adb_interrupts, *adb_reg;
725    
726            adb_interrupts = malloc(4 * sizeof(uint32_t));
727            adb_reg = malloc(8 * sizeof(uint32_t));
728            if (adb_interrupts == NULL || adb_reg == NULL)
729                    goto bad;
730    
731            of_add_device(ofd, "adb", "/bandit/gc");
732            of_add_prop_str(machine, ofd, "/bandit/gc/adb", "name", "via-cuda");
733            of_store_32bit_in_host(adb_interrupts + 0, 25);
734            of_store_32bit_in_host(adb_interrupts + 4, 0);
735            of_store_32bit_in_host(adb_interrupts + 8, 0);
736            of_store_32bit_in_host(adb_interrupts + 12, 0);
737            of_add_prop(ofd, "/bandit/gc/adb", "interrupts", adb_interrupts,
738                4*sizeof(uint32_t), 0);
739            of_store_32bit_in_host(adb_reg + 0, 0x16000);
740            of_store_32bit_in_host(adb_reg + 4, 0x2000);
741            of_store_32bit_in_host(adb_reg + 8, 0);
742            of_store_32bit_in_host(adb_reg + 12, 0);
743            of_store_32bit_in_host(adb_reg + 16, 0);
744            of_store_32bit_in_host(adb_reg + 20, 0);
745            of_store_32bit_in_host(adb_reg + 24, 0);
746            of_store_32bit_in_host(adb_reg + 28, 0);
747            of_add_prop(ofd, "/bandit/gc/adb", "reg", adb_reg,
748                8*sizeof(uint32_t), 0);
749    
750            return;
751    
752    bad:
753            fatal("of_emul_init_adb(): out of memory\n");
754            exit(1);
755    }
756    
757    
758    /*
759     *  of_emul_init_zs():
760     */
761    void of_emul_init_zs(struct machine *machine)
762    {
763            struct of_data *ofd = machine->of_data;
764            unsigned char *zs_interrupts, *zs_reg;
765    
766            zs_reg = malloc(6 * sizeof(uint32_t));
767            if (zs_reg == NULL)
768                    goto bad;
769    
770            /*  The controller:  */
771            of_add_device(ofd, "zs", "/bandit/gc");
772            of_add_prop_str(machine, ofd, "/bandit/gc/zs", "device_type", "serial");
773            of_add_prop_str(machine, ofd, "/bandit/gc/zs", "name", "escc");
774            of_store_32bit_in_host(zs_reg + 0, 0x13000);
775            of_store_32bit_in_host(zs_reg + 4, 0x40);
776            of_store_32bit_in_host(zs_reg + 8, 0x100);
777            of_store_32bit_in_host(zs_reg + 12, 0x100);
778            of_store_32bit_in_host(zs_reg + 16, 0x200);
779            of_store_32bit_in_host(zs_reg + 20, 0x100);
780            of_add_prop(ofd, "/bandit/gc/zs", "reg", zs_reg, 6*sizeof(uint32_t), 0);
781    
782            /*  Port 1:  */
783            zs_interrupts = malloc(3 * sizeof(uint32_t));
784            zs_reg = malloc(6 * sizeof(uint32_t));
785            if (zs_interrupts == NULL || zs_reg == NULL)
786                    goto bad;
787    
788            of_add_device(ofd, "zstty1", "/bandit/gc/zs");
789            of_add_prop_str(machine, ofd, "/bandit/gc/zs/zstty1", "name", "ch-a");
790            of_store_32bit_in_host(zs_interrupts + 0, 16);
791            of_store_32bit_in_host(zs_interrupts + 4, 0);
792            of_store_32bit_in_host(zs_interrupts + 8, 0);
793            of_add_prop(ofd, "/bandit/gc/zs/zstty1", "interrupts", zs_interrupts,
794                3*sizeof(uint32_t), 0);
795            of_store_32bit_in_host(zs_reg + 0, 0x13800);
796            of_store_32bit_in_host(zs_reg + 4, 0x100);
797            of_store_32bit_in_host(zs_reg + 8, 0x100);
798            of_store_32bit_in_host(zs_reg + 12, 0x100);
799            of_store_32bit_in_host(zs_reg + 16, 0x200);
800            of_store_32bit_in_host(zs_reg + 20, 0x100);
801            of_add_prop(ofd, "/bandit/gc/zs/zstty1",
802                "reg", zs_reg, 6*sizeof(uint32_t), 0);
803    
804            /*  Port 0:  */
805            zs_interrupts = malloc(3 * sizeof(uint32_t));
806            zs_reg = malloc(6 * sizeof(uint32_t));
807            if (zs_interrupts == NULL || zs_reg == NULL)
808                    goto bad;
809    
810            of_add_device(ofd, "zstty0", "/bandit/gc/zs");
811            of_add_prop_str(machine, ofd, "/bandit/gc/zs/zstty0", "name", "ch-b");
812            of_store_32bit_in_host(zs_interrupts + 0, 15);
813            of_store_32bit_in_host(zs_interrupts + 4, 0);
814            of_store_32bit_in_host(zs_interrupts + 8, 0);
815            of_add_prop(ofd, "/bandit/gc/zs/zstty0", "interrupts", zs_interrupts,
816                3*sizeof(uint32_t), 0);
817            of_store_32bit_in_host(zs_reg + 0, 0x13400);
818            of_store_32bit_in_host(zs_reg + 4, 0x100);
819            of_store_32bit_in_host(zs_reg + 8, 0x100);
820            of_store_32bit_in_host(zs_reg + 12, 0x100);
821            of_store_32bit_in_host(zs_reg + 16, 0x200);
822            of_store_32bit_in_host(zs_reg + 20, 0x100);
823            of_add_prop(ofd, "/bandit/gc/zs/zstty0",
824                "reg", zs_reg, 6*sizeof(uint32_t), 0);
825    
826            return;
827    
828    bad:
829            fatal("of_emul_init_zs(): out of memory\n");
830            exit(1);
831    }
832    
833    
834    /*
835     *  of_emul_init_uninorth():
836     */
837    void of_emul_init_uninorth(struct machine *machine)
838    {
839            struct of_data *ofd = machine->of_data;
840            unsigned char *uninorth_reg, *uninorth_bus_range, *uninorth_ranges;
841            unsigned char *macio_aa, *ata_interrupts, *ata_reg;
842            struct of_device *ic;
843            char *n = "pci@e2000000";
844            char *macio = "mac-io";
845    
846            of_add_device(ofd, n, "/");
847            of_add_prop_str(machine, ofd, n, "name", "pci");
848            of_add_prop_str(machine, ofd, n, "device_type", "pci");
849            of_add_prop_str(machine, ofd, n, "compatible", "uni-north");
850    
851            uninorth_reg = malloc(2 * sizeof(uint32_t));
852            uninorth_bus_range = malloc(2 * sizeof(uint32_t));
853            uninorth_ranges = malloc(12 * sizeof(uint32_t));
854            macio_aa = malloc(5 * sizeof(uint32_t));
855            ata_interrupts = malloc(6 * sizeof(uint32_t));
856            ata_reg = malloc(8 * sizeof(uint32_t));
857            if (uninorth_ranges == NULL || uninorth_bus_range == NULL ||
858                uninorth_reg == NULL || macio_aa == NULL ||
859                ata_interrupts == NULL || ata_reg == NULL)
860                    goto bad;
861    
862            of_store_32bit_in_host(uninorth_reg + 0, 0xe2000000);
863            of_store_32bit_in_host(uninorth_reg + 4, 0);    /*  not used?  */
864            of_add_prop(ofd, n, "reg", uninorth_reg, 2*sizeof(uint32_t), 0);
865    
866            of_store_32bit_in_host(uninorth_bus_range + 0, 0);
867            of_store_32bit_in_host(uninorth_bus_range + 4, 0);
868            of_add_prop(ofd, n, "bus-range", uninorth_bus_range,
869                2*sizeof(uint32_t), 0);
870    
871            /*  MEM:  */
872            of_store_32bit_in_host(uninorth_ranges + 0, 0x02000000);
873            of_store_32bit_in_host(uninorth_ranges + 4, 0);
874            of_store_32bit_in_host(uninorth_ranges + 8, 0);
875            of_store_32bit_in_host(uninorth_ranges + 12, 0xd0000000);
876            of_store_32bit_in_host(uninorth_ranges + 16, 0);
877            of_store_32bit_in_host(uninorth_ranges + 20, 0x04000000);
878            /*  IO:  */
879            of_store_32bit_in_host(uninorth_ranges + 24, 0x01000000);
880            of_store_32bit_in_host(uninorth_ranges + 28, 0);
881            of_store_32bit_in_host(uninorth_ranges + 32, 0);
882            of_store_32bit_in_host(uninorth_ranges + 36, 0xe2000000);
883            of_store_32bit_in_host(uninorth_ranges + 40, 0);
884            of_store_32bit_in_host(uninorth_ranges + 44, 0x01000000);
885            of_add_prop(ofd, n, "ranges", uninorth_ranges,
886                12*sizeof(uint32_t), 0);
887    
888            ic = of_add_device(ofd, macio, "/");
889            memset(macio_aa, 0, 20);
890            of_store_32bit_in_host(macio_aa + 0, 15 << 11); /* pci tag */
891            of_store_32bit_in_host(macio_aa + 8, 0xf3000000);
892            of_add_prop(ofd, macio, "assigned-addresses", macio_aa,
893                5*sizeof(uint32_t), 0);
894    /*      of_add_prop(ofd, n, "assigned-addresses", macio_aa,
895                5*sizeof(uint32_t), 0); */
896            of_add_prop_int32(ofd, "/chosen", "interrupt-controller", ic->handle);
897    
898            of_add_device(ofd, "bandit", "/");
899            of_add_device(ofd, "gc", "/bandit");
900            of_add_prop(ofd, "/bandit/gc", "assigned-addresses", macio_aa,
901                5*sizeof(uint32_t), 0);
902    
903            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
904                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
905                    of_add_device(ofd, "ata", "/bandit/gc");
906                    of_add_prop_str(machine, ofd, "/bandit/gc/ata", "name", "ata");
907                    of_add_prop_str(machine, ofd, "/bandit/gc/ata", "compatible",
908                        "heathrow-ata");
909                    of_store_32bit_in_host(ata_interrupts + 0, 13);
910                    of_store_32bit_in_host(ata_interrupts + 4, 0);
911                    of_store_32bit_in_host(ata_interrupts + 8, 0);
912                    of_store_32bit_in_host(ata_interrupts + 12, 0);
913                    of_store_32bit_in_host(ata_interrupts + 16, 0);
914                    of_store_32bit_in_host(ata_interrupts + 20, 0);
915                    of_add_prop(ofd, "/bandit/gc/ata", "interrupts", ata_interrupts,
916                        6*sizeof(uint32_t), 0);
917                    of_store_32bit_in_host(ata_reg + 0, 0x20000);
918                    of_store_32bit_in_host(ata_reg + 4, 0);
919                    of_store_32bit_in_host(ata_reg + 8, 0x21000);
920                    of_store_32bit_in_host(ata_reg + 12, 0x22000);
921                    of_store_32bit_in_host(ata_reg + 16, 0);
922                    of_store_32bit_in_host(ata_reg + 20, 0);
923                    of_store_32bit_in_host(ata_reg + 24, 0);
924                    of_store_32bit_in_host(ata_reg + 28, 0);
925                    of_add_prop(ofd, "/bandit/gc/ata", "reg", ata_reg,
926                        8*sizeof(uint32_t), 0);
927                    device_add(machine, "wdc addr=0xf3020000 irq=21 "
928                        "addr_mult=0x10");
929            }
930    
931            return;
932    
933    bad:
934            fatal("of_emul_init_uninorth(): out of memory\n");
935            exit(1);
936    }
937    
938    
939    /*
940     *  of_emul_init():
941     *
942     *  This function creates an OpenFirmware emulation instance.
943     */
944    struct of_data *of_emul_init(struct machine *machine, struct vfb_data *vfb_data,
945            uint64_t fb_addr, int fb_xsize, int fb_ysize)
946    {
947            unsigned char *memory_reg, *memory_av;
948            unsigned char *zs_assigned_addresses;
949            struct of_device *mmu, *devstdout, *devstdin;
950            struct of_data *ofd = malloc(sizeof(struct of_data));
951            int i;
952    
953            if (ofd == NULL)
954                    goto bad;
955            memset(ofd, 0, sizeof(struct of_data));
956    
957            ofd->vfb_data = vfb_data;
958    
959            /*  Devices:  */
960    
961            /*  Root = device 1  */
962            of_add_device(ofd, "", "");
963    
964            of_add_device(ofd, "io", "/");
965            devstdin  = of_add_device(ofd, "stdin", "/io");
966            devstdout = of_add_device(ofd, "stdout", "/io");
967    
968            if (machine->use_x11) {
969                    fatal("!\n!  TODO: keyboard + framebuffer for MacPPC\n!\n");
970    
971                    of_add_prop_str(machine, ofd, "/io/stdin", "name",
972                        "keyboard");
973                    of_add_prop_str(machine, ofd, "/io", "name", "adb");
974    
975                    of_add_prop_str(machine, ofd, "/io/stdout", "device_type",
976                        "display");
977                    of_add_prop_int32(ofd, "/io/stdout", "width", fb_xsize);
978                    of_add_prop_int32(ofd, "/io/stdout", "height", fb_ysize);
979                    of_add_prop_int32(ofd, "/io/stdout", "linebytes", fb_xsize * 1);
980                    of_add_prop_int32(ofd, "/io/stdout", "depth", 8);
981                    of_add_prop_int32(ofd, "/io/stdout", "address", fb_addr);
982            } else {
983                    zs_assigned_addresses = malloc(12);
984                    if (zs_assigned_addresses == NULL)
985                            goto bad;
986                    memset(zs_assigned_addresses, 0, 12);
987                    of_add_prop_str(machine, ofd, "/io/stdin", "name", "ch-b");
988                    of_add_prop_str(machine, ofd, "/io/stdin", "device_type",
989                        "serial");
990                    of_add_prop_int32(ofd, "/io/stdin", "reg", 0xf3013000);
991                    of_add_prop(ofd, "/io/stdin", "assigned-addresses",
992                        zs_assigned_addresses, 12, 0);
993    
994                    of_add_prop_str(machine, ofd, "/io/stdout", "device_type",
995                        "serial");
996            }
997    
998            of_add_device(ofd, "cpus", "/");
999            for (i=0; i<machine->ncpus; i++) {
1000                    char tmp[50];
1001                    snprintf(tmp, sizeof(tmp), "@%x", i);
1002                    of_add_device(ofd, tmp, "/cpus");
1003                    snprintf(tmp, sizeof(tmp), "/cpus/@%x", i);
1004                    of_add_prop_str(machine, ofd, tmp, "device_type", "cpu");
1005                    of_add_prop_int32(ofd, tmp, "timebase-frequency",
1006                        machine->emulated_hz / 4);
1007                    of_add_prop_int32(ofd, tmp, "clock-frequency",
1008                        machine->emulated_hz);
1009                    of_add_prop_int32(ofd, tmp, "reg", i);
1010            }
1011    
1012            mmu = of_add_device(ofd, "mmu", "/");
1013    
1014            /*  TODO:  */
1015            of_add_prop(ofd, "/mmu", "translations", NULL, 0, 0);
1016    
1017            of_add_device(ofd, "chosen", "/");
1018            of_add_prop_int32(ofd, "/chosen", "mmu", mmu->handle);
1019            of_add_prop_int32(ofd, "/chosen", "stdin", devstdin->handle);
1020            of_add_prop_int32(ofd, "/chosen", "stdout", devstdout->handle);
1021    
1022            of_add_device(ofd, "memory", "/");
1023            memory_reg = malloc(2 * sizeof(uint32_t));
1024            memory_av = malloc(2 * sizeof(uint32_t));
1025            if (memory_reg == NULL || memory_av == NULL)
1026                    goto bad;
1027            of_store_32bit_in_host(memory_reg + 0, 0);
1028            of_store_32bit_in_host(memory_reg + 4, machine->physical_ram_in_mb<<20);
1029            of_store_32bit_in_host(memory_av + 0, 10 << 20);
1030            of_store_32bit_in_host(memory_av + 4,
1031                (machine->physical_ram_in_mb - 10) << 20);
1032            of_add_prop(ofd, "/memory", "reg", memory_reg, 2 * sizeof(uint32_t), 0);
1033            of_add_prop(ofd, "/memory", "available",memory_av,2*sizeof(uint32_t),0);
1034            of_add_prop_str(machine, ofd, "/memory","device_type","memory"/*?*/);
1035    
1036            /*  Services:  */
1037            of_add_service(ofd, "call-method", of__call_method_2_2, 2, 2);
1038            of_add_service(ofd, "call-method", of__call_method_3_4, 3, 4);
1039            of_add_service(ofd, "call-method", of__call_method_5_2, 5, 2);
1040            of_add_service(ofd, "call-method", of__call_method_6_1, 6, 1);
1041            of_add_service(ofd, "call-method", of__call_method_6_2, 6, 2);
1042            of_add_service(ofd, "child", of__child, 1, 1);
1043            of_add_service(ofd, "exit", of__exit, 0, 0);
1044            of_add_service(ofd, "finddevice", of__finddevice, 1, 1);
1045            of_add_service(ofd, "getprop", of__getprop, 4, 1);
1046            of_add_service(ofd, "getproplen", of__getproplen, 2, 1);
1047            of_add_service(ofd, "instance-to-package",
1048                of__instance_to_package, 1, 1);
1049            of_add_service(ofd, "interpret", of__interpret_1, 1, 1);
1050            of_add_service(ofd, "interpret", of__interpret_2, 1, 2);
1051            of_add_service(ofd, "package-to-path", of__package_to_path, 3, 1);
1052            of_add_service(ofd, "parent", of__parent, 1, 1);
1053            of_add_service(ofd, "peer", of__peer, 1, 1);
1054            of_add_service(ofd, "read", of__read, 3, 1);
1055            of_add_service(ofd, "write", of__write, 3, 1);
1056    
1057            if (verbose >= 2)
1058                    of_dump_all(ofd);
1059    
1060            machine->of_data = ofd;
1061            return ofd;
1062    
1063    bad:
1064            fatal("of_emul_init(): out of memory\n");
1065            exit(1);
1066    }
1067    
1068    
1069    /*
1070   *  of_emul():   *  of_emul():
1071   *   *
1072   *  OpenFirmware call emulation.   *  OpenFirmware call emulation.
1073   */   */
1074  int of_emul(struct cpu *cpu)  int of_emul(struct cpu *cpu)
1075  {  {
1076          int i, nargs, nret, ofs, handle, retval;          int i, nargs, nret, ofs, retval = 0;
1077          char service[50];          char service[50];
1078          char arg[N_MAX_ARGS][ARG_MAX_LEN];          char *arg[OF_N_MAX_ARGS];
         char tmpstr[ARG_MAX_LEN];  
1079          uint64_t base, ptr;          uint64_t base, ptr;
1080          uint64_t buf, buflen;          struct of_service *os;
1081            struct of_data *of_data = cpu->machine->of_data;
1082    
1083            if (of_data == NULL) {
1084                    fatal("of_emul(): no of_data struct?\n");
1085                    exit(1);
1086            }
1087    
1088          /*          /*
1089           *  The first argument register points to "prom_args":           *  The first argument register points to "prom_args":
# Line 115  int of_emul(struct cpu *cpu) Line 1101  int of_emul(struct cpu *cpu)
1101          case ARCH_PPC:          case ARCH_PPC:
1102                  base = cpu->cd.ppc.gpr[3];                  base = cpu->cd.ppc.gpr[3];
1103                  break;                  break;
1104          default:          default:fatal("of_emul(): unimplemented arch (TODO)\n");
                 fatal("of_emul(): TODO: unimplemented arch\n");  
1105                  exit(1);                  exit(1);
1106          }          }
1107    
# Line 130  int of_emul(struct cpu *cpu) Line 1115  int of_emul(struct cpu *cpu)
1115          debug("[ of: %s(", service);          debug("[ of: %s(", service);
1116          ofs = 12;          ofs = 12;
1117          for (i=0; i<nargs; i++) {          for (i=0; i<nargs; i++) {
1118                    int x;
1119                  if (i > 0)                  if (i > 0)
1120                          debug(", ");                          debug(", ");
1121                  if (i >= N_MAX_ARGS) {                  if (i >= OF_N_MAX_ARGS) {
1122                          fatal("TOO MANY ARGS!");                          fatal("TOO MANY ARGS!");
1123                          continue;                          continue;
1124                  }                  }
1125                  ptr = load_32bit_word(cpu, base + ofs);                  ptr = load_32bit_word(cpu, base + ofs);
1126                  readstr(cpu, ptr, arg[i], ARG_MAX_LEN);                  arg[i] = malloc(OF_ARG_MAX_LEN + 1);
1127                  if (arg[i][0])                  if (arg[i] == NULL) {
1128                          debug("\"%s\"", arg[i]);                          fatal("out of memory\n");
1129                  else {                          exit(1);
1130                          int x = ptr;                  }
1131                          if (x > -256 && x < 256)                  memset(arg[i], 0, OF_ARG_MAX_LEN + 1);
1132                                  debug("%i", x);                  x = ptr;
1133                    if (x > -256 && x < 256) {
1134                            debug("%i", x);
1135                    } else {
1136                            readstr(cpu, ptr, arg[i], OF_ARG_MAX_LEN);
1137                            if (arg[i][0])
1138                                    debug("\"%s\"", arg[i]);
1139                          else                          else
1140                                  debug("0x%x", x);                                  debug("0x%x", x);
1141                  }                  }
# Line 151  int of_emul(struct cpu *cpu) Line 1143  int of_emul(struct cpu *cpu)
1143          }          }
1144          debug(") ]\n");          debug(") ]\n");
1145    
         /*  Return value:  */  
         retval = 0;  
   
1146          /*  Note: base + ofs points to the first return slot.  */          /*  Note: base + ofs points to the first return slot.  */
1147    
1148          if (strcmp(service, "exit") == 0) {          os = of_data->of_services;
1149                  cpu->running = 0;          while (os != NULL) {
1150          } else if (strcmp(service, "finddevice") == 0) {                  if (strcmp(service, os->name) == 0 &&
1151                  /*  Return a handle in ret[0]:  */                      nargs == os->n_args && nret == os->n_ret_args) {
1152                  if (nret < 1) {                          retval = os->f(cpu, arg, base, ofs);
                         fatal("[ of: finddevice(\"%s\"): nret < 1! ]\n",  
                             arg[0]);  
                 } else if (strcmp(arg[0], "/memory") == 0) {      
                         store_32bit_word(cpu, base + ofs, HANDLE_MEMORY);  
                 } else if (strcmp(arg[0], "/chosen") == 0) {      
                         store_32bit_word(cpu, base + ofs, HANDLE_CHOSEN);  
                 } else {  
                         /*  Device not found.  */  
                         fatal("[ of: finddevice(\"%s\"): not yet"  
                             " implemented ]\n", arg[0]);  
                         retval = -1;  
                 }  
         } else if (strcmp(service, "getprop") == 0) {  
                 handle = load_32bit_word(cpu, base + 12 + 4*0);  
                 ptr    = load_32bit_word(cpu, base + 12 + 4*1);  
                 buf    = load_32bit_word(cpu, base + 12 + 4*2);  
                 buflen = load_32bit_word(cpu, base + 12 + 4*3);  
                 readstr(cpu, ptr, tmpstr, sizeof(tmpstr));  
   
                 /*  TODO: rewrite this  */  
                 switch (handle) {  
                 case HANDLE_MEMORY:  
                         if (strcmp(tmpstr, "available") == 0) {  
                                 store_32bit_word(cpu, base + ofs, 2*8);  
                                 /*  TODO.  {start, size}  */  
                                 store_32bit_word(cpu, buf, 0);  
                                 store_32bit_word(cpu, buf+4,  
                                     cpu->machine->physical_ram_in_mb * 1048576  
                                     - 65536);  
                                 store_32bit_word(cpu, buf+8, 0);  
                                 store_32bit_word(cpu, buf+12, 0);  
                         } else if (strcmp(tmpstr, "reg") == 0) {  
                                 /*  TODO  */  
                                 store_32bit_word(cpu, base + ofs, 33*8);  
                                 store_32bit_word(cpu, buf, 0);  
                                 store_32bit_word(cpu, buf+4,  
                                     cpu->machine->physical_ram_in_mb * 1048576);  
                                 store_32bit_word(cpu, buf+8, 0);  
                                 store_32bit_word(cpu, buf+12, 0);  
                         } else {  
                                 fatal("[ of: getprop(%i,\"%s\"): not yet"  
                                     " implemented ]\n", (int)handle, arg[1]);  
                                 retval = -1;  
                         }  
1153                          break;                          break;
1154                  case HANDLE_CHOSEN:                  }
1155                          if (strcmp(tmpstr, "stdin") == 0) {                  os = os->next;
1156                                  if (buflen >= 4)          }
1157                                          store_32bit_word(cpu, buf,  
1158                                              HANDLE_STDIN);          if (os == NULL) {
                                 store_32bit_word(cpu, base + ofs, 4);  
                         } else if (strcmp(tmpstr, "stdout") == 0) {  
                                 if (buflen >= 4)  
                                         store_32bit_word(cpu, buf,  
                                             HANDLE_STDOUT);  
                                 store_32bit_word(cpu, base + ofs, 4);  
                         } else if (strcmp(tmpstr, "mmu") == 0) {  
                                 if (buflen >= 4)  
                                         store_32bit_word(cpu, buf,  
                                             HANDLE_MMU);  
                                 store_32bit_word(cpu, base + ofs, 4);  
                         } else {  
                                 fatal("[ of: getprop(%i,\"%s\"): not yet"  
                                     " implemented ]\n", (int)handle, arg[1]);  
                                 retval = -1;  
                         }  
                         break;  
                 default:  
                         fatal("[ of: getprop(%i,\"%s\"): not yet"  
                             " implemented ]\n", (int)handle, arg[1]);  
                         retval = -1;  
                 }  
         } else if (strcmp(service, "instance-to-package") == 0) {  
                 /*  TODO: a package handle  */  
                 store_32bit_word(cpu, base + ofs, 1000);  
         } else if (strcmp(service, "getproplen") == 0) {  
                 /*  TODO  */  
                 store_32bit_word(cpu, base + ofs, 0);  
         } else if (strcmp(service, "peer") == 0) {  
                 /*  TODO  */  
                 store_32bit_word(cpu, base + ofs, 0);  
         } else {  
1159                  quiet_mode = 0;                  quiet_mode = 0;
1160                  cpu_register_dump(cpu->machine, cpu, 1, 0);                  cpu_register_dump(cpu->machine, cpu, 1, 0);
1161                  printf("\n");                  printf("\n");
1162                  fatal("[ of_emul(): unimplemented service \"%s\" ]\n", service);                  fatal("[ of: unimplemented service \"%s\" with %i input "
1163                        "args and %i output values ]\n", service, nargs, nret);
1164                  cpu->running = 0;                  cpu->running = 0;
1165                  cpu->dead = 1;                  cpu->dead = 1;
1166          }          }
1167    
1168            for (i=0; i<nargs; i++)
1169                    free(arg[i]);
1170    
1171            /*  Return:  */
1172          switch (cpu->machine->arch) {          switch (cpu->machine->arch) {
1173          case ARCH_ARM:          case ARCH_ARM:
1174                  cpu->cd.arm.r[0] = retval;                  cpu->cd.arm.r[0] = retval;
# Line 258  int of_emul(struct cpu *cpu) Line 1176  int of_emul(struct cpu *cpu)
1176          case ARCH_PPC:          case ARCH_PPC:
1177                  cpu->cd.ppc.gpr[3] = retval;                  cpu->cd.ppc.gpr[3] = retval;
1178                  break;                  break;
1179          default:          default:fatal("of_emul(): TODO: unimplemented arch (Retval)\n");
                 fatal("of_emul(): TODO: unimplemented arch (Retval)\n");  
1180                  exit(1);                  exit(1);
1181          }          }
1182    

Legend:
Removed from v.21  
changed lines
  Added in v.22

  ViewVC Help
Powered by ViewVC 1.1.26