/[gxemul]/upstream/0.3.6.2/src/devices/dev_dec5800.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.6.2/src/devices/dev_dec5800.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (show annotations)
Mon Oct 8 16:19:16 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 12503 byte(s)
0.3.6.2
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_dec5800.c,v 1.16 2005/10/26 14:37:03 debug Exp $
29 *
30 * Emulation of devices found in a DECsystem 58x0, where x is the number
31 * of CPUs in the system. (The CPU board is called KN5800 by Ultrix.)
32 *
33 * o) timers and misc stuff
34 * o) BI (Backplane Interconnect)
35 * o) CCA (Console Communication Area)
36 * o) XMI (Extended Memory Interconnect)
37 *
38 * TODO: This hardware is not very easy to find docs about.
39 * Perhaps VAX 6000/300 docs?
40 */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "console.h"
47 #include "cpu.h"
48 #include "devices.h"
49 #include "machine.h"
50 #include "memory.h"
51 #include "misc.h"
52
53
54 /*
55 * dev_dec5800_tick():
56 */
57 void dev_dec5800_tick(struct cpu *cpu, void *extra)
58 {
59 struct dec5800_data *d = extra;
60
61 /* Timer interrupts? */
62 if (d->csr & 0x8000) {
63 debug("[ dec5800: timer interrupt! ]\n");
64
65 /* Set timer interrupt pending bit: */
66 d->csr |= 0x20000000;
67
68 cpu_interrupt(cpu, 3);
69 }
70 }
71
72
73 /*
74 * dev_dec5800_vectors_access():
75 */
76 int dev_dec5800_vectors_access(struct cpu *cpu, struct memory *mem,
77 uint64_t relative_addr, unsigned char *data, size_t len,
78 int writeflag, void *extra)
79 {
80 uint64_t idata = 0, odata = 0;
81 struct dec5800_data *d = extra;
82
83 if (writeflag == MEM_WRITE)
84 idata = memory_readmax64(cpu, data, len);
85
86 if (writeflag == MEM_READ) {
87 /* TODO */
88 /* 0xfc = transmit interrupt, 0xf8 = receive interrupt,
89 0x80 = IPI */
90 odata = d->vector_0x50;
91 /* odata = 0xfc; */
92 debug("[ dec5800_vectors: read from 0x%02x: 0x%02x ]\n",
93 (int)relative_addr, (int)odata);
94 } else {
95 d->vector_0x50 = idata;
96 debug("[ dec5800_vectors: write to 0x%02x: 0x%02x ]\n",
97 (int)relative_addr, (int)idata);
98 }
99
100 if (writeflag == MEM_READ)
101 memory_writemax64(cpu, data, len, odata);
102
103 return 1;
104 }
105
106
107 /*
108 * dev_dec5800_access():
109 */
110 int dev_dec5800_access(struct cpu *cpu, struct memory *mem,
111 uint64_t relative_addr, unsigned char *data, size_t len,
112 int writeflag, void *extra)
113 {
114 uint64_t idata = 0, odata = 0;
115 struct dec5800_data *d = extra;
116
117 if (writeflag == MEM_WRITE)
118 idata = memory_readmax64(cpu, data, len);
119
120 /* Lowest 4 bits of csr contain cpu id: */
121 d->csr = (d->csr & ~0xf) | (cpu->cpu_id & 0xf);
122
123 switch (relative_addr) {
124 case 0x0000: /* csr */
125 if (writeflag == MEM_READ) {
126 odata = d->csr;
127 odata ^= random() & 0x10000;
128 debug("[ dec5800: read from csr: 0x%08x ]\n",
129 (int)odata);
130 } else {
131 d->csr = idata;
132
133 /* Ack. timer interrupts: */
134 d->csr &= ~0x20000000;
135 cpu_interrupt_ack(cpu, 3);
136
137 debug("[ dec5800: write to csr: 0x%08x ]\n",
138 (int)idata);
139 }
140 break;
141 default:
142 if (writeflag==MEM_READ) {
143 debug("[ dec5800: read from 0x%08lx ]\n",
144 (long)relative_addr);
145 } else {
146 debug("[ dec5800: write to 0x%08lx: 0x%08x ]\n",
147 (long)relative_addr, (int)idata);
148 }
149 }
150
151 if (writeflag == MEM_READ)
152 memory_writemax64(cpu, data, len, odata);
153
154 return 1;
155 }
156
157
158 /*
159 * dev_dec5800_init():
160 */
161 struct dec5800_data *dev_dec5800_init(struct machine *machine,
162 struct memory *mem, uint64_t baseaddr)
163 {
164 struct dec5800_data *d;
165
166 d = malloc(sizeof(struct dec5800_data));
167 if (d == NULL) {
168 fprintf(stderr, "out of memory\n");
169 exit(1);
170 }
171 memset(d, 0, sizeof(struct dec5800_data));
172
173 memory_device_register(mem, "dec5800", baseaddr,
174 DEV_DEC5800_LENGTH, dev_dec5800_access, d, MEM_DEFAULT, NULL);
175 memory_device_register(mem, "dec5800_vectors",
176 baseaddr + 0x30000000, 0x100, dev_dec5800_vectors_access,
177 d, MEM_DEFAULT, NULL);
178 machine_add_tickfunction(machine, dev_dec5800_tick, d, 14);
179
180 return d;
181 }
182
183
184 /*****************************************************************************/
185
186
187 #include "bireg.h"
188
189 struct decbi_data {
190 int csr[NNODEBI];
191 };
192
193
194 /*
195 * dev_decbi_access():
196 */
197 int dev_decbi_access(struct cpu *cpu, struct memory *mem,
198 uint64_t relative_addr, unsigned char *data, size_t len,
199 int writeflag, void *extra)
200 {
201 uint64_t idata = 0, odata = 0;
202 int node_nr;
203 struct decbi_data *d = extra;
204
205 if (writeflag == MEM_WRITE)
206 idata = memory_readmax64(cpu, data, len);
207
208 relative_addr += BI_NODESIZE; /* HACK */
209
210 node_nr = relative_addr / BI_NODESIZE;
211 relative_addr &= (BI_NODESIZE - 1);
212
213 /* TODO: This "1" here is the max node number in actual use. */
214 if (node_nr > 1 || node_nr >= NNODEBI)
215 return 0;
216
217 switch (relative_addr) {
218 case BIREG_DTYPE:
219 if (writeflag==MEM_READ) {
220 /*
221 * This is a list of the devices in our BI slots:
222 */
223 switch (node_nr) {
224 case 1: odata = BIDT_KDB50; break; /* Disk */
225 /* case 2: odata = BIDT_DEBNA; break; */
226 /* BIDT_DEBNA = Ethernet */
227 /* case 3: odata = BIDT_MS820; break; */
228 /* BIDT_MS820 = Memory */
229 default:
230 /* No device. */
231 odata = 0;
232 }
233
234 debug("[ decbi: (node %i) read from BIREG_DTYPE:"
235 " 0x%x ]\n", node_nr, (int)odata);
236 } else {
237 debug("[ decbi: (node %i) attempt to write to "
238 "BIREG_DTYPE: 0x%08x ]\n", node_nr, (int)idata);
239 }
240 break;
241 case BIREG_VAXBICSR:
242 if (writeflag==MEM_READ) {
243 odata = (d->csr[node_nr] & ~BICSR_NODEMASK) | node_nr;
244 debug("[ decbi: (node %i) read from BIREG_"
245 "VAXBICSR: 0x%x ]\n", node_nr, (int)odata);
246 } else {
247 d->csr[node_nr] = idata;
248 debug("[ decbi: (node %i) attempt to write to "
249 "BIREG_VAXBICSR: 0x%08x ]\n", node_nr, (int)idata);
250 }
251 break;
252 case 0xf4:
253 if (writeflag==MEM_READ) {
254 odata = 0xffff; /* ? */
255 debug("[ decbi: (node %i) read from 0xf4: "
256 "0x%x ]\n", node_nr, (int)odata);
257 } else {
258 debug("[ decbi: (node %i) attempt to write "
259 "to 0xf4: 0x%08x ]\n", node_nr, (int)idata);
260 }
261 break;
262 default:
263 if (writeflag==MEM_READ) {
264 debug("[ decbi: (node %i) read from unimplemented "
265 "0x%08lx ]\n", node_nr, (long)relative_addr,
266 (int)odata);
267 } else {
268 debug("[ decbi: (node %i) write to unimplemented "
269 "0x%08lx: 0x%08x ]\n", node_nr,
270 (long)relative_addr, (int)idata);
271 }
272 }
273
274 if (writeflag == MEM_READ)
275 memory_writemax64(cpu, data, len, odata);
276
277 return 1;
278 }
279
280
281 /*
282 * dev_decbi_init():
283 */
284 void dev_decbi_init(struct memory *mem, uint64_t baseaddr)
285 {
286 struct decbi_data *d;
287
288 d = malloc(sizeof(struct decbi_data));
289 if (d == NULL) {
290 fprintf(stderr, "out of memory\n");
291 exit(1);
292 }
293 memset(d, 0, sizeof(struct decbi_data));
294
295 memory_device_register(mem, "decbi", baseaddr + 0x2000,
296 DEV_DECBI_LENGTH - 0x2000, dev_decbi_access, d, MEM_DEFAULT, NULL);
297 }
298
299
300 /*****************************************************************************/
301
302
303 /*
304 * CCA, "Console Communication Area" for a DEC 5800 SMP system.
305 */
306
307 struct deccca_data {
308 int dummy;
309 };
310
311
312 /*
313 * dev_deccca_access():
314 */
315 int dev_deccca_access(struct cpu *cpu, struct memory *mem,
316 uint64_t relative_addr, unsigned char *data, size_t len,
317 int writeflag, void *extra)
318 {
319 uint64_t idata = 0, odata = 0;
320 /* struct deccca_data *d = extra; */
321
322 if (writeflag == MEM_WRITE)
323 idata = memory_readmax64(cpu, data, len);
324
325 switch (relative_addr) {
326 case 6:
327 case 7:
328 /* CCA "ID" bytes? These must be here, or Ultrix complains. */
329 if (writeflag == MEM_READ)
330 odata = 67;
331 break;
332 case 8:
333 if (writeflag == MEM_READ)
334 odata = cpu->machine->ncpus;
335 break;
336 case 20:
337 if (writeflag == MEM_READ)
338 odata = (1 << cpu->machine->ncpus) - 1;
339 /* one bit for each cpu */
340 break;
341 case 28:
342 if (writeflag == MEM_READ)
343 odata = (1 << cpu->machine->ncpus) - 1;
344 /* one bit for each enabled(?) cpu */
345 break;
346 default:
347 if (writeflag==MEM_READ) {
348 debug("[ deccca: read from 0x%08lx ]\n",
349 (long)relative_addr);
350 } else {
351 debug("[ deccca: write to 0x%08lx: 0x%08x ]\n",
352 (long)relative_addr, (int)idata);
353 }
354 }
355
356 if (writeflag == MEM_READ)
357 memory_writemax64(cpu, data, len, odata);
358
359 return 1;
360 }
361
362
363 /*
364 * dev_deccca_init():
365 */
366 void dev_deccca_init(struct memory *mem, uint64_t baseaddr)
367 {
368 struct deccca_data *d;
369
370 d = malloc(sizeof(struct deccca_data));
371 if (d == NULL) {
372 fprintf(stderr, "out of memory\n");
373 exit(1);
374 }
375 memset(d, 0, sizeof(struct deccca_data));
376
377 memory_device_register(mem, "deccca", baseaddr, DEV_DECCCA_LENGTH,
378 dev_deccca_access, d, MEM_DEFAULT, NULL);
379 }
380
381
382 /*****************************************************************************/
383
384
385 /*
386 * DEC 5800 XMI (this has to do with SMP...)
387 */
388
389 #include "xmireg.h"
390
391 struct decxmi_data {
392 uint32_t reg_0xc[NNODEXMI];
393 };
394
395
396 /*
397 * dev_decxmi_access():
398 */
399 int dev_decxmi_access(struct cpu *cpu, struct memory *mem,
400 uint64_t relative_addr, unsigned char *data, size_t len,
401 int writeflag, void *extra)
402 {
403 uint64_t idata = 0, odata = 0;
404 int node_nr;
405 struct decxmi_data *d = extra;
406
407 if (writeflag == MEM_WRITE)
408 idata = memory_readmax64(cpu, data, len);
409
410 node_nr = relative_addr / XMI_NODESIZE;
411 relative_addr &= (XMI_NODESIZE - 1);
412
413 if (node_nr >= cpu->machine->ncpus + 1 || node_nr >= NNODEXMI)
414 return 0;
415
416 switch (relative_addr) {
417 case XMI_TYPE:
418 if (writeflag == MEM_READ) {
419 /*
420 * The first node is an XMI->BI adapter node, and then
421 * there are n CPU nodes.
422 */
423 odata = XMIDT_ISIS;
424 if (node_nr == 0)
425 odata = XMIDT_DWMBA;
426
427 debug("[ decxmi: (node %i) read from XMI_TYPE: "
428 "0x%08x ]\n", node_nr, (int)odata);
429 } else
430 debug("[ decxmi: (node %i) write to XMI_TYPE: "
431 "0x%08x ]\n", node_nr, (int)idata);
432 break;
433 case XMI_BUSERR:
434 if (writeflag == MEM_READ) {
435 odata = 0;
436 debug("[ decxmi: (node %i) read from XMI_BUSERR: "
437 "0x%08x ]\n", node_nr, (int)odata);
438 } else
439 debug("[ decxmi: (node %i) write to XMI_BUSERR: "
440 "0x%08x ]\n", node_nr, (int)idata);
441 break;
442 case XMI_FAIL:
443 if (writeflag == MEM_READ) {
444 odata = 0;
445 debug("[ decxmi: (node %i) read from XMI_FAIL: "
446 "0x%08x ]\n", node_nr, (int)odata);
447 } else
448 debug("[ decxmi: (node %i) write to XMI_FAIL: "
449 "0x%08x ]\n", node_nr, (int)idata);
450 break;
451 case 0xc:
452 if (writeflag == MEM_READ) {
453 odata = d->reg_0xc[node_nr];
454 debug("[ decxmi: (node %i) read from REG 0xC: "
455 "0x%08x ]\n", node_nr, (int)odata);
456 } else {
457 d->reg_0xc[node_nr] = idata;
458 debug("[ decxmi: (node %i) write to REG 0xC: "
459 "0x%08x ]\n", node_nr, (int)idata);
460 }
461 break;
462 default:
463 if (writeflag==MEM_READ) {
464 debug("[ decxmi: (node %i) read from unimplemented "
465 "0x%08lx ]\n", node_nr, (long)relative_addr,
466 (int)odata);
467 } else {
468 debug("[ decxmi: (node %i) write to unimplemented "
469 "0x%08lx: 0x%08x ]\n", node_nr,
470 (long)relative_addr, (int)idata);
471 }
472 }
473
474 if (writeflag == MEM_READ)
475 memory_writemax64(cpu, data, len, odata);
476
477 return 1;
478 }
479
480
481 /*
482 * dev_decxmi_init():
483 */
484 void dev_decxmi_init(struct memory *mem, uint64_t baseaddr)
485 {
486 struct decxmi_data *d;
487
488 d = malloc(sizeof(struct decxmi_data));
489 if (d == NULL) {
490 fprintf(stderr, "out of memory\n");
491 exit(1);
492 }
493 memset(d, 0, sizeof(struct decxmi_data));
494
495 memory_device_register(mem, "decxmi", baseaddr, DEV_DECXMI_LENGTH,
496 dev_decxmi_access, d, MEM_DEFAULT, NULL);
497 }
498

  ViewVC Help
Powered by ViewVC 1.1.26