/[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 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 38 by dpavlin, Mon Oct 8 16:21:53 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  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.23 2007/03/24 06:40:16 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->md.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->md.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->md.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->md.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->md.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->md.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->md.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->md.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            return NULL;    /*  Silences a compiler warning  */
502    }
503    
504    
505    /*
506     *  of_add_prop():
507     *
508     *  Adds a property to a device.
509     */
510    static void of_add_prop(struct of_data *of_data, char *devname,
511            char *propname, unsigned char *data, uint32_t len, int flags)
512    {
513            struct of_device_property *pr =
514                malloc(sizeof(struct of_device_property));
515            struct of_device *od = of_data->of_devices;
516            int h = find_device_handle(of_data, devname);
517    
518            OF_FIND(od, od->handle == h);
519            if (od == NULL) {
520                    fatal("of_add_prop(): device '%s' not registered\n", devname);
521                    exit(1);
522            }
523    
524            if (pr == NULL)
525                    goto bad;
526            memset(pr, 0, sizeof(struct of_device_property));
527    
528            pr->name = strdup(propname);
529            if (pr->name == NULL)
530                    goto bad;
531            pr->data = data;
532            pr->len = len;
533            pr->flags = flags;
534    
535            pr->next = od->properties;
536            od->properties = pr;
537            return;
538    
539    bad:
540            fatal("of_add_device(): out of memory\n");
541            exit(1);
542    }
543    
544    
545    /*
546     *  of_add_service():
547     *
548     *  Adds a service.
549     */
550    static void of_add_service(struct of_data *of_data, char *name,
551            int (*f)(OF_SERVICE_ARGS), int n_args, int n_ret_args)
552    {
553            struct of_service *os = malloc(sizeof(struct of_service));
554            if (os == NULL)
555                    goto bad;
556            memset(os, 0, sizeof(struct of_service));
557    
558            os->name = strdup(name);
559            if (os->name == NULL)
560                    goto bad;
561    
562            os->f = f;
563            os->n_args = n_args;
564            os->n_ret_args = n_ret_args;
565    
566            os->next = of_data->of_services;
567            of_data->of_services = os;
568            return;
569    
570    bad:
571            fatal("of_add_service(): out of memory\n");
572            exit(1);
573    }
574    
575    
576    /*
577     *  of_dump_devices():
578     *
579     *  Debug dump helper.
580     */
581    static void of_dump_devices(struct of_data *ofd, int parent)
582    {
583            int iadd = DEBUG_INDENTATION;
584            struct of_device *od = ofd->of_devices;
585    
586            while (od != NULL) {
587                    struct of_device_property *pr = od->properties;
588                    if (od->parent != parent) {
589                            od = od->next;
590                            continue;
591                    }
592                    debug("\"%s\"\n", od->name, od->handle);
593                    debug_indentation(iadd);
594                    while (pr != NULL) {
595                            debug("(%s: ", pr->name);
596                            if (pr->flags == OF_PROP_STRING)
597                                    debug("\"%s\"", pr->data);
598                            else
599                                    debug("%i bytes", pr->len);
600                            debug(")\n");
601                            pr = pr->next;
602                    }
603                    of_dump_devices(ofd, od->handle);
604                    debug_indentation(-iadd);
605                    od = od->next;
606            }
607    }
608    
609    
610    /*
611     *  of_dump_all():
612     *
613     *  Debug dump.
614     */
615    static void of_dump_all(struct of_data *ofd)
616    {
617            int iadd = DEBUG_INDENTATION;
618            struct of_service *os;
619    
620            debug("openfirmware debug dump:\n");
621            debug_indentation(iadd);
622    
623            /*  Devices:  */
624            of_dump_devices(ofd, 0);
625    
626            /*  Services:  */
627            os = ofd->of_services;
628            while (os != NULL) {
629                    debug("service '%s'", os->name);
630                    if (os->n_ret_args > 0 || os->n_args > 0) {
631                            debug(" (");
632                            if (os->n_args > 0) {
633                                    debug("%i arg%s", os->n_args,
634                                        os->n_args > 1? "s" : "");
635                                    if (os->n_ret_args > 0)
636                                            debug(", ");
637                            }
638                            if (os->n_ret_args > 0)
639                                    debug("%i return value%s", os->n_ret_args,
640                                        os->n_ret_args > 1? "s" : "");
641                            debug(")");
642                    }
643                    debug("\n");
644                    os = os->next;
645            }
646    
647            debug_indentation(-iadd);
648    }
649    
650    
651    /*
652     *  of_add_prop_int32():
653     *
654     *  Helper function.
655     */
656    static void of_add_prop_int32(struct of_data *ofd,
657            char *devname, char *propname, uint32_t x)
658    {
659            unsigned char *p = malloc(sizeof(int32_t));
660            if (p == NULL) {
661                    fatal("of_add_prop_int32(): out of memory\n");
662                    exit(1);
663            }
664            of_store_32bit_in_host(p, x);
665            of_add_prop(ofd, devname, propname, p, sizeof(int32_t),
666                OF_PROP_INT);
667    }
668    
669    
670    /*
671     *  of_add_prop_str():
672     *
673     *  Helper function.
674     */
675    static void of_add_prop_str(struct machine *machine, struct of_data *ofd,
676            char *devname, char *propname, char *data)
677    {
678            char *p = strdup(data);
679            if (p == NULL) {
680                    fatal("of_add_prop_str(): out of memory\n");
681                    exit(1);
682            }
683    
684            of_add_prop(ofd, devname, propname, (unsigned char *)p, strlen(p) + 1,
685                OF_PROP_STRING);
686    }
687    
688    
689    /*
690     *  of_emul_init_isa():
691     */
692    void of_emul_init_isa(struct machine *machine)
693    {
694            struct of_data *ofd = machine->md.of_data;
695            unsigned char *isa_ranges;
696    
697            of_add_device(ofd, "isa", "/");
698            isa_ranges = malloc(32);
699            if (isa_ranges == NULL)
700                    goto bad;
701            memset(isa_ranges, 0, 32);
702            /*  2 *: isa_phys_hi, isa_phys_lo, parent_phys_start, size  */
703            /*  MEM space:  */
704            of_store_32bit_in_host(isa_ranges + 0, 0);
705            of_store_32bit_in_host(isa_ranges + 4, 0xc0000000);
706            /*  I/O space: low bit if isa_phys_hi set  */
707            of_store_32bit_in_host(isa_ranges + 16, 1);
708            of_store_32bit_in_host(isa_ranges + 20, 0xd0000000);
709    
710            of_add_prop(ofd, "/isa", "ranges", isa_ranges, 32, 0);
711    
712            return;
713    
714    bad:
715            fatal("of_emul_init_isa(): out of memory\n");
716            exit(1);
717    }
718    
719    
720    /*
721     *  of_emul_init_adb():
722     */
723    void of_emul_init_adb(struct machine *machine)
724    {
725            struct of_data *ofd = machine->md.of_data;
726            unsigned char *adb_interrupts, *adb_reg;
727    
728            adb_interrupts = malloc(4 * sizeof(uint32_t));
729            adb_reg = malloc(8 * sizeof(uint32_t));
730            if (adb_interrupts == NULL || adb_reg == NULL)
731                    goto bad;
732    
733            of_add_device(ofd, "adb", "/bandit/gc");
734            of_add_prop_str(machine, ofd, "/bandit/gc/adb", "name", "via-cuda");
735            of_store_32bit_in_host(adb_interrupts + 0, 25);
736            of_store_32bit_in_host(adb_interrupts + 4, 0);
737            of_store_32bit_in_host(adb_interrupts + 8, 0);
738            of_store_32bit_in_host(adb_interrupts + 12, 0);
739            of_add_prop(ofd, "/bandit/gc/adb", "interrupts", adb_interrupts,
740                4*sizeof(uint32_t), 0);
741            of_store_32bit_in_host(adb_reg + 0, 0x16000);
742            of_store_32bit_in_host(adb_reg + 4, 0x2000);
743            of_store_32bit_in_host(adb_reg + 8, 0);
744            of_store_32bit_in_host(adb_reg + 12, 0);
745            of_store_32bit_in_host(adb_reg + 16, 0);
746            of_store_32bit_in_host(adb_reg + 20, 0);
747            of_store_32bit_in_host(adb_reg + 24, 0);
748            of_store_32bit_in_host(adb_reg + 28, 0);
749            of_add_prop(ofd, "/bandit/gc/adb", "reg", adb_reg,
750                8*sizeof(uint32_t), 0);
751    
752            return;
753    
754    bad:
755            fatal("of_emul_init_adb(): out of memory\n");
756            exit(1);
757    }
758    
759    
760    /*
761     *  of_emul_init_zs():
762     */
763    void of_emul_init_zs(struct machine *machine)
764    {
765            struct of_data *ofd = machine->md.of_data;
766            unsigned char *zs_interrupts, *zs_reg;
767    
768            zs_reg = malloc(6 * sizeof(uint32_t));
769            if (zs_reg == NULL)
770                    goto bad;
771    
772            /*  The controller:  */
773            of_add_device(ofd, "zs", "/bandit/gc");
774            of_add_prop_str(machine, ofd, "/bandit/gc/zs", "device_type", "serial");
775            of_add_prop_str(machine, ofd, "/bandit/gc/zs", "name", "escc");
776            of_store_32bit_in_host(zs_reg + 0, 0x13000);
777            of_store_32bit_in_host(zs_reg + 4, 0x40);
778            of_store_32bit_in_host(zs_reg + 8, 0x100);
779            of_store_32bit_in_host(zs_reg + 12, 0x100);
780            of_store_32bit_in_host(zs_reg + 16, 0x200);
781            of_store_32bit_in_host(zs_reg + 20, 0x100);
782            of_add_prop(ofd, "/bandit/gc/zs", "reg", zs_reg, 6*sizeof(uint32_t), 0);
783    
784            /*  Port 1:  */
785            zs_interrupts = malloc(3 * sizeof(uint32_t));
786            zs_reg = malloc(6 * sizeof(uint32_t));
787            if (zs_interrupts == NULL || zs_reg == NULL)
788                    goto bad;
789    
790            of_add_device(ofd, "zstty1", "/bandit/gc/zs");
791            of_add_prop_str(machine, ofd, "/bandit/gc/zs/zstty1", "name", "ch-a");
792            of_store_32bit_in_host(zs_interrupts + 0, 16);
793            of_store_32bit_in_host(zs_interrupts + 4, 0);
794            of_store_32bit_in_host(zs_interrupts + 8, 0);
795            of_add_prop(ofd, "/bandit/gc/zs/zstty1", "interrupts", zs_interrupts,
796                3*sizeof(uint32_t), 0);
797            of_store_32bit_in_host(zs_reg + 0, 0x13800);
798            of_store_32bit_in_host(zs_reg + 4, 0x100);
799            of_store_32bit_in_host(zs_reg + 8, 0x100);
800            of_store_32bit_in_host(zs_reg + 12, 0x100);
801            of_store_32bit_in_host(zs_reg + 16, 0x200);
802            of_store_32bit_in_host(zs_reg + 20, 0x100);
803            of_add_prop(ofd, "/bandit/gc/zs/zstty1",
804                "reg", zs_reg, 6*sizeof(uint32_t), 0);
805    
806            /*  Port 0:  */
807            zs_interrupts = malloc(3 * sizeof(uint32_t));
808            zs_reg = malloc(6 * sizeof(uint32_t));
809            if (zs_interrupts == NULL || zs_reg == NULL)
810                    goto bad;
811    
812            of_add_device(ofd, "zstty0", "/bandit/gc/zs");
813            of_add_prop_str(machine, ofd, "/bandit/gc/zs/zstty0", "name", "ch-b");
814            of_store_32bit_in_host(zs_interrupts + 0, 15);
815            of_store_32bit_in_host(zs_interrupts + 4, 0);
816            of_store_32bit_in_host(zs_interrupts + 8, 0);
817            of_add_prop(ofd, "/bandit/gc/zs/zstty0", "interrupts", zs_interrupts,
818                3*sizeof(uint32_t), 0);
819            of_store_32bit_in_host(zs_reg + 0, 0x13400);
820            of_store_32bit_in_host(zs_reg + 4, 0x100);
821            of_store_32bit_in_host(zs_reg + 8, 0x100);
822            of_store_32bit_in_host(zs_reg + 12, 0x100);
823            of_store_32bit_in_host(zs_reg + 16, 0x200);
824            of_store_32bit_in_host(zs_reg + 20, 0x100);
825            of_add_prop(ofd, "/bandit/gc/zs/zstty0",
826                "reg", zs_reg, 6*sizeof(uint32_t), 0);
827    
828            return;
829    
830    bad:
831            fatal("of_emul_init_zs(): out of memory\n");
832            exit(1);
833    }
834    
835    
836    /*
837     *  of_emul_init_uninorth():
838     */
839    void of_emul_init_uninorth(struct machine *machine)
840    {
841            struct of_data *ofd = machine->md.of_data;
842            unsigned char *uninorth_reg, *uninorth_bus_range, *uninorth_ranges;
843            unsigned char *macio_aa, *ata_interrupts, *ata_reg;
844            struct of_device *ic;
845            char *n = "pci@e2000000";
846            char *macio = "mac-io";
847    
848            of_add_device(ofd, n, "/");
849            of_add_prop_str(machine, ofd, n, "name", "pci");
850            of_add_prop_str(machine, ofd, n, "device_type", "pci");
851            of_add_prop_str(machine, ofd, n, "compatible", "uni-north");
852    
853            uninorth_reg = malloc(2 * sizeof(uint32_t));
854            uninorth_bus_range = malloc(2 * sizeof(uint32_t));
855            uninorth_ranges = malloc(12 * sizeof(uint32_t));
856            macio_aa = malloc(5 * sizeof(uint32_t));
857            ata_interrupts = malloc(6 * sizeof(uint32_t));
858            ata_reg = malloc(8 * sizeof(uint32_t));
859            if (uninorth_ranges == NULL || uninorth_bus_range == NULL ||
860                uninorth_reg == NULL || macio_aa == NULL ||
861                ata_interrupts == NULL || ata_reg == NULL)
862                    goto bad;
863    
864            of_store_32bit_in_host(uninorth_reg + 0, 0xe2000000);
865            of_store_32bit_in_host(uninorth_reg + 4, 0);    /*  not used?  */
866            of_add_prop(ofd, n, "reg", uninorth_reg, 2*sizeof(uint32_t), 0);
867    
868            of_store_32bit_in_host(uninorth_bus_range + 0, 0);
869            of_store_32bit_in_host(uninorth_bus_range + 4, 0);
870            of_add_prop(ofd, n, "bus-range", uninorth_bus_range,
871                2*sizeof(uint32_t), 0);
872    
873            /*  MEM:  */
874            of_store_32bit_in_host(uninorth_ranges + 0, 0x02000000);
875            of_store_32bit_in_host(uninorth_ranges + 4, 0);
876            of_store_32bit_in_host(uninorth_ranges + 8, 0);
877            of_store_32bit_in_host(uninorth_ranges + 12, 0xd0000000);
878            of_store_32bit_in_host(uninorth_ranges + 16, 0);
879            of_store_32bit_in_host(uninorth_ranges + 20, 0x04000000);
880            /*  IO:  */
881            of_store_32bit_in_host(uninorth_ranges + 24, 0x01000000);
882            of_store_32bit_in_host(uninorth_ranges + 28, 0);
883            of_store_32bit_in_host(uninorth_ranges + 32, 0);
884            of_store_32bit_in_host(uninorth_ranges + 36, 0xe2000000);
885            of_store_32bit_in_host(uninorth_ranges + 40, 0);
886            of_store_32bit_in_host(uninorth_ranges + 44, 0x01000000);
887            of_add_prop(ofd, n, "ranges", uninorth_ranges,
888                12*sizeof(uint32_t), 0);
889    
890            ic = of_add_device(ofd, macio, "/");
891            memset(macio_aa, 0, 20);
892            of_store_32bit_in_host(macio_aa + 0, 15 << 11); /* pci tag */
893            of_store_32bit_in_host(macio_aa + 8, 0xf3000000);
894            of_add_prop(ofd, macio, "assigned-addresses", macio_aa,
895                5*sizeof(uint32_t), 0);
896    /*      of_add_prop(ofd, n, "assigned-addresses", macio_aa,
897                5*sizeof(uint32_t), 0); */
898            of_add_prop_int32(ofd, "/chosen", "interrupt-controller", ic->handle);
899    
900            of_add_device(ofd, "bandit", "/");
901            of_add_device(ofd, "gc", "/bandit");
902            of_add_prop(ofd, "/bandit/gc", "assigned-addresses", macio_aa,
903                5*sizeof(uint32_t), 0);
904    
905            if (diskimage_exist(machine, 0, DISKIMAGE_IDE) ||
906                diskimage_exist(machine, 1, DISKIMAGE_IDE)) {
907                    char tmpstr[400];
908                    of_add_device(ofd, "ata", "/bandit/gc");
909                    of_add_prop_str(machine, ofd, "/bandit/gc/ata", "name", "ata");
910                    of_add_prop_str(machine, ofd, "/bandit/gc/ata", "compatible",
911                        "heathrow-ata");
912                    of_store_32bit_in_host(ata_interrupts + 0, 13);
913                    of_store_32bit_in_host(ata_interrupts + 4, 0);
914                    of_store_32bit_in_host(ata_interrupts + 8, 0);
915                    of_store_32bit_in_host(ata_interrupts + 12, 0);
916                    of_store_32bit_in_host(ata_interrupts + 16, 0);
917                    of_store_32bit_in_host(ata_interrupts + 20, 0);
918                    of_add_prop(ofd, "/bandit/gc/ata", "interrupts", ata_interrupts,
919                        6*sizeof(uint32_t), 0);
920                    of_store_32bit_in_host(ata_reg + 0, 0x20000);
921                    of_store_32bit_in_host(ata_reg + 4, 0);
922                    of_store_32bit_in_host(ata_reg + 8, 0x21000);
923                    of_store_32bit_in_host(ata_reg + 12, 0x22000);
924                    of_store_32bit_in_host(ata_reg + 16, 0);
925                    of_store_32bit_in_host(ata_reg + 20, 0);
926                    of_store_32bit_in_host(ata_reg + 24, 0);
927                    of_store_32bit_in_host(ata_reg + 28, 0);
928                    of_add_prop(ofd, "/bandit/gc/ata", "reg", ata_reg,
929                        8*sizeof(uint32_t), 0);
930    
931                    snprintf(tmpstr, sizeof(tmpstr), "wdc addr=0xf3020000 "
932                        "irq=%s.cpu[%i].gc.lo.21 addr_mult=0x10", machine->path,
933                        machine->bootstrap_cpu);
934                    device_add(machine, tmpstr);
935            }
936    
937            return;
938    
939    bad:
940            fatal("of_emul_init_uninorth(): out of memory\n");
941            exit(1);
942    }
943    
944    
945    /*
946     *  of_emul_init():
947     *
948     *  This function creates an OpenFirmware emulation instance.
949     */
950    struct of_data *of_emul_init(struct machine *machine, struct vfb_data *vfb_data,
951            uint64_t fb_addr, int fb_xsize, int fb_ysize)
952    {
953            unsigned char *memory_reg, *memory_av;
954            unsigned char *zs_assigned_addresses;
955            struct of_device *mmu, *devstdout, *devstdin;
956            struct of_data *ofd = malloc(sizeof(struct of_data));
957            int i;
958    
959            if (ofd == NULL)
960                    goto bad;
961            memset(ofd, 0, sizeof(struct of_data));
962    
963            ofd->vfb_data = vfb_data;
964    
965            /*  Devices:  */
966    
967            /*  Root = device 1  */
968            of_add_device(ofd, "", "");
969    
970            of_add_device(ofd, "io", "/");
971            devstdin  = of_add_device(ofd, "stdin", "/io");
972            devstdout = of_add_device(ofd, "stdout", "/io");
973    
974            if (machine->use_x11) {
975                    fatal("!\n!  TODO: keyboard + framebuffer for MacPPC\n!\n");
976    
977                    of_add_prop_str(machine, ofd, "/io/stdin", "name",
978                        "keyboard");
979                    of_add_prop_str(machine, ofd, "/io", "name", "adb");
980    
981                    of_add_prop_str(machine, ofd, "/io/stdout", "device_type",
982                        "display");
983                    of_add_prop_int32(ofd, "/io/stdout", "width", fb_xsize);
984                    of_add_prop_int32(ofd, "/io/stdout", "height", fb_ysize);
985                    of_add_prop_int32(ofd, "/io/stdout", "linebytes", fb_xsize * 1);
986                    of_add_prop_int32(ofd, "/io/stdout", "depth", 8);
987                    of_add_prop_int32(ofd, "/io/stdout", "address", fb_addr);
988            } else {
989                    zs_assigned_addresses = malloc(12);
990                    if (zs_assigned_addresses == NULL)
991                            goto bad;
992                    memset(zs_assigned_addresses, 0, 12);
993                    of_add_prop_str(machine, ofd, "/io/stdin", "name", "ch-b");
994                    of_add_prop_str(machine, ofd, "/io/stdin", "device_type",
995                        "serial");
996                    of_add_prop_int32(ofd, "/io/stdin", "reg", 0xf3013000);
997                    of_add_prop(ofd, "/io/stdin", "assigned-addresses",
998                        zs_assigned_addresses, 12, 0);
999    
1000                    of_add_prop_str(machine, ofd, "/io/stdout", "device_type",
1001                        "serial");
1002            }
1003    
1004            of_add_device(ofd, "cpus", "/");
1005            for (i=0; i<machine->ncpus; i++) {
1006                    char tmp[50];
1007                    snprintf(tmp, sizeof(tmp), "@%x", i);
1008                    of_add_device(ofd, tmp, "/cpus");
1009                    snprintf(tmp, sizeof(tmp), "/cpus/@%x", i);
1010                    of_add_prop_str(machine, ofd, tmp, "device_type", "cpu");
1011                    of_add_prop_int32(ofd, tmp, "timebase-frequency",
1012                        machine->emulated_hz / 4);
1013                    of_add_prop_int32(ofd, tmp, "clock-frequency",
1014                        machine->emulated_hz);
1015                    of_add_prop_int32(ofd, tmp, "reg", i);
1016            }
1017    
1018            mmu = of_add_device(ofd, "mmu", "/");
1019    
1020            /*  TODO:  */
1021            of_add_prop(ofd, "/mmu", "translations", NULL, 0, 0);
1022    
1023            of_add_device(ofd, "chosen", "/");
1024            of_add_prop_int32(ofd, "/chosen", "mmu", mmu->handle);
1025            of_add_prop_int32(ofd, "/chosen", "stdin", devstdin->handle);
1026            of_add_prop_int32(ofd, "/chosen", "stdout", devstdout->handle);
1027    
1028            of_add_device(ofd, "memory", "/");
1029            memory_reg = malloc(2 * sizeof(uint32_t));
1030            memory_av = malloc(2 * sizeof(uint32_t));
1031            if (memory_reg == NULL || memory_av == NULL)
1032                    goto bad;
1033            of_store_32bit_in_host(memory_reg + 0, 0);
1034            of_store_32bit_in_host(memory_reg + 4, machine->physical_ram_in_mb<<20);
1035            of_store_32bit_in_host(memory_av + 0, 10 << 20);
1036            of_store_32bit_in_host(memory_av + 4,
1037                (machine->physical_ram_in_mb - 10) << 20);
1038            of_add_prop(ofd, "/memory", "reg", memory_reg, 2 * sizeof(uint32_t), 0);
1039            of_add_prop(ofd, "/memory", "available",memory_av,2*sizeof(uint32_t),0);
1040            of_add_prop_str(machine, ofd, "/memory","device_type","memory"/*?*/);
1041    
1042            /*  Services:  */
1043            of_add_service(ofd, "call-method", of__call_method_2_2, 2, 2);
1044            of_add_service(ofd, "call-method", of__call_method_3_4, 3, 4);
1045            of_add_service(ofd, "call-method", of__call_method_5_2, 5, 2);
1046            of_add_service(ofd, "call-method", of__call_method_6_1, 6, 1);
1047            of_add_service(ofd, "call-method", of__call_method_6_2, 6, 2);
1048            of_add_service(ofd, "child", of__child, 1, 1);
1049            of_add_service(ofd, "exit", of__exit, 0, 0);
1050            of_add_service(ofd, "finddevice", of__finddevice, 1, 1);
1051            of_add_service(ofd, "getprop", of__getprop, 4, 1);
1052            of_add_service(ofd, "getproplen", of__getproplen, 2, 1);
1053            of_add_service(ofd, "instance-to-package",
1054                of__instance_to_package, 1, 1);
1055            of_add_service(ofd, "interpret", of__interpret_1, 1, 1);
1056            of_add_service(ofd, "interpret", of__interpret_2, 1, 2);
1057            of_add_service(ofd, "package-to-path", of__package_to_path, 3, 1);
1058            of_add_service(ofd, "parent", of__parent, 1, 1);
1059            of_add_service(ofd, "peer", of__peer, 1, 1);
1060            of_add_service(ofd, "read", of__read, 3, 1);
1061            of_add_service(ofd, "write", of__write, 3, 1);
1062    
1063            if (verbose >= 2)
1064                    of_dump_all(ofd);
1065    
1066            machine->md.of_data = ofd;
1067            return ofd;
1068    
1069    bad:
1070            fatal("of_emul_init(): out of memory\n");
1071            exit(1);
1072    
1073            return NULL;    /*  Silences a compiler warning  */
1074    }
1075    
1076    
1077    /*
1078   *  of_emul():   *  of_emul():
1079   *   *
1080   *  OpenFirmware call emulation.   *  OpenFirmware call emulation.
1081   */   */
1082  int of_emul(struct cpu *cpu)  int of_emul(struct cpu *cpu)
1083  {  {
1084          int i, nargs, nret, ofs, handle, retval;          int i, nargs, nret, ofs, retval = 0;
1085          char service[50];          char service[50];
1086          char arg[N_MAX_ARGS][ARG_MAX_LEN];          char *arg[OF_N_MAX_ARGS];
         char tmpstr[ARG_MAX_LEN];  
1087          uint64_t base, ptr;          uint64_t base, ptr;
1088          uint64_t buf, buflen;          struct of_service *os;
1089            struct of_data *of_data = cpu->machine->md.of_data;
1090    
1091            if (of_data == NULL) {
1092                    fatal("of_emul(): no of_data struct?\n");
1093                    exit(1);
1094            }
1095    
1096          /*          /*
1097           *  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 1109  int of_emul(struct cpu *cpu)
1109          case ARCH_PPC:          case ARCH_PPC:
1110                  base = cpu->cd.ppc.gpr[3];                  base = cpu->cd.ppc.gpr[3];
1111                  break;                  break;
1112          default:          default:fatal("of_emul(): unimplemented arch (TODO)\n");
                 fatal("of_emul(): TODO: unimplemented arch\n");  
1113                  exit(1);                  exit(1);
1114          }          }
1115    
# Line 130  int of_emul(struct cpu *cpu) Line 1123  int of_emul(struct cpu *cpu)
1123          debug("[ of: %s(", service);          debug("[ of: %s(", service);
1124          ofs = 12;          ofs = 12;
1125          for (i=0; i<nargs; i++) {          for (i=0; i<nargs; i++) {
1126                    int x;
1127                  if (i > 0)                  if (i > 0)
1128                          debug(", ");                          debug(", ");
1129                  if (i >= N_MAX_ARGS) {                  if (i >= OF_N_MAX_ARGS) {
1130                          fatal("TOO MANY ARGS!");                          fatal("TOO MANY ARGS!");
1131                          continue;                          continue;
1132                  }                  }
1133                  ptr = load_32bit_word(cpu, base + ofs);                  ptr = load_32bit_word(cpu, base + ofs);
1134                  readstr(cpu, ptr, arg[i], ARG_MAX_LEN);                  arg[i] = malloc(OF_ARG_MAX_LEN + 1);
1135                  if (arg[i][0])                  if (arg[i] == NULL) {
1136                          debug("\"%s\"", arg[i]);                          fatal("out of memory\n");
1137                  else {                          exit(1);
1138                          int x = ptr;                  }
1139                          if (x > -256 && x < 256)                  memset(arg[i], 0, OF_ARG_MAX_LEN + 1);
1140                                  debug("%i", x);                  x = ptr;
1141                    if (x > -256 && x < 256) {
1142                            debug("%i", x);
1143                    } else {
1144                            readstr(cpu, ptr, arg[i], OF_ARG_MAX_LEN);
1145                            if (arg[i][0])
1146                                    debug("\"%s\"", arg[i]);
1147                          else                          else
1148                                  debug("0x%x", x);                                  debug("0x%x", x);
1149                  }                  }
# Line 151  int of_emul(struct cpu *cpu) Line 1151  int of_emul(struct cpu *cpu)
1151          }          }
1152          debug(") ]\n");          debug(") ]\n");
1153    
         /*  Return value:  */  
         retval = 0;  
   
1154          /*  Note: base + ofs points to the first return slot.  */          /*  Note: base + ofs points to the first return slot.  */
1155    
1156          if (strcmp(service, "exit") == 0) {          os = of_data->of_services;
1157                  cpu->running = 0;          while (os != NULL) {
1158          } else if (strcmp(service, "finddevice") == 0) {                  if (strcmp(service, os->name) == 0 &&
1159                  /*  Return a handle in ret[0]:  */                      nargs == os->n_args && nret == os->n_ret_args) {
1160                  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;  
                         }  
1161                          break;                          break;
1162                  case HANDLE_CHOSEN:                  }
1163                          if (strcmp(tmpstr, "stdin") == 0) {                  os = os->next;
1164                                  if (buflen >= 4)          }
1165                                          store_32bit_word(cpu, buf,  
1166                                              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 {  
1167                  quiet_mode = 0;                  quiet_mode = 0;
1168                  cpu_register_dump(cpu->machine, cpu, 1, 0);                  cpu_register_dump(cpu->machine, cpu, 1, 0);
1169                  printf("\n");                  printf("\n");
1170                  fatal("[ of_emul(): unimplemented service \"%s\" ]\n", service);                  fatal("[ of: unimplemented service \"%s\" with %i input "
1171                        "args and %i output values ]\n", service, nargs, nret);
1172                  cpu->running = 0;                  cpu->running = 0;
                 cpu->dead = 1;  
1173          }          }
1174    
1175            for (i=0; i<nargs; i++)
1176                    free(arg[i]);
1177    
1178            /*  Return:  */
1179          switch (cpu->machine->arch) {          switch (cpu->machine->arch) {
1180          case ARCH_ARM:          case ARCH_ARM:
1181                  cpu->cd.arm.r[0] = retval;                  cpu->cd.arm.r[0] = retval;
# Line 258  int of_emul(struct cpu *cpu) Line 1183  int of_emul(struct cpu *cpu)
1183          case ARCH_PPC:          case ARCH_PPC:
1184                  cpu->cd.ppc.gpr[3] = retval;                  cpu->cd.ppc.gpr[3] = retval;
1185                  break;                  break;
1186          default:          default:fatal("of_emul(): TODO: unimplemented arch (Retval)\n");
                 fatal("of_emul(): TODO: unimplemented arch (Retval)\n");  
1187                  exit(1);                  exit(1);
1188          }          }
1189    

Legend:
Removed from v.14  
changed lines
  Added in v.38

  ViewVC Help
Powered by ViewVC 1.1.26