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