/[gxemul]/upstream/0.3.1/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.1/devices/dev_rd94.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: 6124 byte(s)
0.3.1
1 /*
2 * Copyright (C) 2003-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_rd94.c,v 1.24 2005/03/18 23:20:52 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 int dev_rd94_access(struct cpu *cpu, struct memory *mem,
86 uint64_t relative_addr, unsigned char *data, size_t len,
87 int writeflag, void *extra)
88 {
89 struct rd94_data *d = (struct rd94_data *) extra;
90 uint64_t idata = 0, odata = 0;
91 int regnr;
92
93 idata = memory_readmax64(cpu, data, len);
94 regnr = relative_addr / sizeof(uint32_t);
95
96 switch (relative_addr) {
97 case RD94_SYS_CONFIG:
98 if (writeflag == MEM_WRITE) {
99 fatal("[ rd94: write to CONFIG: 0x%llx ]\n",
100 (long long)idata);
101 } else {
102 odata = 0;
103 fatal("[ rd94: read from CONFIG: 0x%llx ]\n",
104 (long long)odata);
105 }
106 break;
107 case RD94_SYS_INTSTAT1: /* LB (Local Bus ???) */
108 if (writeflag == MEM_WRITE) {
109 } else {
110 /* Return value is (irq level + 1) << 2 */
111 odata = (8+1) << 2;
112
113 /* Ugly hack: */
114 if ((cpu->cd.mips.coproc[0]->reg[COP0_CAUSE] & 0x800)
115 == 0)
116 odata = 0;
117 }
118 debug("[ rd94: intstat1 ]\n");
119 /* cpu_interrupt_ack(cpu, 3); */
120 break;
121 case RD94_SYS_INTSTAT2: /* PCI/EISA */
122 if (writeflag == MEM_WRITE) {
123 } else {
124 odata = 0; /* TODO */
125 }
126 debug("[ rd94: intstat2 ]\n");
127 /* cpu_interrupt_ack(cpu, 4); */
128 break;
129 case RD94_SYS_INTSTAT3: /* IT (Interval Timer) */
130 if (writeflag == MEM_WRITE) {
131 } else {
132 odata = 0; /* return value does not matter? */
133 }
134 debug("[ rd94: intstat3 ]\n");
135 cpu_interrupt_ack(cpu, 5);
136 d->interval = d->interval_start;
137 break;
138 case RD94_SYS_INTSTAT4: /* IPI */
139 if (writeflag == MEM_WRITE) {
140 } else {
141 odata = 0; /* return value does not matter? */
142 }
143 fatal("[ rd94: intstat4 ]\n");
144 cpu_interrupt_ack(cpu, 6);
145 break;
146 case RD94_SYS_CPUID:
147 if (writeflag == MEM_WRITE) {
148 fatal("[ rd94: write to CPUID: 0x%llx ]\n",
149 (long long)idata);
150 } else {
151 odata = cpu->cpu_id;
152 fatal("[ rd94: read from CPUID: 0x%llx ]\n",
153 (long long)odata);
154 }
155 break;
156 case RD94_SYS_EXT_IMASK:
157 if (writeflag == MEM_WRITE) {
158 d->intmask = idata;
159 } else {
160 odata = d->intmask;
161 }
162 break;
163 case RD94_SYS_IT_VALUE:
164 if (writeflag == MEM_WRITE) {
165 d->interval = d->interval_start = idata;
166 debug("[ rd94: setting Interval Timer value to %i ]\n",
167 (int)idata);
168 } else {
169 odata = d->interval_start;
170 /* TODO: or d->interval ? */;
171 }
172 break;
173 case RD94_SYS_PCI_CONFADDR:
174 case RD94_SYS_PCI_CONFDATA:
175 if (writeflag == MEM_WRITE) {
176 bus_pci_access(cpu, mem, relative_addr ==
177 RD94_SYS_PCI_CONFADDR? BUS_PCI_ADDR : BUS_PCI_DATA,
178 &idata, writeflag, d->pci_data);
179 } else {
180 bus_pci_access(cpu, mem, relative_addr ==
181 RD94_SYS_PCI_CONFADDR? BUS_PCI_ADDR : BUS_PCI_DATA,
182 &odata, writeflag, d->pci_data);
183 /* odata = 0; */
184 }
185 break;
186 default:
187 if (writeflag == MEM_WRITE) {
188 fatal("[ rd94: unimplemented write to address 0x%x, "
189 "data=0x%02x ]\n", (int)relative_addr, (int)idata);
190 } else {
191 fatal("[ rd94: unimplemented read from address 0x%x"
192 " ]\n", (int)relative_addr);
193 }
194 }
195
196 if (writeflag == MEM_READ)
197 memory_writemax64(cpu, data, len, odata);
198
199 return 1;
200 }
201
202
203 /*
204 * devinit_rd94():
205 */
206 int devinit_rd94(struct devinit *devinit)
207 {
208 struct rd94_data *d = malloc(sizeof(struct rd94_data));
209 if (d == NULL) {
210 fprintf(stderr, "out of memory\n");
211 exit(1);
212 }
213 memset(d, 0, sizeof(struct rd94_data));
214 d->pciirq = devinit->irq_nr;
215 d->pci_data = bus_pci_init(d->pciirq);
216
217 memory_device_register(devinit->machine->memory, devinit->name,
218 devinit->addr, DEV_RD94_LENGTH,
219 dev_rd94_access, (void *)d, MEM_DEFAULT, NULL);
220
221 machine_add_tickfunction(devinit->machine, dev_rd94_tick,
222 d, RD94_TICK_SHIFT);
223
224 devinit->return_ptr = d->pci_data;
225
226 return 1;
227 }
228

  ViewVC Help
Powered by ViewVC 1.1.26