|
|
1.1.1.3 ! root 1: /* $Id: sun2-mainbus.c,v 1.16 2005/02/17 13:32:05 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.3 ! root 37: _TME_RCSID("$Id: sun2-mainbus.c,v 1.16 2005/02/17 13:32:05 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 MMU: */ 282: _tme_sun2_mmu_reset(sun2); 283: 284: /* reset the CPU: */ 285: (*sun2->tme_sun2_m68k->tme_m68k_bus_connection.tme_bus_signal) 286: (&sun2->tme_sun2_m68k->tme_m68k_bus_connection, 287: TME_BUS_SIGNAL_RESET 288: | TME_BUS_SIGNAL_LEVEL_NEGATED 289: | TME_BUS_SIGNAL_EDGE); 290: 291: /* reset all busses: */ 292: (*sun2->tme_sun2_obio->tme_bus_signal) 293: (sun2->tme_sun2_obio, 294: TME_BUS_SIGNAL_RESET 295: | TME_BUS_SIGNAL_LEVEL_NEGATED 296: | TME_BUS_SIGNAL_EDGE); 297: (*sun2->tme_sun2_obmem->tme_bus_signal) 298: (sun2->tme_sun2_obmem, 299: TME_BUS_SIGNAL_RESET 300: | TME_BUS_SIGNAL_LEVEL_NEGATED 301: | TME_BUS_SIGNAL_EDGE); 302: if (sun2->tme_sun2_has_vme) { 303: (*sun2->tme_sun2_vmebus->tme_bus_signal) 304: (sun2->tme_sun2_obmem, 305: TME_BUS_SIGNAL_RESET 306: | TME_BUS_SIGNAL_LEVEL_NEGATED 307: | TME_BUS_SIGNAL_EDGE); 308: } 309: else { 310: (*sun2->tme_sun2_mbio->tme_bus_signal) 311: (sun2->tme_sun2_mbio, 312: TME_BUS_SIGNAL_RESET 313: | TME_BUS_SIGNAL_LEVEL_NEGATED 314: | TME_BUS_SIGNAL_EDGE); 315: (*sun2->tme_sun2_mbmem->tme_bus_signal) 316: (sun2->tme_sun2_mbmem, 317: TME_BUS_SIGNAL_RESET 318: | TME_BUS_SIGNAL_LEVEL_NEGATED 319: | TME_BUS_SIGNAL_EDGE); 320: } 321: } 322: 323: return (TME_OK); 324: } 325: 326: /* the connection scorer: */ 327: static int 328: _tme_sun2_connection_score(struct tme_connection *conn, unsigned int *_score) 329: { 330: struct tme_m68k_bus_connection *conn_m68k; 331: struct tme_sun2_bus_connection *conn_sun2; 332: struct tme_bus_connection *conn_bus; 333: struct tme_sun2 *sun2; 334: unsigned int score; 335: 336: /* recover our sun2: */ 337: sun2 = (struct tme_sun2 *) conn->tme_connection_element->tme_element_private; 338: 339: /* assume that this connection is useless: */ 340: score = 0; 341: 342: /* dispatch on the connection type: */ 343: conn_m68k = (struct tme_m68k_bus_connection *) conn->tme_connection_other; 344: conn_sun2 = (struct tme_sun2_bus_connection *) conn; 345: conn_bus = (struct tme_bus_connection *) conn->tme_connection_other; 346: switch (conn->tme_connection_type) { 347: 348: /* this must be an m68k chip, and not another bus: */ 349: case TME_CONNECTION_BUS_M68K: 350: if (conn_bus->tme_bus_tlb_set_allocate == NULL 351: && conn_m68k->tme_m68k_bus_tlb_fill == NULL) { 352: score = 10; 353: } 354: break; 355: 356: /* this must be a bus, and not a chip: */ 357: case TME_CONNECTION_BUS_GENERIC: 358: if (conn_bus->tme_bus_tlb_set_allocate != NULL 359: && conn_bus->tme_bus_tlb_fill != NULL 360: && sun2->tme_sun2_buses[conn_sun2->tme_sun2_bus_connection_which] == NULL) { 361: score = 1; 362: } 363: break; 364: 365: default: abort(); 366: } 367: 368: *_score = score; 369: return (TME_OK); 370: } 371: 372: /* this makes a new connection: */ 373: static int 374: _tme_sun2_connection_make(struct tme_connection *conn, unsigned int state) 375: { 376: struct tme_sun2 *sun2; 377: struct tme_m68k_bus_connection *conn_m68k; 378: struct tme_sun2_bus_connection *conn_sun2; 379: struct tme_bus_connection *conn_bus; 380: struct tme_connection *conn_other; 381: 382: /* recover our sun2: */ 383: sun2 = (struct tme_sun2 *) conn->tme_connection_element->tme_element_private; 384: 385: /* dispatch on the connection type: */ 386: conn_other = conn->tme_connection_other; 387: conn_m68k = (struct tme_m68k_bus_connection *) conn_other; 388: conn_sun2 = (struct tme_sun2_bus_connection *) conn; 389: conn_bus = (struct tme_bus_connection *) conn_other; 390: switch (conn->tme_connection_type) { 391: 392: case TME_CONNECTION_BUS_M68K: 393: sun2->tme_sun2_m68k = conn_m68k; 394: break; 395: 396: case TME_CONNECTION_BUS_GENERIC: 397: sun2->tme_sun2_buses[conn_sun2->tme_sun2_bus_connection_which] = conn_bus; 398: break; 399: 400: default: assert(FALSE); 401: } 402: return (TME_OK); 403: } 404: 405: /* this breaks a connection: */ 406: static int 407: _tme_sun2_connection_break(struct tme_connection *conn, unsigned int state) 408: { 409: abort(); 410: } 411: 412: /* this makes new connection sides: */ 413: static int 414: _tme_sun2_connections_new(struct tme_element *element, const char * const *args, struct tme_connection **_conns, char **_output) 415: { 416: struct tme_m68k_bus_connection *conn_m68k; 417: struct tme_sun2_bus_connection *conn_sun2; 418: struct tme_bus_connection *conn_bus; 419: struct tme_connection *conn; 420: struct tme_sun2 *sun2; 421: char *free_buses; 422: int which_bus; 423: 424: /* recover our sun2: */ 425: sun2 = (struct tme_sun2 *) element->tme_element_private; 426: 427: /* if we have no arguments and don't have a CPU yet, we can take an m68k connection: */ 428: if (args[1] == NULL 429: && sun2->tme_sun2_m68k == NULL) { 430: 431: /* create our side of an m68k bus connection: */ 432: conn_m68k = tme_new0(struct tme_m68k_bus_connection, 1); 433: conn_bus = &conn_m68k->tme_m68k_bus_connection; 434: conn = &conn_bus->tme_bus_connection; 435: 436: /* fill in the generic connection: */ 437: conn->tme_connection_next = *_conns; 438: conn->tme_connection_type = TME_CONNECTION_BUS_M68K; 439: conn->tme_connection_score = _tme_sun2_connection_score; 440: conn->tme_connection_make = _tme_sun2_connection_make; 441: conn->tme_connection_break = _tme_sun2_connection_break; 442: 443: /* fill in the generic bus connection: */ 444: conn_bus->tme_bus_signal = _tme_sun2_bus_signal; 445: conn_bus->tme_bus_intack = _tme_sun2_bus_intack; 446: conn_bus->tme_bus_tlb_set_allocate = _tme_sun2_mmu_tlb_set_allocate; 447: 448: /* full in the m68k bus connection: */ 449: conn_m68k->tme_m68k_bus_tlb_fill = _tme_sun2_m68k_tlb_fill; 450: 451: /* add in this connection side possibility: */ 452: *_conns = conn; 453: } 454: 455: /* otherwise, we must have an argument and it must be for a bus that 456: we don't have yet: */ 457: else { 458: 459: free_buses = NULL; 460: which_bus = -1; 461: 462: if (sun2->tme_sun2_obio == NULL) { 463: tme_output_append(&free_buses, " obio"); 464: } 465: if (TME_ARG_IS(args[1], "obio")) { 466: which_bus = TME_SUN2_BUS_OBIO; 467: } 468: 1.1.1.3 ! root 469: if (sun2->tme_sun2_obmem == NULL) { 1.1 root 470: tme_output_append(&free_buses, " obmem"); 471: } 472: if (TME_ARG_IS(args[1], "obmem")) { 473: which_bus = TME_SUN2_BUS_OBMEM; 474: } 475: 476: if (sun2->tme_sun2_has_vme) { 477: 478: if (sun2->tme_sun2_vmebus == NULL) { 479: tme_output_append(&free_buses, " vme"); 480: } 481: if (TME_ARG_IS(args[1], "vme")) { 482: which_bus = TME_SUN2_BUS_VME; 483: } 484: 485: } 486: 487: else { 488: 489: if (sun2->tme_sun2_mbio == NULL) { 490: tme_output_append(&free_buses, " mbio"); 491: } 492: if (TME_ARG_IS(args[1], "mbio")) { 493: which_bus = TME_SUN2_BUS_MBIO; 494: } 495: 1.1.1.3 ! root 496: if (sun2->tme_sun2_mbmem == NULL) { 1.1 root 497: tme_output_append(&free_buses, " mbmem"); 498: } 499: if (TME_ARG_IS(args[1], "mbmem")) { 500: which_bus = TME_SUN2_BUS_MBMEM; 501: } 502: } 503: 504: if (args[1] == NULL 505: || which_bus < 0 506: || sun2->tme_sun2_buses[which_bus] != NULL) { 507: if (free_buses != NULL) { 508: tme_output_append_error(_output, 509: "%s%s", 510: _("remaining buses:"), 511: free_buses); 512: tme_free(free_buses); 513: } 514: else { 515: tme_output_append_error(_output, _("all buses present")); 516: } 517: return (EINVAL); 518: } 519: if (free_buses != NULL) { 520: tme_free(free_buses); 521: } 522: 523: if (args[2] != NULL) { 524: tme_output_append_error(_output, 525: "%s %s", 526: args[2], 527: _("unexpected")); 528: return (EINVAL); 529: } 530: 531: /* create our side of a generic bus connection: */ 532: conn_sun2 = tme_new0(struct tme_sun2_bus_connection, 1); 533: conn_bus = &conn_sun2->tme_sun2_bus_connection; 534: conn = &conn_bus->tme_bus_connection; 535: conn->tme_connection_next = *_conns; 536: 537: /* fill in the generic connection: */ 538: conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC; 539: conn->tme_connection_score = _tme_sun2_connection_score; 540: conn->tme_connection_make = _tme_sun2_connection_make; 541: conn->tme_connection_break = _tme_sun2_connection_break; 542: 543: /* fill in the generic bus connection: */ 1.1.1.2 root 544: if (which_bus == TME_SUN2_BUS_MBMEM) { 545: conn_bus->tme_bus_subregions.tme_bus_subregion_address_last 546: = TME_SUN2_DVMA_SIZE_MBMEM; 547: } 548: else if (which_bus == TME_SUN2_BUS_VME) { 549: conn_bus->tme_bus_subregions.tme_bus_subregion_address_last 550: = TME_SUN2_DVMA_SIZE_VME; 551: } 1.1 root 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] = 1.1.1.3 ! root 690: TME_BUS_SIGNAL_INT(7) | (TME_BUS_SIGNAL_LEVEL_ASSERTED ^ TME_BUS_SIGNAL_LEVEL_HIGH); 1.1 root 691: 692: /* Timer 2 is connected to the bus as ipl 5 (inverted): */ 693: socket.tme_am9513_socket_counter_signals[1] = 1.1.1.3 ! root 694: TME_BUS_SIGNAL_INT(5) | (TME_BUS_SIGNAL_LEVEL_ASSERTED ^ TME_BUS_SIGNAL_LEVEL_HIGH); 1.1 root 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) { 1.1.1.3 ! root 729: struct tme_z8530_socket socket = TME_SUN_Z8530_SOCKET_INIT; 1.1 root 730: char *sub_args[2]; 731: 1.1.1.3 ! root 732: /* override the least lane in the z8530 socket: */ 1.1 root 733: socket.tme_z8530_socket_port_least_lane = 1; /* D15-D8 */ 734: 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.