|
|
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) { 619: tme_output_append_error(_output, idprom_filename); 620: return (errno); 621: } 622: if (fread(idprom, sizeof(tme_uint8_t), sizeof(idprom), idprom_fp) != sizeof(idprom)) { 623: tme_output_append_error(_output, idprom_filename); 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.