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

Annotation of /upstream/0.3.6.1/src/devices/dev_sgi_ip22.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26