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