/[gxemul]/upstream/0.3.1/devices/dev_sgi_ip30.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.1/devices/dev_sgi_ip30.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 10114 byte(s)
0.3.1
1 /*
2 * Copyright (C) 2004-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: dev_sgi_ip30.c,v 1.17 2005/02/25 06:14:30 debug Exp $
29 *
30 * SGI IP30 stuff.
31 *
32 * This is just comprised of hardcoded guesses so far. (Ugly.)
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "cpu.h"
40 #include "devices.h"
41 #include "machine.h"
42 #include "memory.h"
43 #include "misc.h"
44
45
46 void dev_sgi_ip30_tick(struct cpu *cpu, void *extra)
47 {
48 struct sgi_ip30_data *d = extra;
49
50 d->reg_0x20000 += 1000;
51
52 if (d->imask0 & ((int64_t)1<<50)) {
53 /* TODO: Only interrupt if reg 0x20000 (the counter)
54 has passed the compare (0x30000). */
55 cpu_interrupt(cpu, 8+1 + 50);
56 }
57 }
58
59
60 /*
61 * dev_sgi_ip30_access():
62 */
63 int dev_sgi_ip30_access(struct cpu *cpu, struct memory *mem,
64 uint64_t relative_addr, unsigned char *data, size_t len,
65 int writeflag, void *extra)
66 {
67 struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra;
68 uint64_t idata = 0, odata = 0;
69
70 idata = memory_readmax64(cpu, data, len);
71
72 switch (relative_addr) {
73 case 0x20:
74 /* Memory bank configuration: */
75 odata = 0x80010000ULL;
76 break;
77 case 0x10000: /* Interrupt mask register 0: */
78 if (writeflag == MEM_WRITE) {
79 d->imask0 = idata;
80 } else {
81 odata = d->imask0;
82 }
83 break;
84 case 0x10018:
85 /*
86 * If this is not implemented, the IP30 PROM complains during
87 * bootup:
88 *
89 * *FAILED*
90 * Address: 0xffffffffaff10018, Expected:
91 * 0x0000000000000001, Received: 0x0000000000000000
92 */
93 if (writeflag == MEM_WRITE) {
94 d->reg_0x10018 = idata;
95 } else {
96 odata = d->reg_0x10018;
97 }
98 break;
99 case 0x10020: /* Set ISR, according to Linux/IP30 */
100 d->isr = idata;
101 /* Recalculate CPU interrupt assertions: */
102 cpu_interrupt(cpu, 8);
103 break;
104 case 0x10028: /* Clear ISR, according to Linux/IP30 */
105 d->isr &= ~idata;
106 /* Recalculate CPU interrupt assertions: */
107 cpu_interrupt(cpu, 8);
108 break;
109 case 0x10030: /* Interrupt Status Register */
110 if (writeflag == MEM_WRITE) {
111 /* Clear-on-write (TODO: is this correct?) */
112 d->isr &= ~idata;
113 /* Recalculate CPU interrupt assertions: */
114 cpu_interrupt(cpu, 8);
115 } else {
116 odata = d->isr;
117 }
118 break;
119 case 0x20000:
120 /* A counter */
121 if (writeflag == MEM_WRITE) {
122 d->reg_0x20000 = idata;
123 } else {
124 odata = d->reg_0x20000;
125 }
126 break;
127 case 0x30000:
128 if (writeflag == MEM_WRITE) {
129 d->reg_0x30000 = idata;
130 } else {
131 odata = d->reg_0x30000;
132 }
133 break;
134 default:
135 if (writeflag == MEM_WRITE) {
136 debug("[ sgi_ip30: unimplemented write to address "
137 "0x%x, data=0x%02x ]\n", (int)relative_addr,
138 (int)idata);
139 } else {
140 debug("[ sgi_ip30: unimplemented read from address"
141 " 0x%x ]\n", (int)relative_addr);
142 }
143 }
144
145 if (writeflag == MEM_READ)
146 memory_writemax64(cpu, data, len, odata);
147
148 return 1;
149 }
150
151
152 /*
153 * dev_sgi_ip30_2_access():
154 */
155 int dev_sgi_ip30_2_access(struct cpu *cpu, struct memory *mem,
156 uint64_t relative_addr, unsigned char *data, size_t len,
157 int writeflag, void *extra)
158 {
159 struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra;
160 uint64_t idata = 0, odata = 0;
161
162 idata = memory_readmax64(cpu, data, len);
163
164 switch (relative_addr) {
165
166 /* 0x114 + 0x40 * (wid - 8): 0x80000000 for "alive",
167 according to Linux/IP30 */
168
169 case 0x114 + 0x40 * (12 - 8):
170 fatal("[ IP30: asdvasdvnb ]\n");
171 odata = 0x80000000;
172 break;
173
174 case 0x0029c:
175 /*
176 * If this is not implemented, the IP30 PROM complains during
177 * bootup:
178 *
179 * *FAILED*
180 * Address: 0xffffffffb000029c, Expected:
181 * 0x0000000000000001, Received: 0x0000000000000000
182 */
183 if (writeflag == MEM_WRITE) {
184 d->reg_0x0029c = idata;
185 } else {
186 odata = d->reg_0x0029c;
187 }
188 break;
189 default:
190 if (writeflag == MEM_WRITE) {
191 debug("[ sgi_ip30_2: unimplemented write to "
192 "address 0x%x, data=0x%02x ]\n",
193 (int)relative_addr, (int)idata);
194 } else {
195 debug("[ sgi_ip30_2: unimplemented read from address "
196 "0x%x ]\n", (int)relative_addr);
197 }
198 }
199
200 if (writeflag == MEM_READ)
201 memory_writemax64(cpu, data, len, odata);
202
203 return 1;
204 }
205
206
207 /*
208 * dev_sgi_ip30_3_access():
209 */
210 int dev_sgi_ip30_3_access(struct cpu *cpu, struct memory *mem,
211 uint64_t relative_addr, unsigned char *data, size_t len,
212 int writeflag, void *extra)
213 {
214 struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra;
215 uint64_t idata = 0, odata = 0;
216
217 idata = memory_readmax64(cpu, data, len);
218
219 switch (relative_addr) {
220 case 0xb4:
221 if (writeflag == MEM_WRITE) {
222 debug("[ sgi_ip30_3: unimplemented write to "
223 "address 0x%x, data=0x%02x ]\n",
224 (int)relative_addr, (int)idata);
225 } else {
226 odata = 2; /* should be 2, or Irix loops */
227 }
228 break;
229 case 0x00104:
230 if (writeflag == MEM_WRITE) {
231 debug("[ sgi_ip30_3: unimplemented write to address "
232 "0x%x, data=0x%02x ]\n", (int)relative_addr,
233 (int)idata);
234 } else {
235 odata = 64; /* should be 64, or the PROM
236 complains */
237 }
238 break;
239 case 0x00284:
240 /*
241 * If this is not implemented, the IP30 PROM complains during
242 * bootup:
243 *
244 * *FAILED*
245 * Address: 0xffffffffbf000284, Expected:
246 * 0x0000000000000001, Received: 0x0000000000000000
247 */
248 if (writeflag == MEM_WRITE) {
249 d->reg_0x00284 = idata;
250 } else {
251 odata = d->reg_0x00284;
252 }
253 break;
254 default:
255 if (writeflag == MEM_WRITE) {
256 debug("[ sgi_ip30_3: unimplemented write to address "
257 "0x%x, data=0x%02x ]\n", (int)relative_addr,
258 (int)idata);
259 } else {
260 debug("[ sgi_ip30_3: unimplemented read from "
261 "address 0x%x ]\n", (int)relative_addr);
262 }
263 }
264
265 if (writeflag == MEM_READ)
266 memory_writemax64(cpu, data, len, odata);
267
268 return 1;
269 }
270
271
272 /*
273 * dev_sgi_ip30_4_access():
274 */
275 int dev_sgi_ip30_4_access(struct cpu *cpu, struct memory *mem,
276 uint64_t relative_addr, unsigned char *data, size_t len,
277 int writeflag, void *extra)
278 {
279 struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra;
280 uint64_t idata = 0, odata = 0;
281
282 idata = memory_readmax64(cpu, data, len);
283
284 switch (relative_addr) {
285 case 0x000b0:
286 /*
287 * If this is not implemented, the IP30 PROM complains during
288 * bootup:
289 *
290 * *FAILED*
291 * Address: 0xffffffffbf6000b0, Expected:
292 * 0x0000000000000001, Received: 0x0000000000000000
293 */
294 if (writeflag == MEM_WRITE) {
295 d->reg_0x000b0 = idata;
296 } else {
297 odata = d->reg_0x000b0;
298 }
299 break;
300 default:
301 if (writeflag == MEM_WRITE) {
302 debug("[ sgi_ip30_4: unimplemented write to address"
303 " 0x%x, data=0x%02x ]\n",
304 (int)relative_addr, (int)idata);
305 } else {
306 debug("[ sgi_ip30_4: unimplemented read from address"
307 " 0x%x ]\n", (int)relative_addr);
308 }
309 }
310
311 if (writeflag == MEM_READ)
312 memory_writemax64(cpu, data, len, odata);
313
314 return 1;
315 }
316
317
318 /*
319 * dev_sgi_ip30_5_access():
320 */
321 int dev_sgi_ip30_5_access(struct cpu *cpu, struct memory *mem,
322 uint64_t relative_addr, unsigned char *data, size_t len,
323 int writeflag, void *extra)
324 {
325 struct sgi_ip30_data *d = (struct sgi_ip30_data *) extra;
326 uint64_t idata = 0, odata = 0;
327
328 idata = memory_readmax64(cpu, data, len);
329
330 switch (relative_addr) {
331 case 0x00000:
332 if (writeflag == MEM_WRITE) {
333 d->reg_0x00000 = idata;
334 } else {
335 odata = d->reg_0x00000;
336 }
337 break;
338 default:
339 if (writeflag == MEM_WRITE) {
340 debug("[ sgi_ip30_5: unimplemented write to address "
341 "0x%x, data=0x%02x ]\n", (int)relative_addr,
342 (int)idata);
343 } else {
344 debug("[ sgi_ip30_5: unimplemented read from address "
345 "0x%x ]\n", (int)relative_addr);
346 }
347 }
348
349 if (writeflag == MEM_READ)
350 memory_writemax64(cpu, data, len, odata);
351
352 return 1;
353 }
354
355
356 /*
357 * dev_sgi_ip30_init():
358 */
359 struct sgi_ip30_data *dev_sgi_ip30_init(struct machine *machine,
360 struct memory *mem, uint64_t baseaddr)
361 {
362 struct sgi_ip30_data *d = malloc(sizeof(struct sgi_ip30_data));
363 if (d == NULL) {
364 fprintf(stderr, "out of memory\n");
365 exit(1);
366 }
367 memset(d, 0, sizeof(struct sgi_ip30_data));
368
369 memory_device_register(mem, "sgi_ip30_1", baseaddr,
370 DEV_SGI_IP30_LENGTH, dev_sgi_ip30_access, (void *)d,
371 MEM_DEFAULT, NULL);
372 memory_device_register(mem, "sgi_ip30_2", 0x10000000,
373 0x10000, dev_sgi_ip30_2_access, (void *)d, MEM_DEFAULT, NULL);
374 memory_device_register(mem, "sgi_ip30_3", 0x1f000000,
375 0x10000, dev_sgi_ip30_3_access, (void *)d, MEM_DEFAULT, NULL);
376 memory_device_register(mem, "sgi_ip30_4", 0x1f600000,
377 0x10000, dev_sgi_ip30_4_access, (void *)d, MEM_DEFAULT, NULL);
378 memory_device_register(mem, "sgi_ip30_5", 0x1f6c0000,
379 0x10000, dev_sgi_ip30_5_access, (void *)d, MEM_DEFAULT, NULL);
380
381 machine_add_tickfunction(machine, dev_sgi_ip30_tick, d, 16);
382
383 return d;
384 }
385

  ViewVC Help
Powered by ViewVC 1.1.26