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

  ViewVC Help
Powered by ViewVC 1.1.26