Annotation of tme/machine/sun2/sun2-mainbus.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.