/[gxemul]/upstream/0.3.3.2/src/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

Annotation of /upstream/0.3.3.2/src/of.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Mon Oct 8 16:18:22 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6884 byte(s)
0.3.3.2
1 dpavlin 2 /*
2     * Copyright (C) 2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28 dpavlin 4 * $Id: of.c,v 1.6 2005/04/19 00:02:00 debug Exp $
29 dpavlin 2 *
30     * OpenFirmware emulation.
31     */
32    
33     #include <stdio.h>
34     #include <stdlib.h>
35     #include <string.h>
36     #include <sys/types.h>
37    
38     #include "console.h"
39     #include "cpu.h"
40     #include "cpu_ppc.h"
41     #include "machine.h"
42     #include "memory.h"
43     #include "misc.h"
44    
45    
46     #define N_MAX_ARGS 10
47     #define ARG_MAX_LEN 4096
48    
49     extern int quiet_mode;
50    
51     /* TODO: IMPORTANT! Change this into something else, to allow multiple
52     opens of the same device: */
53     #define HANDLE_STDIN 0
54     #define HANDLE_STDOUT 1
55     #define HANDLE_STDERR 2
56     #define HANDLE_MMU 3
57     #define HANDLE_MEMORY 4
58     #define HANDLE_CHOSEN 5
59    
60    
61     /*
62     * readstr():
63     *
64     * Helper function to read a string from emulated memory.
65     */
66     static void readstr(struct cpu *cpu, uint64_t addr, char *strbuf,
67     int bufsize)
68     {
69     int i;
70     for (i=0; i<bufsize; i++) {
71     unsigned char ch;
72     cpu->memory_rw(cpu, cpu->mem, addr + i,
73     &ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
74     strbuf[i] = '\0';
75     if (ch >= 1 && ch < 32)
76     ch = 0;
77     strbuf[i] = ch;
78     if (strbuf[i] == '\0')
79     break;
80     }
81    
82     strbuf[bufsize - 1] = '\0';
83     }
84    
85    
86     /*
87     * of_emul():
88     *
89     * OpenFirmware call emulation.
90     */
91     int of_emul(struct cpu *cpu)
92     {
93     int i, nargs, nret, ofs, handle;
94     char service[50];
95     char arg[N_MAX_ARGS][ARG_MAX_LEN];
96     char tmpstr[ARG_MAX_LEN];
97     uint64_t base, ptr;
98     uint64_t buf, buflen;
99    
100     /*
101     * r3 points to "prom_args":
102     *
103     * char *service; (probably 32 bit)
104     * int nargs;
105     * int nret;
106     * char *args[10];
107     */
108    
109     base = cpu->cd.ppc.gpr[3];
110    
111     /* TODO: how about 64-bit OpenFirmware? */
112     ptr = load_32bit_word(cpu, base);
113     nargs = load_32bit_word(cpu, base + 4);
114     nret = load_32bit_word(cpu, base + 8);
115    
116     readstr(cpu, ptr, service, sizeof(service));
117    
118     debug("[ of: %s(", service);
119     ofs = 12;
120     for (i=0; i<nargs; i++) {
121     if (i > 0)
122     debug(", ");
123     if (i >= N_MAX_ARGS) {
124     fatal("TOO MANY ARGS!");
125     continue;
126     }
127     ptr = load_32bit_word(cpu, base + ofs);
128     readstr(cpu, ptr, arg[i], ARG_MAX_LEN);
129     if (arg[i][0])
130     debug("\"%s\"", arg[i]);
131     else {
132     int x = ptr;
133     if (x > -256 && x < 256)
134     debug("%i", x);
135     else
136     debug("0x%x", x);
137     }
138     ofs += sizeof(uint32_t);
139     }
140     debug(") ]\n");
141    
142     /* Return value: */
143     cpu->cd.ppc.gpr[3] = 0;
144    
145     /* Note: base + ofs points to the first return slot. */
146    
147     if (strcmp(service, "exit") == 0) {
148     cpu->running = 0;
149     } else if (strcmp(service, "finddevice") == 0) {
150     /* Return a handle in ret[0]: */
151     if (nret < 1) {
152     fatal("[ of: finddevice(\"%s\"): nret < 1! ]\n",
153     arg[0]);
154     } else if (strcmp(arg[0], "/memory") == 0) {
155     store_32bit_word(cpu, base + ofs, HANDLE_MEMORY);
156     } else if (strcmp(arg[0], "/chosen") == 0) {
157     store_32bit_word(cpu, base + ofs, HANDLE_CHOSEN);
158     } else {
159     /* Device not found. */
160     fatal("[ of: finddevice(\"%s\"): not yet"
161     " implemented ]\n", arg[0]);
162     cpu->cd.ppc.gpr[3] = -1;
163     }
164     } else if (strcmp(service, "getprop") == 0) {
165     handle = load_32bit_word(cpu, base + 12 + 4*0);
166     ptr = load_32bit_word(cpu, base + 12 + 4*1);
167     buf = load_32bit_word(cpu, base + 12 + 4*2);
168     buflen = load_32bit_word(cpu, base + 12 + 4*3);
169     readstr(cpu, ptr, tmpstr, sizeof(tmpstr));
170    
171     /* TODO: rewrite this */
172     switch (handle) {
173     case HANDLE_MEMORY:
174     if (strcmp(tmpstr, "available") == 0) {
175     store_32bit_word(cpu, base + ofs, 2*8);
176     /* TODO. {start, size} */
177     store_32bit_word(cpu, buf, 0);
178     store_32bit_word(cpu, buf+4,
179     cpu->machine->physical_ram_in_mb * 1048576
180     - 65536);
181     store_32bit_word(cpu, buf+8, 0);
182     store_32bit_word(cpu, buf+12, 0);
183     } else if (strcmp(tmpstr, "reg") == 0) {
184     /* TODO */
185     store_32bit_word(cpu, base + ofs, 33*8);
186     store_32bit_word(cpu, buf, 0);
187     store_32bit_word(cpu, buf+4,
188     cpu->machine->physical_ram_in_mb * 1048576);
189     store_32bit_word(cpu, buf+8, 0);
190     store_32bit_word(cpu, buf+12, 0);
191     } else {
192     fatal("[ of: getprop(%i,\"%s\"): not yet"
193     " implemented ]\n", (int)handle, arg[1]);
194     cpu->cd.ppc.gpr[3] = -1;
195     }
196     break;
197     case HANDLE_CHOSEN:
198     if (strcmp(tmpstr, "stdin") == 0) {
199     if (buflen >= 4)
200     store_32bit_word(cpu, buf,
201     HANDLE_STDIN);
202     store_32bit_word(cpu, base + ofs, 4);
203     } else if (strcmp(tmpstr, "stdout") == 0) {
204     if (buflen >= 4)
205     store_32bit_word(cpu, buf,
206     HANDLE_STDOUT);
207     store_32bit_word(cpu, base + ofs, 4);
208     } else if (strcmp(tmpstr, "mmu") == 0) {
209     if (buflen >= 4)
210     store_32bit_word(cpu, buf,
211     HANDLE_MMU);
212     store_32bit_word(cpu, base + ofs, 4);
213     } else {
214     fatal("[ of: getprop(%i,\"%s\"): not yet"
215     " implemented ]\n", (int)handle, arg[1]);
216     cpu->cd.ppc.gpr[3] = -1;
217     }
218     break;
219     default:
220     fatal("[ of: getprop(%i,\"%s\"): not yet"
221     " implemented ]\n", (int)handle, arg[1]);
222     cpu->cd.ppc.gpr[3] = -1;
223     }
224     } else if (strcmp(service, "instance-to-package") == 0) {
225     /* TODO: a package handle */
226     store_32bit_word(cpu, base + ofs, 1000);
227     } else if (strcmp(service, "getproplen") == 0) {
228     /* TODO */
229     store_32bit_word(cpu, base + ofs, 0);
230 dpavlin 4 } else if (strcmp(service, "peer") == 0) {
231     /* TODO */
232     store_32bit_word(cpu, base + ofs, 0);
233 dpavlin 2 } else {
234     quiet_mode = 0;
235     cpu_register_dump(cpu->machine, cpu, 1, 0);
236     printf("\n");
237     fatal("[ of_emul(): unimplemented service \"%s\" ]\n", service);
238     cpu->running = 0;
239     cpu->dead = 1;
240     }
241    
242     return 1;
243     }
244    

  ViewVC Help
Powered by ViewVC 1.1.26