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

Contents of /upstream/0.3.5/src/of.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (show annotations)
Mon Oct 8 16:18:43 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 6884 byte(s)
0.3.5
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.6 2005/04/19 00:02:00 debug Exp $
29 *
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 } else if (strcmp(service, "peer") == 0) {
231 /* TODO */
232 store_32bit_word(cpu, base + ofs, 0);
233 } 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