|
|
1.1.1.5 root 1: /* $Id: sun2-mainbus.c,v 1.18 2009/08/30 14:32:29 fredette Exp $ */
1.1 root 2:
3: /* machine/sun2/sun2-mainbus.c - implementation of Sun 2 emulation: */
4:
5: /*
6: * Copyright (c) 2003 Matt Fredette
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Matt Fredette.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33: * POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: #include <tme/common.h>
1.1.1.5 root 37: _TME_RCSID("$Id: sun2-mainbus.c,v 1.18 2009/08/30 14:32:29 fredette Exp $");
1.1 root 38:
39: /* includes: */
40: #include "sun2-impl.h"
41: #include <tme/ic/am9513.h>
42: #include <tme/ic/z8530.h>
43: #include <tme/ic/mm58167.h>
44: #include <stdio.h>
45:
46: /* this possibly updates that the interrupt priority level driven to the CPU: */
47: int
48: _tme_sun2_ipl_check(struct tme_sun2 *sun2)
49: {
50: tme_uint16_t ena;
51: unsigned int ipl, ipl_index;
52: tme_uint8_t ipl_mask;
53:
54: /* get the enable register: */
55: ena = sun2->tme_sun2_enable;
56:
57: /* assume that interrupts are completely masked: */
58: ipl = TME_M68K_IPL_NONE;
59:
60: /* if interrupts are enabled: */
61: if (ena & TME_SUN2_ENA_INTS) {
62:
63: /* find the highest ipl now asserted on the buses: */
64: for (ipl = TME_M68K_IPL_MAX;
65: ipl > TME_M68K_IPL_NONE;
66: ipl--) {
67: ipl_index = ipl >> 3;
68: ipl_mask = TME_BIT(ipl & 7);
69: if (sun2->tme_sun2_int_signals[ipl_index] & ipl_mask) {
70: break;
71: }
72: }
73:
74: /* check the soft interrupts: */
75: if (ena & TME_SUN2_ENA_SOFT_INT_3) {
76: ipl = TME_MAX(ipl, 3);
77: }
78: else if (ena & TME_SUN2_ENA_SOFT_INT_2) {
79: ipl = TME_MAX(ipl, 2);
80: }
81: else if (ena & TME_SUN2_ENA_SOFT_INT_1) {
82: ipl = TME_MAX(ipl, 1);
83: }
84: }
85:
86: /* possibly update the CPU: */
87: if (ipl != sun2->tme_sun2_int_ipl_last) {
88: sun2->tme_sun2_int_ipl_last = ipl;
89: return ((*sun2->tme_sun2_m68k->tme_m68k_bus_interrupt)
90: (sun2->tme_sun2_m68k, ipl));
91: }
92: return (TME_OK);
93: }
94:
95: /* our mainbus signal handler: */
96: static int
97: _tme_sun2_bus_signal(struct tme_bus_connection *conn_bus_raiser, unsigned int signal)
98: {
99: struct tme_sun2 *sun2;
100: int signal_asserted;
101: unsigned int ipl, ipl_index;
102: tme_uint8_t ipl_mask;
103:
104: /* recover our sun2: */
105: sun2 = (struct tme_sun2 *) conn_bus_raiser->tme_bus_connection.tme_connection_element->tme_element_private;
106:
1.1.1.3 root 107: /* see whether the signal is asserted or negated: */
1.1 root 108: signal_asserted = TRUE;
109: switch (signal & TME_BUS_SIGNAL_LEVEL_MASK) {
110: case TME_BUS_SIGNAL_LEVEL_NEGATED:
111: signal_asserted = FALSE;
1.1.1.3 root 112: case TME_BUS_SIGNAL_LEVEL_ASSERTED:
1.1 root 113: break;
1.1.1.3 root 114: default:
115: abort();
1.1 root 116: }
1.1.1.3 root 117: signal = TME_BUS_SIGNAL_WHICH(signal);
1.1 root 118:
119: /* dispatch on the signal: */
120:
121: /* halt: */
122: if (signal == TME_BUS_SIGNAL_HALT) {
123: abort();
124: }
125:
126: /* reset: */
127: else if (signal == TME_BUS_SIGNAL_RESET) {
1.1.1.2 root 128: /* XXX reset is just ignored for now: */
1.1 root 129: }
130:
131: /* an interrupt signal: */
132: else if (TME_BUS_SIGNAL_IS_INT(signal)) {
1.1.1.3 root 133: ipl = TME_BUS_SIGNAL_INDEX_INT(signal);
1.1 root 134: if (ipl >= TME_M68K_IPL_MIN
135: && ipl <= TME_M68K_IPL_MAX) {
136:
137: /* update this ipl in the byte array: */
138: ipl_index = ipl >> 3;
139: ipl_mask = TME_BIT(ipl & 7);
140: sun2->tme_sun2_int_signals[ipl_index]
141: = ((sun2->tme_sun2_int_signals[ipl_index]
142: & ~ipl_mask)
143: | (signal_asserted
144: ? ipl_mask
145: : 0));
146:
147: /* possibly update the ipl being driven to the CPU: */
148: return (_tme_sun2_ipl_check(sun2));
149: }
150: }
151:
152: /* an unknown signal: */
153: else {
154: abort();
155: }
156:
157: return (TME_OK);
158: }
159:
160: /* this handles a CPU interrupt acknowledge: */
161: static int
162: _tme_sun2_bus_intack(struct tme_bus_connection *conn_m68k, unsigned int ipl, int *vector)
163: {
164: struct tme_sun2 *sun2;
165: tme_uint16_t ena;
166: int signal;
167: int rc;
168:
169: /* recover our sun2: */
170: sun2 = (struct tme_sun2 *) conn_m68k->tme_bus_connection.tme_connection_element->tme_element_private;
171:
172: /* acknowledge any soft interrupt: */
173: ena = sun2->tme_sun2_enable;
174: if ((ipl == 3
175: && (ena & TME_SUN2_ENA_SOFT_INT_3))
176: || (ipl == 2
177: && (ena & TME_SUN2_ENA_SOFT_INT_2))
178: || (ipl == 1
179: && (ena & TME_SUN2_ENA_SOFT_INT_1))) {
180: *vector = TME_BUS_INTERRUPT_VECTOR_UNDEF;
181: return (TME_OK);
182: }
183:
184: /* turn the ipl into a bus signal number: */
185: signal = TME_BUS_SIGNAL_INT(ipl);
186:
187: /* try the acknowledge on these buses, in order: */
188:
189: /* obio: */
190: rc = (*sun2->tme_sun2_obio->tme_bus_intack)
191: (sun2->tme_sun2_obio, signal, vector);
192: if (rc != ENOENT) {
193: return (rc);
194: }
1.1.1.2 root 195: /* obmem: */
196: rc = (*sun2->tme_sun2_obmem->tme_bus_intack)
197: (sun2->tme_sun2_obmem, signal, vector);
198: if (rc != ENOENT) {
199: return (rc);
200: }
1.1 root 201: if (sun2->tme_sun2_has_vme) {
202: /* VME: */
203: rc = (*sun2->tme_sun2_vmebus->tme_bus_intack)
204: (sun2->tme_sun2_vmebus, signal, vector);
205: if (rc != ENOENT) {
206: return (rc);
207: }
208: }
209: else {
210: /* mbio: */
211: rc = (*sun2->tme_sun2_mbio->tme_bus_intack)
212: (sun2->tme_sun2_mbio, signal, vector);
213: if (rc != ENOENT) {
214: return (rc);
215: }
216: /* mbmem: */
217: rc = (*sun2->tme_sun2_mbmem->tme_bus_intack)
218: (sun2->tme_sun2_mbmem, signal, vector);
219: if (rc != ENOENT) {
220: return (rc);
221: }
222: }
223:
224: /* done: */
225: return (rc);
226: }
227:
228: /* our command function: */
229: static int
230: _tme_sun2_command(struct tme_element *element, const char * const * args, char **_output)
231: {
232: struct tme_sun2 *sun2;
233: int do_reset;
234:
235: /* recover our sun2: */
236: sun2 = (struct tme_sun2 *) element->tme_element_private;
237:
238: /* assume no reset: */
239: do_reset = FALSE;
240:
241: /* the "power" command: */
242: if (TME_ARG_IS(args[1], "power")) {
243:
244: if (TME_ARG_IS(args[2], "up")
245: && args[3] == NULL) {
246: do_reset = TRUE;
247: }
248:
249: else if (TME_ARG_IS(args[2], "down")
250: && args[3] == NULL) {
251: /* nothing */
252: }
253:
254: /* return an error: */
255: else {
256: tme_output_append_error(_output,
257: "%s %s power [ up | down ]",
258: _("usage:"),
259: args[0]);
260: return (EINVAL);
261: }
262: }
263:
264: /* any other command: */
265: else {
266: if (args[1] != NULL) {
267: tme_output_append_error(_output,
268: "%s '%s', ",
269: _("unknown command"),
270: args[1]);
271: }
272: tme_output_append_error(_output,
273: _("available %s commands: %s"),
274: args[0],
275: "power");
276: return (EINVAL);
277: }
278:
279: if (do_reset) {
280:
281: /* reset the CPU: */
282: (*sun2->tme_sun2_m68k->tme_m68k_bus_connection.tme_bus_signal)
283: (&sun2->tme_sun2_m68k->tme_m68k_bus_connection,
284: TME_BUS_SIGNAL_RESET
285: | TME_BUS_SIGNAL_LEVEL_NEGATED
286: | TME_BUS_SIGNAL_EDGE);
287:
288: /* reset all busses: */
289: (*sun2->tme_sun2_obio->tme_bus_signal)
290: (sun2->tme_sun2_obio,
291: TME_BUS_SIGNAL_RESET
292: | TME_BUS_SIGNAL_LEVEL_NEGATED
293: | TME_BUS_SIGNAL_EDGE);
294: (*sun2->tme_sun2_obmem->tme_bus_signal)
295: (sun2->tme_sun2_obmem,
296: TME_BUS_SIGNAL_RESET
297: | TME_BUS_SIGNAL_LEVEL_NEGATED
298: | TME_BUS_SIGNAL_EDGE);
299: if (sun2->tme_sun2_has_vme) {
300: (*sun2->tme_sun2_vmebus->tme_bus_signal)
301: (sun2->tme_sun2_obmem,
302: TME_BUS_SIGNAL_RESET
303: | TME_BUS_SIGNAL_LEVEL_NEGATED
304: | TME_BUS_SIGNAL_EDGE);
305: }
306: else {
307: (*sun2->tme_sun2_mbio->tme_bus_signal)
308: (sun2->tme_sun2_mbio,
309: TME_BUS_SIGNAL_RESET
310: | TME_BUS_SIGNAL_LEVEL_NEGATED
311: | TME_BUS_SIGNAL_EDGE);
312: (*sun2->tme_sun2_mbmem->tme_bus_signal)
313: (sun2->tme_sun2_mbmem,
314: TME_BUS_SIGNAL_RESET
315: | TME_BUS_SIGNAL_LEVEL_NEGATED
316: | TME_BUS_SIGNAL_EDGE);
317: }
318: }
319:
320: return (TME_OK);
321: }
322:
323: /* the connection scorer: */
324: static int
325: _tme_sun2_connection_score(struct tme_connection *conn, unsigned int *_score)
326: {
327: struct tme_m68k_bus_connection *conn_m68k;
328: struct tme_sun2_bus_connection *conn_sun2;
329: struct tme_bus_connection *conn_bus;
330: struct tme_sun2 *sun2;
331: unsigned int score;
332:
333: /* recover our sun2: */
334: sun2 = (struct tme_sun2 *) conn->tme_connection_element->tme_element_private;
335:
336: /* assume that this connection is useless: */
337: score = 0;
338:
339: /* dispatch on the connection type: */
340: conn_m68k = (struct tme_m68k_bus_connection *) conn->tme_connection_other;
341: conn_sun2 = (struct tme_sun2_bus_connection *) conn;
342: conn_bus = (struct tme_bus_connection *) conn->tme_connection_other;
343: switch (conn->tme_connection_type) {
344:
345: /* this must be an m68k chip, and not another bus: */
346: case TME_CONNECTION_BUS_M68K:
1.1.1.5 root 347: if (conn_bus->tme_bus_tlb_set_add == NULL
1.1 root 348: && conn_m68k->tme_m68k_bus_tlb_fill == NULL) {
349: score = 10;
350: }
351: break;
352:
353: /* this must be a bus, and not a chip: */
354: case TME_CONNECTION_BUS_GENERIC:
1.1.1.5 root 355: if (conn_bus->tme_bus_tlb_set_add != NULL
1.1 root 356: && conn_bus->tme_bus_tlb_fill != NULL
357: && sun2->tme_sun2_buses[conn_sun2->tme_sun2_bus_connection_which] == NULL) {
358: score = 1;
359: }
360: break;
361:
362: default: abort();
363: }
364:
365: *_score = score;
366: return (TME_OK);
367: }
368:
369: /* this makes a new connection: */
370: static int
371: _tme_sun2_connection_make(struct tme_connection *conn, unsigned int state)
372: {
373: struct tme_sun2 *sun2;
374: struct tme_m68k_bus_connection *conn_m68k;
375: struct tme_sun2_bus_connection *conn_sun2;
376: struct tme_bus_connection *conn_bus;
377: struct tme_connection *conn_other;
378:
379: /* recover our sun2: */
380: sun2 = (struct tme_sun2 *) conn->tme_connection_element->tme_element_private;
381:
382: /* dispatch on the connection type: */
383: conn_other = conn->tme_connection_other;
384: conn_m68k = (struct tme_m68k_bus_connection *) conn_other;
385: conn_sun2 = (struct tme_sun2_bus_connection *) conn;
386: conn_bus = (struct tme_bus_connection *) conn_other;
387: switch (conn->tme_connection_type) {
388:
389: case TME_CONNECTION_BUS_M68K:
390: sun2->tme_sun2_m68k = conn_m68k;
391: break;
392:
393: case TME_CONNECTION_BUS_GENERIC:
394: sun2->tme_sun2_buses[conn_sun2->tme_sun2_bus_connection_which] = conn_bus;
395: break;
396:
397: default: assert(FALSE);
398: }
399: return (TME_OK);
400: }
401:
402: /* this breaks a connection: */
403: static int
404: _tme_sun2_connection_break(struct tme_connection *conn, unsigned int state)
405: {
406: abort();
407: }
408:
409: /* this makes new connection sides: */
410: static int
411: _tme_sun2_connections_new(struct tme_element *element, const char * const *args, struct tme_connection **_conns, char **_output)
412: {
413: struct tme_m68k_bus_connection *conn_m68k;
414: struct tme_sun2_bus_connection *conn_sun2;
415: struct tme_bus_connection *conn_bus;
416: struct tme_connection *conn;
417: struct tme_sun2 *sun2;
418: char *free_buses;
419: int which_bus;
420:
421: /* recover our sun2: */
422: sun2 = (struct tme_sun2 *) element->tme_element_private;
423:
424: /* if we have no arguments and don't have a CPU yet, we can take an m68k connection: */
425: if (args[1] == NULL
426: && sun2->tme_sun2_m68k == NULL) {
427:
428: /* create our side of an m68k bus connection: */
429: conn_m68k = tme_new0(struct tme_m68k_bus_connection, 1);
430: conn_bus = &conn_m68k->tme_m68k_bus_connection;
431: conn = &conn_bus->tme_bus_connection;
432:
433: /* fill in the generic connection: */
434: conn->tme_connection_next = *_conns;
435: conn->tme_connection_type = TME_CONNECTION_BUS_M68K;
436: conn->tme_connection_score = _tme_sun2_connection_score;
437: conn->tme_connection_make = _tme_sun2_connection_make;
438: conn->tme_connection_break = _tme_sun2_connection_break;
439:
440: /* fill in the generic bus connection: */
441: conn_bus->tme_bus_signal = _tme_sun2_bus_signal;
442: conn_bus->tme_bus_intack = _tme_sun2_bus_intack;
1.1.1.5 root 443: conn_bus->tme_bus_tlb_set_add = _tme_sun2_mmu_tlb_set_add;
1.1 root 444:
445: /* full in the m68k bus connection: */
446: conn_m68k->tme_m68k_bus_tlb_fill = _tme_sun2_m68k_tlb_fill;
447:
448: /* add in this connection side possibility: */
449: *_conns = conn;
450: }
451:
452: /* otherwise, we must have an argument and it must be for a bus that
453: we don't have yet: */
454: else {
455:
456: free_buses = NULL;
457: which_bus = -1;
458:
459: if (sun2->tme_sun2_obio == NULL) {
460: tme_output_append(&free_buses, " obio");
461: }
462: if (TME_ARG_IS(args[1], "obio")) {
463: which_bus = TME_SUN2_BUS_OBIO;
464: }
465:
1.1.1.3 root 466: if (sun2->tme_sun2_obmem == NULL) {
1.1 root 467: tme_output_append(&free_buses, " obmem");
468: }
469: if (TME_ARG_IS(args[1], "obmem")) {
470: which_bus = TME_SUN2_BUS_OBMEM;
471: }
472:
473: if (sun2->tme_sun2_has_vme) {
474:
475: if (sun2->tme_sun2_vmebus == NULL) {
476: tme_output_append(&free_buses, " vme");
477: }
478: if (TME_ARG_IS(args[1], "vme")) {
479: which_bus = TME_SUN2_BUS_VME;
480: }
481:
482: }
483:
484: else {
485:
486: if (sun2->tme_sun2_mbio == NULL) {
487: tme_output_append(&free_buses, " mbio");
488: }
489: if (TME_ARG_IS(args[1], "mbio")) {
490: which_bus = TME_SUN2_BUS_MBIO;
491: }
492:
1.1.1.3 root 493: if (sun2->tme_sun2_mbmem == NULL) {
1.1 root 494: tme_output_append(&free_buses, " mbmem");
495: }
496: if (TME_ARG_IS(args[1], "mbmem")) {
497: which_bus = TME_SUN2_BUS_MBMEM;
498: }
499: }
500:
501: if (args[1] == NULL
502: || which_bus < 0
503: || sun2->tme_sun2_buses[which_bus] != NULL) {
504: if (free_buses != NULL) {
505: tme_output_append_error(_output,
506: "%s%s",
507: _("remaining buses:"),
508: free_buses);
509: tme_free(free_buses);
510: }
511: else {
512: tme_output_append_error(_output, _("all buses present"));
513: }
514: return (EINVAL);
515: }
516: if (free_buses != NULL) {
517: tme_free(free_buses);
518: }
519:
520: if (args[2] != NULL) {
521: tme_output_append_error(_output,
522: "%s %s",
523: args[2],
524: _("unexpected"));
525: return (EINVAL);
526: }
527:
528: /* create our side of a generic bus connection: */
529: conn_sun2 = tme_new0(struct tme_sun2_bus_connection, 1);
530: conn_bus = &conn_sun2->tme_sun2_bus_connection;
531: conn = &conn_bus->tme_bus_connection;
532: conn->tme_connection_next = *_conns;
533:
534: /* fill in the generic connection: */
535: conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC;
536: conn->tme_connection_score = _tme_sun2_connection_score;
537: conn->tme_connection_make = _tme_sun2_connection_make;
538: conn->tme_connection_break = _tme_sun2_connection_break;
539:
540: /* fill in the generic bus connection: */
1.1.1.2 root 541: if (which_bus == TME_SUN2_BUS_MBMEM) {
542: conn_bus->tme_bus_subregions.tme_bus_subregion_address_last
543: = TME_SUN2_DVMA_SIZE_MBMEM;
544: }
545: else if (which_bus == TME_SUN2_BUS_VME) {
546: conn_bus->tme_bus_subregions.tme_bus_subregion_address_last
547: = TME_SUN2_DVMA_SIZE_VME;
548: }
1.1 root 549: conn_bus->tme_bus_signal = _tme_sun2_bus_signal;
550: conn_bus->tme_bus_intack = NULL;
1.1.1.5 root 551: conn_bus->tme_bus_tlb_set_add = _tme_sun2_mmu_tlb_set_add;
1.1 root 552: conn_bus->tme_bus_tlb_fill = _tme_sun2_bus_tlb_fill;
553:
554: /* fill in the sun2 connection: */
555: conn_sun2->tme_sun2_bus_connection_which = which_bus;
556:
557: /* add in this connection side possibility: */
558: *_conns = conn;
559: }
560:
561: /* done: */
562: return (TME_OK);
563: }
564:
565: /* this creates a new sun2 element: */
566: TME_ELEMENT_NEW_DECL(tme_machine_sun2) {
567: int usage;
568: struct tme_sun2 *sun2;
569: int sun2_has_vme;
570: const char *idprom_filename;
571: FILE *idprom_fp;
572: tme_uint8_t idprom[TME_SUN_IDPROM_SIZE];
573: int arg_i;
574:
575: arg_i = 1;
576: usage = FALSE;
577:
578: /* our first argument must be either "multibus" or "vme": */
579: sun2_has_vme = FALSE;
580: if (TME_ARG_IS(args[arg_i], "multibus")) {
581: arg_i++;
582: }
583: else if (TME_ARG_IS(args[arg_i], "vme")) {
584: arg_i++;
585: sun2_has_vme = TRUE;
586: }
587: else {
588: usage = TRUE;
589: }
590:
591: /* our second argument is the filename to load our IDPROM contents from: */
592: idprom_filename = args[arg_i++];
593: if (idprom_filename == NULL) {
594: usage = TRUE;
595: }
596:
597: /* we must have no more arguments: */
598: if (args[arg_i] != NULL) {
599: tme_output_append_error(_output,
600: "%s %s, ",
601: args[arg_i],
602: _("unexpected"));
603: usage = TRUE;
604: }
605:
606: /* if our usage was bad: */
607: if (usage) {
608: tme_output_append_error(_output,
609: "%s %s [ multibus | vme ] IDPROM%s",
610: _("usage:"),
611: args[0],
612: _("-FILENAME"));
613: return (EINVAL);
614: }
615:
616: /* try to read in the IDPROM: */
617: idprom_fp = fopen(idprom_filename, "r");
618: if (idprom_fp == NULL) {
1.1.1.6 ! root 619: tme_output_append_error(_output, "%s", idprom_filename);
1.1 root 620: return (errno);
621: }
622: if (fread(idprom, sizeof(tme_uint8_t), sizeof(idprom), idprom_fp) != sizeof(idprom)) {
1.1.1.6 ! root 623: tme_output_append_error(_output, "%s", idprom_filename);
1.1 root 624: fclose(idprom_fp);
625: return (ENOEXEC);
626: }
627: fclose(idprom_fp);
628:
629: /* allocate and initialize the new sun2: */
630: sun2 = tme_new0(struct tme_sun2, 1);
631: sun2->tme_sun2_element = element;
632:
633: /* set the VME flag: */
634: sun2->tme_sun2_has_vme = sun2_has_vme;
635:
636: /* set the IDPROM: */
637: memcpy(sun2->tme_sun2_idprom_contents, idprom, sizeof(idprom));
638:
639: /* the system and user context registers: */
640: sun2->tme_sun2_context_system = 0;
641: sun2->tme_sun2_context_user = 0;
642:
643: /* the diagnostics register: */
644: sun2->tme_sun2_diag = 0;
645:
646: /* the bus error register: */
647: sun2->tme_sun2_buserr = 0;
648:
649: /* the enable register: */
650: sun2->tme_sun2_enable = 0;
651:
652: /* the MMU: */
653: _tme_sun2_mmu_new(sun2);
654:
655: /* the busses: */
656: sun2->tme_sun2_obio = NULL;
657: sun2->tme_sun2_obmem = NULL;
658: sun2->tme_sun2_mbio = NULL;
659: sun2->tme_sun2_mbmem = NULL;
660: sun2->tme_sun2_vmebus = NULL;
661:
1.1.1.5 root 662: /* we don't have the CPU's bus context register yet: */
663: sun2->tme_sun2_m68k_bus_context = NULL;
1.1 root 664:
665: /* fill the element: */
666: element->tme_element_private = sun2;
667: element->tme_element_connections_new = _tme_sun2_connections_new;
668: element->tme_element_command = _tme_sun2_command;
669:
670: return (TME_OK);
671: }
672:
673: /* this creates a new Sun-2 am9513: */
674: TME_ELEMENT_SUB_NEW_DECL(tme_machine_sun2,clock) {
675: struct tme_am9513_socket socket;
676: char *sub_args[2];
677:
678: /* create the am9513 socket: */
679: socket.tme_am9513_socket_version = TME_AM9513_SOCKET_0;
680: socket.tme_am9513_socket_address_cmd = 2;
681: socket.tme_am9513_socket_address_data = 0;
682: socket.tme_am9513_socket_port_least_lane = 0; /* D7-D0 */
683: socket.tme_am9513_socket_basic_clock = (19660800 / 4);
684:
685: /* Timer 1 is connected to the bus as ipl 7 (inverted): */
686: socket.tme_am9513_socket_counter_signals[0] =
1.1.1.3 root 687: TME_BUS_SIGNAL_INT(7) | (TME_BUS_SIGNAL_LEVEL_ASSERTED ^ TME_BUS_SIGNAL_LEVEL_HIGH);
1.1 root 688:
689: /* Timer 2 is connected to the bus as ipl 5 (inverted): */
690: socket.tme_am9513_socket_counter_signals[1] =
1.1.1.3 root 691: TME_BUS_SIGNAL_INT(5) | (TME_BUS_SIGNAL_LEVEL_ASSERTED ^ TME_BUS_SIGNAL_LEVEL_HIGH);
1.1 root 692:
693: /* Timer 3 is connected to the bus as ???: */
694: socket.tme_am9513_socket_counter_signals[2] = TME_BUS_SIGNAL_ABORT;
695:
696: /* Timer 4 is connected to the bus as ???: */
697: socket.tme_am9513_socket_counter_signals[3] = TME_BUS_SIGNAL_ABORT;
698:
699: /* Timer 5 is connected to the bus as ???: */
700: socket.tme_am9513_socket_counter_signals[4] = TME_BUS_SIGNAL_ABORT;
701:
702: /* create the am9513: */
703: sub_args[0] = "tme/ic/am9513";
704: sub_args[1] = NULL;
705: return (tme_element_new(element, (const char * const *) sub_args, &socket, _output));
706: }
707:
708: /* this creates a new Sun-2 mm58167: */
709: TME_ELEMENT_SUB_NEW_DECL(tme_machine_sun2,tod) {
710: struct tme_mm58167_socket socket;
711: char *sub_args[2];
712:
713: /* create the mm58167 socket: */
714: socket.tme_mm58167_socket_version = TME_MM58167_SOCKET_0;
715: socket.tme_mm58167_socket_addr_shift = 1;
716: socket.tme_mm58167_socket_port_least_lane = 1; /* D15-D8 */
717:
718: /* create the mm58167: */
719: sub_args[0] = "tme/ic/mm58167";
720: sub_args[1] = NULL;
721: return (tme_element_new(element, (const char * const *) sub_args, &socket, _output));
722: }
723:
724: /* this creates a new Sun-2 z8530: */
725: TME_ELEMENT_SUB_NEW_DECL(tme_machine_sun2,zs) {
1.1.1.3 root 726: struct tme_z8530_socket socket = TME_SUN_Z8530_SOCKET_INIT;
1.1 root 727: char *sub_args[2];
728:
1.1.1.3 root 729: /* override the least lane in the z8530 socket: */
1.1 root 730: socket.tme_z8530_socket_port_least_lane = 1; /* D15-D8 */
731:
1.1.1.4 root 732: /* override the socket flags: */
733: socket.tme_z8530_socket_flags |= TME_Z8530_SOCKET_FLAG_IEI_TIED_LOW;
734:
1.1 root 735: /* create the z8530: */
736: sub_args[0] = "tme/ic/z8530";
737: sub_args[1] = NULL;
738: return (tme_element_new(element, (const char * const *) sub_args, &socket, _output));
739: }
1.1.1.3 root 740:
741: /* this creates a new Sun-2 bwtwo: */
742: TME_ELEMENT_SUB_NEW_DECL(tme_machine_sun2,bwtwo) {
743: return (tme_sun_bwtwo(element, args, _output));
744: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.