/[gxemul]/upstream/0.3.8/src/devices/dev_rd94.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.8/src/devices/dev_rd94.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 5923 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2003-2006 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_rd94.c,v 1.34 2006/02/09 20:02:59 debug Exp $
29 *
30 * Used by NEC-RD94, -R94, and -R96.
31 */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "bus_pci.h"
38 #include "cop0.h"
39 #include "cpu.h"
40 #include "cpu_mips.h"
41 #include "device.h"
42 #include "machine.h"
43 #include "memory.h"
44 #include "misc.h"
45
46 #include "rd94.h"
47
48
49 #define RD94_TICK_SHIFT 14
50
51 #define DEV_RD94_LENGTH 0x1000
52
53 struct rd94_data {
54 struct pci_data *pci_data;
55 uint32_t reg[DEV_RD94_LENGTH / 4];
56 int pciirq;
57
58 int intmask;
59 int interval;
60 int interval_start;
61 };
62
63
64 /*
65 * dev_rd94_tick():
66 */
67 void dev_rd94_tick(struct cpu *cpu, void *extra)
68 {
69 struct rd94_data *d = extra;
70
71 /* TODO: hm... intmask !=0 ? */
72 if (d->interval_start > 0 && d->interval > 0 && d->intmask != 0) {
73 d->interval --;
74 if (d->interval <= 0) {
75 debug("[ rd94: interval timer interrupt ]\n");
76 cpu_interrupt(cpu, 5);
77 }
78 }
79 }
80
81
82 /*
83 * dev_rd94_access():
84 */
85 DEVICE_ACCESS(rd94)
86 {
87 struct rd94_data *d = (struct rd94_data *) extra;
88 uint64_t idata = 0, odata = 0;
89 int regnr, bus, dev, func, pcireg;
90
91 if (writeflag == MEM_WRITE)
92 idata = memory_readmax64(cpu, data, len);
93
94 regnr = relative_addr / sizeof(uint32_t);
95
96 switch (relative_addr) {
97
98 case RD94_SYS_CONFIG:
99 if (writeflag == MEM_WRITE) {
100 fatal("[ rd94: write to CONFIG: 0x%llx ]\n",
101 (long long)idata);
102 } else {
103 odata = 0;
104 fatal("[ rd94: read from CONFIG: 0x%llx ]\n",
105 (long long)odata);
106 }
107 break;
108
109 case RD94_SYS_INTSTAT1: /* LB (Local Bus ???) */
110 if (writeflag == MEM_WRITE) {
111 } else {
112 /* Return value is (irq level + 1) << 2 */
113 odata = (8+1) << 2;
114
115 /* Ugly hack: */
116 if ((cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] & 0x800)
117 == 0)
118 odata = 0;
119 }
120 debug("[ rd94: intstat1 ]\n");
121 /* cpu_interrupt_ack(cpu, 3); */
122 break;
123
124 case RD94_SYS_INTSTAT2: /* PCI/EISA */
125 if (writeflag == MEM_WRITE) {
126 } else {
127 odata = 0; /* TODO */
128 }
129 debug("[ rd94: intstat2 ]\n");
130 /* cpu_interrupt_ack(cpu, 4); */
131 break;
132
133 case RD94_SYS_INTSTAT3: /* IT (Interval Timer) */
134 if (writeflag == MEM_WRITE) {
135 } else {
136 odata = 0; /* return value does not matter? */
137 }
138 debug("[ rd94: intstat3 ]\n");
139 cpu_interrupt_ack(cpu, 5);
140 d->interval = d->interval_start;
141 break;
142
143 case RD94_SYS_INTSTAT4: /* IPI */
144 if (writeflag == MEM_WRITE) {
145 } else {
146 odata = 0; /* return value does not matter? */
147 }
148 fatal("[ rd94: intstat4 ]\n");
149 cpu_interrupt_ack(cpu, 6);
150 break;
151
152 case RD94_SYS_CPUID:
153 if (writeflag == MEM_WRITE) {
154 fatal("[ rd94: write to CPUID: 0x%llx ]\n",
155 (long long)idata);
156 } else {
157 odata = cpu->cpu_id;
158 fatal("[ rd94: read from CPUID: 0x%llx ]\n",
159 (long long)odata);
160 }
161 break;
162
163 case RD94_SYS_EXT_IMASK:
164 if (writeflag == MEM_WRITE) {
165 d->intmask = idata;
166 } else {
167 odata = d->intmask;
168 }
169 break;
170
171 case RD94_SYS_IT_VALUE:
172 if (writeflag == MEM_WRITE) {
173 d->interval = d->interval_start = idata;
174 debug("[ rd94: setting Interval Timer value to %i ]\n",
175 (int)idata);
176 } else {
177 odata = d->interval_start;
178 /* TODO: or d->interval ? */;
179 }
180 break;
181
182 case RD94_SYS_PCI_CONFADDR:
183 bus_pci_decompose_1(idata, &bus, &dev, &func, &pcireg);
184 bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, pcireg);
185 break;
186
187 case RD94_SYS_PCI_CONFDATA:
188 bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
189 &odata : &idata, len, writeflag);
190 break;
191
192 default:if (writeflag == MEM_WRITE) {
193 fatal("[ rd94: unimplemented write to address 0x%x, "
194 "data=0x%02x ]\n", (int)relative_addr, (int)idata);
195 } else {
196 fatal("[ rd94: unimplemented read from address 0x%x"
197 " ]\n", (int)relative_addr);
198 }
199 }
200
201 if (writeflag == MEM_READ)
202 memory_writemax64(cpu, data, len, odata);
203
204 return 1;
205 }
206
207
208 DEVINIT(rd94)
209 {
210 struct rd94_data *d = malloc(sizeof(struct rd94_data));
211 if (d == NULL) {
212 fprintf(stderr, "out of memory\n");
213 exit(1);
214 }
215 memset(d, 0, sizeof(struct rd94_data));
216 d->pciirq = devinit->irq_nr;
217 d->pci_data = bus_pci_init(devinit->machine, d->pciirq,
218 0,0, 0,0,0, 0,0,0);
219
220 memory_device_register(devinit->machine->memory, devinit->name,
221 devinit->addr, DEV_RD94_LENGTH,
222 dev_rd94_access, (void *)d, DM_DEFAULT, NULL);
223
224 machine_add_tickfunction(devinit->machine, dev_rd94_tick,
225 d, RD94_TICK_SHIFT);
226
227 devinit->return_ptr = d->pci_data;
228
229 return 1;
230 }
231

  ViewVC Help
Powered by ViewVC 1.1.26