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

Contents of /upstream/0.3.6/src/promemul/of.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show annotations)
Mon Oct 8 16:18:56 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 7371 byte(s)
0.3.6
1 /*
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 * $Id: of.c,v 1.3 2005/09/01 13:27:13 debug Exp $
29 *
30 * OpenFirmware emulation.
31 *
32 * Development notes: Care must be taken so that the code in here works
33 * with (at least) POWER/PowerPC, ARM, and SPARC.
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40
41 #include "console.h"
42 #include "cpu.h"
43 #include "machine.h"
44 #include "memory.h"
45 #include "misc.h"
46
47
48 #define N_MAX_ARGS 10
49 #define ARG_MAX_LEN 4096
50
51 extern int quiet_mode;
52
53 /* TODO: IMPORTANT! Change this into something else, to allow multiple
54 opens of the same device: */
55 #define HANDLE_STDIN 0
56 #define HANDLE_STDOUT 1
57 #define HANDLE_STDERR 2
58 #define HANDLE_MMU 3
59 #define HANDLE_MEMORY 4
60 #define HANDLE_CHOSEN 5
61
62
63 /*
64 * readstr():
65 *
66 * Helper function to read a string from emulated memory.
67 */
68 static void readstr(struct cpu *cpu, uint64_t addr, char *strbuf,
69 int bufsize)
70 {
71 int i;
72 for (i=0; i<bufsize; i++) {
73 unsigned char ch;
74 cpu->memory_rw(cpu, cpu->mem, addr + i,
75 &ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS);
76 strbuf[i] = '\0';
77 if (ch >= 1 && ch < 32)
78 ch = 0;
79 strbuf[i] = ch;
80 if (strbuf[i] == '\0')
81 break;
82 }
83
84 strbuf[bufsize - 1] = '\0';
85 }
86
87
88 /*
89 * of_emul():
90 *
91 * OpenFirmware call emulation.
92 */
93 int of_emul(struct cpu *cpu)
94 {
95 int i, nargs, nret, ofs, handle, retval;
96 char service[50];
97 char arg[N_MAX_ARGS][ARG_MAX_LEN];
98 char tmpstr[ARG_MAX_LEN];
99 uint64_t base, ptr;
100 uint64_t buf, buflen;
101
102 /*
103 * The first argument register points to "prom_args":
104 *
105 * char *service; (probably 32 bit)
106 * int nargs;
107 * int nret;
108 * char *args[10];
109 */
110
111 switch (cpu->machine->arch) {
112 case ARCH_ARM:
113 base = cpu->cd.arm.r[0];
114 break;
115 case ARCH_PPC:
116 base = cpu->cd.ppc.gpr[3];
117 break;
118 default:
119 fatal("of_emul(): TODO: unimplemented arch\n");
120 exit(1);
121 }
122
123 /* TODO: how about 64-bit OpenFirmware? */
124 ptr = load_32bit_word(cpu, base);
125 nargs = load_32bit_word(cpu, base + 4);
126 nret = load_32bit_word(cpu, base + 8);
127
128 readstr(cpu, ptr, service, sizeof(service));
129
130 debug("[ of: %s(", service);
131 ofs = 12;
132 for (i=0; i<nargs; i++) {
133 if (i > 0)
134 debug(", ");
135 if (i >= N_MAX_ARGS) {
136 fatal("TOO MANY ARGS!");
137 continue;
138 }
139 ptr = load_32bit_word(cpu, base + ofs);
140 readstr(cpu, ptr, arg[i], ARG_MAX_LEN);
141 if (arg[i][0])
142 debug("\"%s\"", arg[i]);
143 else {
144 int x = ptr;
145 if (x > -256 && x < 256)
146 debug("%i", x);
147 else
148 debug("0x%x", x);
149 }
150 ofs += sizeof(uint32_t);
151 }
152 debug(") ]\n");
153
154 /* Return value: */
155 retval = 0;
156
157 /* Note: base + ofs points to the first return slot. */
158
159 if (strcmp(service, "exit") == 0) {
160 cpu->running = 0;
161 } else if (strcmp(service, "finddevice") == 0) {
162 /* Return a handle in ret[0]: */
163 if (nret < 1) {
164 fatal("[ of: finddevice(\"%s\"): nret < 1! ]\n",
165 arg[0]);
166 } else if (strcmp(arg[0], "/memory") == 0) {
167 store_32bit_word(cpu, base + ofs, HANDLE_MEMORY);
168 } else if (strcmp(arg[0], "/chosen") == 0) {
169 store_32bit_word(cpu, base + ofs, HANDLE_CHOSEN);
170 } else {
171 /* Device not found. */
172 fatal("[ of: finddevice(\"%s\"): not yet"
173 " implemented ]\n", arg[0]);
174 retval = -1;
175 }
176 } else if (strcmp(service, "getprop") == 0) {
177 handle = load_32bit_word(cpu, base + 12 + 4*0);
178 ptr = load_32bit_word(cpu, base + 12 + 4*1);
179 buf = load_32bit_word(cpu, base + 12 + 4*2);
180 buflen = load_32bit_word(cpu, base + 12 + 4*3);
181 readstr(cpu, ptr, tmpstr, sizeof(tmpstr));
182
183 /* TODO: rewrite this */
184 switch (handle) {
185 case HANDLE_MEMORY:
186 if (strcmp(tmpstr, "available") == 0) {
187 store_32bit_word(cpu, base + ofs, 2*8);
188 /* TODO. {start, size} */
189 store_32bit_word(cpu, buf, 0);
190 store_32bit_word(cpu, buf+4,
191 cpu->machine->physical_ram_in_mb * 1048576
192 - 65536);
193 store_32bit_word(cpu, buf+8, 0);
194 store_32bit_word(cpu, buf+12, 0);
195 } else if (strcmp(tmpstr, "reg") == 0) {
196 /* TODO */
197 store_32bit_word(cpu, base + ofs, 33*8);
198 store_32bit_word(cpu, buf, 0);
199 store_32bit_word(cpu, buf+4,
200 cpu->machine->physical_ram_in_mb * 1048576);
201 store_32bit_word(cpu, buf+8, 0);
202 store_32bit_word(cpu, buf+12, 0);
203 } else {
204 fatal("[ of: getprop(%i,\"%s\"): not yet"
205 " implemented ]\n", (int)handle, arg[1]);
206 retval = -1;
207 }
208 break;
209 case HANDLE_CHOSEN:
210 if (strcmp(tmpstr, "stdin") == 0) {
211 if (buflen >= 4)
212 store_32bit_word(cpu, buf,
213 HANDLE_STDIN);
214 store_32bit_word(cpu, base + ofs, 4);
215 } else if (strcmp(tmpstr, "stdout") == 0) {
216 if (buflen >= 4)
217 store_32bit_word(cpu, buf,
218 HANDLE_STDOUT);
219 store_32bit_word(cpu, base + ofs, 4);
220 } else if (strcmp(tmpstr, "mmu") == 0) {
221 if (buflen >= 4)
222 store_32bit_word(cpu, buf,
223 HANDLE_MMU);
224 store_32bit_word(cpu, base + ofs, 4);
225 } else {
226 fatal("[ of: getprop(%i,\"%s\"): not yet"
227 " implemented ]\n", (int)handle, arg[1]);
228 retval = -1;
229 }
230 break;
231 default:
232 fatal("[ of: getprop(%i,\"%s\"): not yet"
233 " implemented ]\n", (int)handle, arg[1]);
234 retval = -1;
235 }
236 } else if (strcmp(service, "instance-to-package") == 0) {
237 /* TODO: a package handle */
238 store_32bit_word(cpu, base + ofs, 1000);
239 } else if (strcmp(service, "getproplen") == 0) {
240 /* TODO */
241 store_32bit_word(cpu, base + ofs, 0);
242 } else if (strcmp(service, "peer") == 0) {
243 /* TODO */
244 store_32bit_word(cpu, base + ofs, 0);
245 } else {
246 quiet_mode = 0;
247 cpu_register_dump(cpu->machine, cpu, 1, 0);
248 printf("\n");
249 fatal("[ of_emul(): unimplemented service \"%s\" ]\n", service);
250 cpu->running = 0;
251 cpu->dead = 1;
252 }
253
254 switch (cpu->machine->arch) {
255 case ARCH_ARM:
256 cpu->cd.arm.r[0] = retval;
257 break;
258 case ARCH_PPC:
259 cpu->cd.ppc.gpr[3] = retval;
260 break;
261 default:
262 fatal("of_emul(): TODO: unimplemented arch (Retval)\n");
263 exit(1);
264 }
265
266 return 1;
267 }
268

  ViewVC Help
Powered by ViewVC 1.1.26