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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26