/[gxemul]/upstream/0.3.7/src/devices/dev_sgi_ip22.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.7/src/devices/dev_sgi_ip22.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show annotations)
Mon Oct 8 16:19:28 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 13210 byte(s)
0.3.7
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_ip22.c,v 1.26 2005/11/13 00:14:09 debug Exp $
29 *
30 * SGI IP22 stuff.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "cpu.h"
38 #include "devices.h"
39 #include "machine.h"
40 #include "memory.h"
41 #include "misc.h"
42
43 #include "imcreg.h"
44
45
46 #define SGI_IP22_TICK_SHIFT 14
47
48
49 /*
50 * dev_sgi_ip22_tick():
51 */
52 void dev_sgi_ip22_tick(struct cpu *cpu, void *extra)
53 {
54 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
55
56 if (d->reg[0x38 / 4] != 0)
57 d->reg[0x38 / 4] --;
58 }
59
60
61 /*
62 * dev_sgi_ip22_imc_access():
63 *
64 * The memory controller (?).
65 */
66 int dev_sgi_ip22_imc_access(struct cpu *cpu, struct memory *mem,
67 uint64_t relative_addr, unsigned char *data, size_t len,
68 int writeflag, void *extra)
69 {
70 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
71 uint64_t idata = 0, odata = 0;
72 int regnr;
73
74 if (writeflag == MEM_WRITE)
75 idata = memory_readmax64(cpu, data, len);
76
77 regnr = relative_addr / sizeof(uint32_t);
78
79 if (writeflag == MEM_WRITE)
80 d->imc_reg[regnr] = idata;
81 else
82 odata = d->imc_reg[regnr];
83
84 switch (relative_addr) {
85 case (IMC_CPUCTRL0 - IP22_IMC_BASE):
86 if (writeflag == MEM_WRITE) {
87 /* debug("[ sgi_ip22_imc: write to "
88 "IMC_CPUCTRL0, data=0x%08x ]\n", (int)idata); */
89 } else {
90 /* debug("[ sgi_ip22_imc: read from IMC_CPUCTRL0, "
91 "data=0x%08x ]\n", (int)odata); */
92 }
93 break;
94 case (IMC_SYSID - IP22_IMC_BASE):
95 if (writeflag == MEM_WRITE) {
96 debug("[ sgi_ip22_imc: unimplemented write "
97 "IMC_SYSID, data=0x%08x ]\n", (int)idata);
98 } else {
99 /* Lowest 4 bits are the revision bits. */
100 odata = 3; /* + IMC_SYSID_HAVEISA; */
101 /* debug("[ sgi_ip22_imc: read from IMC_SYSID, "
102 "data=0x%08x ]\n", (int)odata); */
103 }
104 break;
105 case (IMC_WDOG - IP22_IMC_BASE):
106 if (writeflag == MEM_WRITE) {
107 /* debug("[ sgi_ip22_imc: write to IMC_WDOG, "
108 "data=0x%08x ]\n", (int)idata); */
109 } else {
110 /* debug("[ sgi_ip22_imc: read from IMC_WDOG, "
111 "data=0x%08x ]\n", (int)odata); */
112 }
113 break;
114 case (IMC_MEMCFG0 - IP22_IMC_BASE):
115 if (writeflag == MEM_WRITE) {
116 debug("[ sgi_ip22_imc: unimplemented write "
117 "IMC_MEMCFG0, data=0x%08x ]\n", (int)idata);
118 } else {
119 odata = 0x3100 + (0x8000000 >> 22); /* ? TODO */
120 /* debug("[ sgi_ip22_imc: read from IMC_MEMCFG0,"
121 " data=0x%08x ]\n", (int)odata); */
122 }
123 break;
124 case (IMC_MEMCFG1 - IP22_IMC_BASE):
125 if (writeflag == MEM_WRITE) {
126 debug("[ sgi_ip22_imc: unimplemented write "
127 "IMC_MEMCFG1, data=0x%08x ]\n", (int)idata);
128 } else {
129 odata = 0;
130 /* debug("[ sgi_ip22_imc: read from IMC_MEMCFG1, "
131 "data=0x%08x ]\n", (int)odata); */
132 }
133 break;
134 case (IMC_EEPROM - IP22_IMC_BASE):
135 /*
136 * The IP22 prom tries to access this during bootup,
137 * but I have no idea how it works.
138 */
139 if (writeflag == MEM_WRITE) {
140 debug("[ sgi_ip22_imc: write to IMC_EEPROM, data="
141 "0x%08x ]\n", (int)idata);
142 } else {
143 odata = random() & 0x1e;
144 debug("[ sgi_ip22_imc: read from IMC_WDOG, "
145 "data=0x%08x ]\n", (int)odata);
146 }
147 break;
148 default:
149 if (writeflag == MEM_WRITE) {
150 debug("[ sgi_ip22_imc: unimplemented write to "
151 "address 0x%x, data=0x%08x ]\n",
152 (int)relative_addr, (int)idata);
153 } else {
154 debug("[ sgi_ip22_imc: unimplemented read from "
155 "address 0x%x, data=0x%08x ]\n",
156 (int)relative_addr, (int)odata);
157 }
158 }
159
160 if (writeflag == MEM_READ)
161 memory_writemax64(cpu, data, len, odata);
162
163 return 1;
164 }
165
166
167 /*
168 * dev_sgi_ip22_unknown_access():
169 *
170 * A so far unknown device, used by the IP22 prom during startup.
171 */
172 int dev_sgi_ip22_unknown_access(struct cpu *cpu, struct memory *mem,
173 uint64_t relative_addr, unsigned char *data, size_t len,
174 int writeflag, void *extra)
175 {
176 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
177 uint64_t idata = 0, odata = 0;
178
179 idata = memory_readmax64(cpu, data, len);
180
181 switch (relative_addr) {
182 case 0x04:
183 if (writeflag == MEM_WRITE) {
184 debug("[ sgi_ip22_unknown: write to address 0x%x,"
185 " data=0x%08x ]\n", (int)relative_addr, (int)idata);
186 } else {
187 odata = d->unknown_timer;
188 d->unknown_timer += 100;
189 debug("[ sgi_ip22_unknown: read from address 0x%x, "
190 "data=0x%08x ]\n", (int)relative_addr, (int)odata);
191 }
192 break;
193 default:
194 if (writeflag == MEM_WRITE) {
195 debug("[ sgi_ip22_unknown: unimplemented write to "
196 "address 0x%x, data=0x%08x ]\n",
197 (int)relative_addr, (int)idata);
198 } else {
199 debug("[ sgi_ip22_unknown: unimplemented read from "
200 "address 0x%x, data=0x%08x ]\n",
201 (int)relative_addr, (int)odata);
202 }
203 }
204
205 if (writeflag == MEM_READ)
206 memory_writemax64(cpu, data, len, odata);
207
208 return 1;
209 }
210
211
212 /*
213 * dev_sgi_ip22_unknown2_access():
214 *
215 * A so far unknown device, used by the IP22 prom during startup.
216 */
217 int dev_sgi_ip22_unknown2_access(struct cpu *cpu, struct memory *mem,
218 uint64_t relative_addr, unsigned char *data, size_t len,
219 int writeflag, void *extra)
220 {
221 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
222 uint64_t idata = 0, odata = 0;
223 int regnr;
224
225 idata = memory_readmax64(cpu, data, len);
226 regnr = relative_addr / sizeof(uint32_t);
227
228 if (writeflag == MEM_WRITE)
229 d->unknown2_reg[regnr] = idata;
230 else
231 odata = d->unknown2_reg[regnr];
232
233 switch (relative_addr) {
234 default:
235 if (writeflag == MEM_WRITE) {
236 debug("[ sgi_ip22_unknown2: unimplemented write "
237 "to address 0x%x, data=0x%08x ]\n",
238 (int)relative_addr, (int)idata);
239 } else {
240 debug("[ sgi_ip22_unknown2: unimplemented read from "
241 "address 0x%x, data=0x%08x ]\n",
242 (int)relative_addr, (int)odata);
243 }
244 }
245
246 if (writeflag == MEM_READ)
247 memory_writemax64(cpu, data, len, odata);
248
249 return 1;
250 }
251
252
253 /*
254 * dev_sgi_ip22_sysid_access():
255 */
256 int dev_sgi_ip22_sysid_access(struct cpu *cpu, struct memory *mem,
257 uint64_t relative_addr, unsigned char *data, size_t len,
258 int writeflag, void *extra)
259 {
260 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
261 uint64_t idata = 0, odata = 0;
262
263 idata = memory_readmax64(cpu, data, len);
264
265 if (writeflag == MEM_WRITE) {
266 debug("[ sgi_ip22_sysid: write to address 0x%x, "
267 "data=0x%08x ]\n", (int)relative_addr, (int)idata);
268 } else {
269 /*
270 * According to NetBSD's sgimips/ip22.c:
271 *
272 * printf("IOC rev %d, machine %s, board rev %d\n",
273 * (sysid >> 5) & 0x07,
274 * (sysid & 1) ? "Indigo2 (Fullhouse)" : "Indy (Guiness)",
275 * (sysid >> 1) & 0x0f);
276 */
277
278 /* IOC rev 1, Guiness, board rev 3: */
279 odata = (1 << 5) + (3 << 1) + (d->guiness_flag? 0 : 1);
280
281 debug("[ sgi_ip22_sysid: read from address 0x%x, data="
282 "0x%08x ]\n", (int)relative_addr, (int)odata);
283 }
284
285 if (writeflag == MEM_READ)
286 memory_writemax64(cpu, data, len, odata);
287
288 return 1;
289 }
290
291
292 /*
293 * dev_sgi_ip22_access():
294 *
295 * Returns 1 if ok, 0 on error.
296 */
297 int dev_sgi_ip22_access(struct cpu *cpu, struct memory *mem,
298 uint64_t relative_addr, unsigned char *data, size_t len,
299 int writeflag, void *extra)
300 {
301 struct sgi_ip22_data *d = (struct sgi_ip22_data *) extra;
302 uint64_t idata = 0, odata = 0;
303 int regnr;
304
305 idata = memory_readmax64(cpu, data, len);
306 regnr = relative_addr / sizeof(uint32_t);
307
308 if (writeflag == MEM_WRITE)
309 d->reg[regnr] = idata;
310 else
311 odata = d->reg[regnr];
312
313 /* Read from/write to the sgi_ip22: */
314 switch (relative_addr) {
315 case 0x00: /* local0 irq stat */
316 if (writeflag == MEM_WRITE) {
317 debug("[ sgi_ip22: write to local0 IRQ STAT, "
318 "data=0x%llx ]\n", (long long)idata);
319 } else {
320 debug("[ sgi_ip22: read from local0 IRQ STAT, "
321 "data=0x%llx ]\n", (long long)odata);
322 }
323 break;
324 case 0x04: /* local0 irq mask */
325 if (writeflag == MEM_WRITE) {
326 /*
327 * Ugly hack: if an interrupt is asserted, and someone
328 * writes to this mask register, the interrupt should
329 * be masked. That is, sgi_ip22_interrupt() in
330 * src/machine.c has to be called to deal with this.
331 * The ugly solution I choose here is to deassert
332 * some interrupt which should never be used anyway.
333 * (TODO: Fix this.)
334 */
335 cpu_interrupt_ack(cpu, 8 + 63);
336 debug("[ sgi_ip22: write to local0 IRQ MASK, "
337 "data=0x%llx ]\n", (long long)idata);
338 } else {
339 debug("[ sgi_ip22: read from local0 IRQ MASK, "
340 "data=0x%llx ]\n", (long long)odata);
341 }
342 break;
343 case 0x08: /* local1 irq stat */
344 if (writeflag == MEM_WRITE) {
345 debug("[ sgi_ip22: write to local1 IRQ STAT, "
346 "data=0x%llx ]\n", (long long)idata);
347 } else {
348 debug("[ sgi_ip22: read from local1 IRQ STAT, "
349 "data=0x%llx ]\n", (long long)odata);
350 }
351 break;
352 case 0x0c: /* local1 irq mask */
353 if (writeflag == MEM_WRITE) {
354 /* See commen above, about local0 irq mask. */
355 cpu_interrupt_ack(cpu, 8 + 63);
356 debug("[ sgi_ip22: write to local1 IRQ MASK, "
357 "data=0x%llx ]\n", (long long)idata);
358 } else {
359 debug("[ sgi_ip22: read from local1 IRQ MASK, "
360 "data=0x%llx ]\n", (long long)odata);
361 }
362 break;
363 case 0x10:
364 if (writeflag == MEM_WRITE) {
365 debug("[ sgi_ip22: write to mappable IRQ STAT, "
366 "data=0x%llx ]\n", (long long)idata);
367 } else {
368 debug("[ sgi_ip22: read from mappable IRQ STAT, "
369 "data=0x%llx ]\n", (long long)odata);
370 }
371 break;
372 case 0x14:
373 if (writeflag == MEM_WRITE) {
374 debug("[ sgi_ip22: write to mappable local0 IRQ "
375 "MASK, data=0x%llx ]\n", (long long)idata);
376 } else {
377 debug("[ sgi_ip22: read from mappable local0 IRQ "
378 "MASK, data=0x%llx ]\n", (long long)odata);
379 }
380 break;
381 case 0x18:
382 if (writeflag == MEM_WRITE) {
383 debug("[ sgi_ip22: write to mappable local1 IRQ "
384 "MASK, data=0x%llx ]\n", (long long)idata);
385 } else {
386 debug("[ sgi_ip22: read from mappable local1 IRQ "
387 "MASK, data=0x%llx ]\n", (long long)odata);
388 }
389 break;
390 case 0x38: /* timer count */
391 if (writeflag == MEM_WRITE) {
392 /* Two byte values are written to this address,
393 sequentially... TODO */
394 } else {
395 /* The timer is decreased by the tick function. */
396 }
397 break;
398 case 0x3b: /* ? */
399 odata = random();
400 break;
401 case 0x3c: /* timer control */
402 break;
403 case 0x3f: /* ? */
404 odata = random();
405 break;
406 default:
407 if (writeflag == MEM_WRITE) {
408 debug("[ sgi_ip22: unimplemented write to address "
409 "0x%x, data=0x%02x ]\n", (int)relative_addr,
410 (int)idata);
411 } else {
412 debug("[ sgi_ip22: unimplemented read from address "
413 "0x%llx ]\n", (long long)relative_addr);
414 }
415 }
416
417 if (writeflag == MEM_READ)
418 memory_writemax64(cpu, data, len, odata);
419
420 return 1;
421 }
422
423
424 /*
425 * dev_sgi_ip22_init():
426 */
427 struct sgi_ip22_data *dev_sgi_ip22_init(struct machine *machine,
428 struct memory *mem, uint64_t baseaddr, int guiness_flag)
429 {
430 struct sgi_ip22_data *d = malloc(sizeof(struct sgi_ip22_data));
431 if (d == NULL) {
432 fprintf(stderr, "out of memory\n");
433 exit(1);
434 }
435 memset(d, 0, sizeof(struct sgi_ip22_data));
436 d->guiness_flag = guiness_flag;
437
438 memory_device_register(mem, "sgi_ip22", baseaddr, DEV_SGI_IP22_LENGTH,
439 dev_sgi_ip22_access, (void *)d, DM_DEFAULT, NULL);
440 memory_device_register(mem, "sgi_ip22_sysid", 0x1fbd9858, 0x8,
441 dev_sgi_ip22_sysid_access, (void *)d, DM_DEFAULT, NULL);
442 memory_device_register(mem, "sgi_ip22_imc", IP22_IMC_BASE,
443 DEV_SGI_IP22_IMC_LENGTH, dev_sgi_ip22_imc_access, (void *)d,
444 DM_DEFAULT, NULL);
445 memory_device_register(mem, "sgi_ip22_unknown", 0x1fa01000, 0x10,
446 dev_sgi_ip22_unknown_access, (void *)d, DM_DEFAULT, NULL);
447 memory_device_register(mem, "sgi_ip22_unknown2", IP22_UNKNOWN2_BASE,
448 DEV_SGI_IP22_UNKNOWN2_LENGTH, dev_sgi_ip22_unknown2_access,
449 (void *)d, DM_DEFAULT, NULL);
450
451 machine_add_tickfunction(machine, dev_sgi_ip22_tick, d,
452 SGI_IP22_TICK_SHIFT);
453
454 return d;
455 }
456

  ViewVC Help
Powered by ViewVC 1.1.26