Annotation of tme/machine/sun3/sun3-control.c, revision 1.1.1.1

1.1       root        1: /* $Id: sun3-control.c,v 1.2 2005/02/18 03:58:07 fredette Exp $ */
                      2: 
                      3: /* machine/sun3/sun3-control.c - implementation of Sun 3 emulation control space: */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2003, 2004 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #include <tme/common.h>
                     37: _TME_RCSID("$Id: sun3-control.c,v 1.2 2005/02/18 03:58:07 fredette Exp $");
                     38: 
                     39: /* includes: */
                     40: #include "sun3-impl.h"
                     41: 
                     42: /* the bus cycle handler for function code three space: */
                     43: int
                     44: _tme_sun3_control_cycle_handler(void *_sun3, struct tme_bus_cycle *cycle_init)
                     45: {
                     46:   struct tme_sun3 *sun3;
                     47:   struct tme_bus_cycle cycle_resp;
                     48:   tme_uint32_t address, reg;
                     49:   tme_uint8_t port_data[sizeof(tme_uint32_t)];
                     50:   tme_uint8_t *port_data8;
                     51:   tme_uint32_t *port_data32;
                     52:   tme_uint32_t value32;
                     53:   tme_uint8_t enable_old, enable_new;
                     54:   int rc;
                     55: 
                     56:   /* recover our sun3: */
                     57:   sun3 = (struct tme_sun3 *) _sun3;
                     58: 
                     59:   /* get the address, convert it into a register number, then mask
                     60:      the address: */
                     61:   address = cycle_init->tme_bus_cycle_address;
                     62:   reg = TME_SUN3_CONTROL_REG(address);
                     63:   if (reg != TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_IDPROM)) {
                     64:     address &= TME_SUN3_CONTROL_MASK_ADDRESS;
                     65:   }
                     66: 
                     67:   /* dispatch on the register, to get bytes for our port: */
                     68:   port_data8 = &port_data[0];
                     69:   port_data32 = (tme_uint32_t *) &port_data[0];
                     70:   switch (reg) {
                     71:     
                     72:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_IDPROM):
                     73:     memcpy(port_data, 
                     74:           &sun3->tme_sun3_idprom_contents[(address & (TME_SUN_IDPROM_SIZE - 1))],
                     75:           TME_MIN(sizeof(port_data),
                     76:                   TME_SUN_IDPROM_SIZE - (address & (TME_SUN_IDPROM_SIZE - 1))));
                     77:     break;
                     78: 
                     79:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_PGMAP):
                     80:     rc = _tme_sun3_mmu_pte_get(sun3, address, &value32);
                     81:     assert(rc == TME_OK);
                     82:     *port_data32 = tme_htobe_u32(value32);
                     83:     break;
                     84:       
                     85:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_SEGMAP):
                     86:     *port_data8 = tme_sun_mmu_segmap_get(sun3->tme_sun3_mmu, sun3->tme_sun3_context, address);
                     87:     break;
                     88: 
                     89:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_CONTEXT):
                     90:     *port_data8 = sun3->tme_sun3_context;
                     91:     break;
                     92: 
                     93:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_ENABLE):
                     94:     *port_data8 = sun3->tme_sun3_enable;
                     95:     break;
                     96: 
                     97:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_UDVMA):
                     98:     *port_data8 = sun3->tme_sun3_udvma;
                     99:     break;
                    100: 
                    101:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_BUSERR):
                    102:     *port_data8 = sun3->tme_sun3_buserr;
                    103:     break;
                    104: 
                    105:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_DIAG):
                    106:     *port_data8 = sun3->tme_sun3_diag;
                    107:     break;
                    108: 
                    109:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_TAGS):
                    110:     abort();
                    111:     break;
                    112: 
                    113:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_DATA):
                    114:     abort();
                    115:     break;
                    116: 
                    117:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_FLUSH):
                    118:     abort();
                    119:     break;
                    120: 
                    121:   case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_COPY):
                    122:     abort();
                    123:     break;
                    124: 
                    125:   default:
                    126:     abort();
                    127:   }
                    128:      
                    129:   /* run the bus cycle: */
                    130:   cycle_resp.tme_bus_cycle_buffer = &port_data[0];
                    131:   cycle_resp.tme_bus_cycle_buffer_increment = 1;
                    132:   cycle_resp.tme_bus_cycle_lane_routing = cycle_init->tme_bus_cycle_lane_routing;
                    133:   cycle_resp.tme_bus_cycle_address = 0;
                    134:   cycle_resp.tme_bus_cycle_type = (cycle_init->tme_bus_cycle_type
                    135:                                   ^ (TME_BUS_CYCLE_WRITE
                    136:                                      | TME_BUS_CYCLE_READ));
                    137:   cycle_resp.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
                    138:   tme_bus_cycle_xfer(cycle_init, &cycle_resp);
                    139: 
                    140:   /* whenever the bus error register is read or written, it is
                    141:      cleared: */
                    142:   if (reg == TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_BUSERR)) {
                    143:     sun3->tme_sun3_buserr = 0;
                    144:   }
                    145: 
                    146:   /* these registers only need action taken when they're written: */
                    147:   if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    148: 
                    149:     /* dispatch on the register: */
                    150:     switch (reg) {
                    151: 
                    152:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_PGMAP):
                    153:       value32 = tme_betoh_u32(*port_data32);
                    154:       rc = _tme_sun3_mmu_pte_set(sun3, address, value32);
                    155:       assert (rc == TME_OK);
                    156:       break;
                    157:       
                    158:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_SEGMAP):
                    159:       tme_sun_mmu_segmap_set(sun3->tme_sun3_mmu, sun3->tme_sun3_context, address, *port_data8 % TME_SUN3_PMEGS);
                    160:       break;
                    161:       
                    162:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_CONTEXT):
                    163:       sun3->tme_sun3_context = *port_data8;
                    164:       _tme_sun3_mmu_context_set(sun3);
                    165:       break;
                    166: 
                    167:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_ENABLE):
                    168:       enable_old = sun3->tme_sun3_enable;
                    169:       enable_new = (enable_old & TME_SUN3_ENA_DIAG) | (*port_data8 & ~TME_SUN3_ENA_DIAG);
                    170:       sun3->tme_sun3_enable = enable_new;
                    171: 
                    172:       /* if we're changing to or from boot state, make a pseudo-context change: */
                    173:       if ((enable_old ^ enable_new) & TME_SUN3_ENA_NOTBOOT) {
                    174:        _tme_sun3_mmu_context_set(sun3);
                    175:       }
                    176: 
                    177:       /* if we're changing the m6888x enable bit, call out the change: */
                    178:       if ((enable_old ^ enable_new) & TME_SUN3_ENA_FPP) {
                    179:        rc = ((*sun3->tme_sun3_m68k->tme_m68k_bus_m6888x_enable)
                    180:              (sun3->tme_sun3_m68k, (enable_new & TME_SUN3_ENA_FPP)));
                    181:        assert (rc == TME_OK);
                    182:       }
                    183: 
                    184:       /* if we're enabling or disabling system DVMA, call out the change: */
                    185:       if ((enable_old ^ enable_new) & TME_SUN3_ENA_SDVMA) {
                    186:        _tme_sun3_mmu_sdvma_change(sun3);
                    187:       }
                    188: 
                    189:       /* certain things can't be enabled: */
                    190:       if (enable_new
                    191:          & (TME_SUN3_ENA_COPY
                    192:             | TME_SUN3_ENA_CACHE)) {
                    193:        abort();
                    194:       }
                    195:       break;
                    196: 
                    197:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_UDVMA):
                    198:       if (sun3->tme_sun3_enable & TME_SUN3_ENA_NOTBOOT) {
                    199:        abort();
                    200:       }
                    201:       sun3->tme_sun3_udvma = *port_data8;
                    202:       break;
                    203: 
                    204:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_DIAG):
                    205:       sun3->tme_sun3_diag = *port_data8;
                    206:       /* TBD */
                    207:       break;
                    208: 
                    209:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_TAGS):
                    210:       abort();
                    211:       break;
                    212: 
                    213:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_DATA):
                    214:       abort();
                    215:       break;
                    216: 
                    217:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_VAC_FLUSH):
                    218:       abort();
                    219:       break;
                    220: 
                    221:     case TME_SUN3_CONTROL_REG(TME_SUN3_CONTROL_COPY):
                    222:       abort();
                    223:       break;
                    224:     }
                    225:   }
                    226: 
                    227:   return (TME_OK);
                    228: }
                    229: 
                    230: /* the bus cycle handler for the interrupt register: */
                    231: int
                    232: _tme_sun3_intreg_cycle_handler(void *_sun3, struct tme_bus_cycle *cycle_init)
                    233: {
                    234:   struct tme_sun3 *sun3;
                    235:   int rc;
                    236: 
                    237:   /* recover our sun3: */
                    238:   sun3 = (struct tme_sun3 *) _sun3;
                    239: 
                    240:   /* do the transfer: */
                    241:   tme_bus_cycle_xfer_memory(cycle_init, 
                    242:                            &sun3->tme_sun3_ints,
                    243:                            sizeof(sun3->tme_sun3_ints) - 1);
                    244: 
                    245:   /* if the interrupt register has been written: */
                    246:   if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    247:     rc = _tme_sun3_ipl_check(sun3);
                    248:     assert(rc == TME_OK);
                    249:   }
                    250: 
                    251:   return (TME_OK);
                    252: }
                    253: 
                    254: /* this calls out a memory error interrupt change: */
                    255: static void
                    256: _tme_sun3_memerr_callout(struct tme_sun3 *sun3)
                    257: {
                    258:   unsigned int int_asserted;
                    259:   struct tme_bus_connection *conn_bus;
                    260:   int rc;
                    261: 
                    262:   /* see if the memory error interrupt should be asserted: */
                    263:   int_asserted
                    264:     = ((sun3->tme_sun3_memerr_csr
                    265:        & (TME_SUN3_MEMERR_X_INT_ACTIVE
                    266:           | TME_SUN3_MEMERR_X_ENABLE_INT))
                    267:        == (TME_SUN3_MEMERR_X_INT_ACTIVE
                    268:           | TME_SUN3_MEMERR_X_ENABLE_INT));
                    269: 
                    270:   /* if we need to call out an interrupt change: */
                    271:   if (!int_asserted != !sun3->tme_sun3_memerr_int_asserted) {
                    272: 
                    273:     /* get our bus connection: */
                    274:     conn_bus = sun3->tme_sun3_memerr_bus;
                    275:        
                    276:     /* call out the bus interrupt signal edge: */
                    277:     rc = (*conn_bus->tme_bus_signal)
                    278:       (conn_bus,
                    279:        TME_BUS_SIGNAL_INT_UNSPEC
                    280:        | (int_asserted
                    281:          ? TME_BUS_SIGNAL_LEVEL_ASSERTED
                    282:          : TME_BUS_SIGNAL_LEVEL_NEGATED));
                    283: 
                    284:     /* if this callout was successful, note the new state of the
                    285:        interrupt signal: */
                    286:     if (rc == TME_OK) {
                    287:       sun3->tme_sun3_memerr_int_asserted = int_asserted;
                    288:     }
                    289: 
                    290:     /* otherwise, abort: */
                    291:     else {
                    292:       abort();
                    293:     }
                    294:   }
                    295: }
                    296: 
                    297: /* the bus cycle handler for the memory error register: */
                    298: int
                    299: _tme_sun3_memerr_cycle_handler(void *_sun3, struct tme_bus_cycle *cycle_init)
                    300: {
                    301:   struct tme_sun3 *sun3;
                    302:   tme_uint8_t memerr_reg[TME_SUN3_MEMERR_SIZ_REG];
                    303:   int write_csr, unlatch;
                    304:   tme_uint8_t csr_old, csr_new;
                    305: 
                    306:   /* the read-only bits: */
                    307: #define TME_SUN3_MEMERR_RO (TME_SUN3_MEMERR_X_INT_ACTIVE \
                    308:                            | TME_SUN3_MEMERR_PAR_ERR_BL3 \
                    309:                            | TME_SUN3_MEMERR_PAR_ERR_BL2 \
                    310:                            | TME_SUN3_MEMERR_PAR_ERR_BL1 \
                    311:                            | TME_SUN3_MEMERR_PAR_ERR_BL0)
                    312: 
                    313:   /* recover our sun3: */
                    314:   sun3 = (struct tme_sun3 *) _sun3;
                    315: 
                    316:   /* fill the memory error register: */
                    317:   memerr_reg[TME_SUN3_MEMERR_REG_CSR] = sun3->tme_sun3_memerr_csr;
                    318:   *((tme_uint32_t *) &memerr_reg[TME_SUN3_MEMERR_SIZ_VADDR]) = tme_htobe_u32(sun3->tme_sun3_memerr_vaddr);
                    319: 
                    320:   /* assume this cycle won't write the CSR or unlatch the register: */
                    321:   write_csr = FALSE;
                    322:   unlatch = FALSE;
                    323: 
                    324:   /* if this is a write: */
                    325:   if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    326: 
                    327:     /* see if this writes the CSR: */
                    328:     write_csr = TME_RANGES_OVERLAP(cycle_init->tme_bus_cycle_address,
                    329:                                   (cycle_init->tme_bus_cycle_address
                    330:                                    + cycle_init->tme_bus_cycle_size
                    331:                                    - 1),
                    332:                                   TME_SUN3_MEMERR_REG_CSR,
                    333:                                   (TME_SUN3_MEMERR_REG_CSR
                    334:                                    + TME_SUN3_MEMERR_SIZ_CSR
                    335:                                    - 1));
                    336: 
                    337:     /* see if this write unlatches the register: */
                    338:     unlatch = TME_RANGES_OVERLAP(cycle_init->tme_bus_cycle_address,
                    339:                                 (cycle_init->tme_bus_cycle_address
                    340:                                  + cycle_init->tme_bus_cycle_size
                    341:                                  - 1),
                    342:                                 TME_SUN3_MEMERR_REG_VADDR,
                    343:                                 TME_SUN3_MEMERR_REG_VADDR);
                    344:   }
                    345: 
                    346:   /* do the transfer: */
                    347:   tme_bus_cycle_xfer_memory(cycle_init, 
                    348:                            memerr_reg,
                    349:                            sizeof(memerr_reg) - 1);
                    350: 
                    351:   /* if this is a write: */
                    352:   if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_WRITE) {
                    353: 
                    354:     /* get the old CSR value, and assume that the new CSR value is the
                    355:        same: */
                    356:     csr_old = sun3->tme_sun3_memerr_csr;
                    357:     csr_new = csr_old;
                    358: 
                    359:     /* if the CSR register has been written: */
                    360:     if (write_csr) {
                    361: 
                    362:       /* get the new CSR value, but preserve the read-only bits: */
                    363:       csr_new = ((csr_new & TME_SUN3_MEMERR_RO)
                    364:                 | (memerr_reg[TME_SUN3_MEMERR_REG_CSR] & ~TME_SUN3_MEMERR_RO));
                    365:     }
                    366: 
                    367:     /* if the memory error register has been unlatched: */
                    368:     if (unlatch) {
                    369: 
                    370:       /* clear the memory error: */
                    371:       csr_new &= ~TME_SUN3_MEMERR_RO;
                    372:       sun3->tme_sun3_memerr_vaddr = 0;
                    373:     }
                    374: 
                    375:     /* if the CSR register has changed: */
                    376:     if (csr_new != csr_old) {
                    377: 
                    378:       /* set the new CSR value and call out an interrupt change: */
                    379:       sun3->tme_sun3_memerr_csr = csr_new;
                    380:       _tme_sun3_memerr_callout(sun3);
                    381: 
                    382:       /* if the memory error register is being tested: */
                    383:       if (csr_new & TME_SUN3_MEMERR_PAR_TEST) {
                    384: 
                    385:        /* if the test is just beginning, invalidate all TLB entries: */
                    386:        if (!(csr_old & TME_SUN3_MEMERR_PAR_TEST)) {
                    387:          tme_sun_mmu_tlbs_invalidate(sun3->tme_sun3_mmu);
                    388:        }
                    389:       }
                    390:     }
                    391:   }
                    392:     
                    393:   return (TME_OK);
                    394: }
                    395: 
                    396: /* the bus cycle handler for the memory error register test: */
                    397: int
                    398: _tme_sun3_memerr_test_cycle_handler(void *_sun3, struct tme_bus_cycle *cycle_init)
                    399: {
                    400:   struct tme_sun3 *sun3;
                    401:   struct tme_bus_tlb *tlb;
                    402:   tme_uint32_t vaddr, cycle_align;
                    403:   tme_uint8_t csr;
                    404:   int rc;
                    405: 
                    406:   /* recover our sun3: */
                    407:   sun3 = (struct tme_sun3 *) _sun3;
                    408: 
                    409:   /* get the memory error test TLB entry: */
                    410:   tlb = sun3->tme_sun3_memerr_tlb;
                    411:   if (tlb == NULL) {
                    412:     abort();
                    413:   }
                    414: 
                    415:   /* recover the virtual address from the TLB entry.  this TLB entry
                    416:      should be for normal memory, which means it should have no shift: */
                    417:   if (tlb->tme_bus_tlb_addr_shift != 0) {
                    418:     abort();
                    419:   }
                    420:   vaddr = (cycle_init->tme_bus_cycle_address
                    421:           - tlb->tme_bus_tlb_addr_offset);
                    422: 
                    423:   /* calculate the number of bytes after the last byte of the cycle
                    424:      until the next 32-bit boundary.  this bus cycle must not cross a
                    425:      32-bit boundary: */
                    426:   cycle_align = ((vaddr & (sizeof(tme_uint32_t) - 1))
                    427:                 + cycle_init->tme_bus_cycle_size);
                    428:   if (cycle_align > sizeof(tme_uint32_t)) {
                    429:     abort();
                    430:   }
                    431:   cycle_align = sizeof(tme_uint32_t) - cycle_align;
                    432:   
                    433:   /* make the pending csr value.  this calculates a mask of
                    434:      TME_SUN3_MEMERR_PAR_ERR_BLx bits corresponding to the byte lanes
                    435:      being read or written in this cycle: */
                    436:   csr = (1 << cycle_init->tme_bus_cycle_size) - 1;
                    437:   csr <<= cycle_align;
                    438: 
                    439:   /* if this cycle is a read: */
                    440:   if (cycle_init->tme_bus_cycle_type == TME_BUS_CYCLE_READ) {
                    441: 
                    442:     /* parity checking must be enabled and there must be no memory
                    443:        error pending: */
                    444:     if ((sun3->tme_sun3_memerr_csr
                    445:         & (TME_SUN3_MEMERR_X_INT_ACTIVE
                    446:            | TME_SUN3_MEMERR_PAR_ENABLE))
                    447:        != TME_SUN3_MEMERR_PAR_ENABLE) {
                    448:       abort();
                    449:     }
                    450: 
                    451:     /* this must be a read of the written address: */
                    452:     if ((sun3->tme_sun3_memerr_pending_csr & csr) == 0
                    453:        || ((sun3->tme_sun3_memerr_pending_vaddr ^ vaddr) & -sizeof(tme_uint32_t)) != 0) {
                    454:       abort();
                    455:     }
                    456: 
                    457:     /* do the read: */
                    458:     rc = ((*sun3->tme_sun3_memerr_cycle)
                    459:          (sun3->tme_sun3_memerr_cycle_private, 
                    460:           cycle_init));
                    461: 
                    462:     /* set the memory error control register: */
                    463:     sun3->tme_sun3_memerr_csr
                    464:       = ((sun3->tme_sun3_memerr_csr
                    465:          & ~TME_SUN3_MEMERR_RO)
                    466:         | TME_SUN3_MEMERR_X_INT_ACTIVE
                    467:         | (sun3->tme_sun3_memerr_pending_csr & csr));
                    468: 
                    469:     /* set the memory error address register: */
                    470:     sun3->tme_sun3_memerr_vaddr
                    471:       = ((sun3->tme_sun3_context << 28)
                    472:         | vaddr);
                    473:     
                    474:     /* call out an interrupt: */
                    475:     _tme_sun3_memerr_callout(sun3);
                    476: 
                    477:     /* invalidate the memory test TLB entry: */
                    478:     tme_bus_tlb_invalidate(tlb);
                    479:     sun3->tme_sun3_memerr_tlb = NULL;
                    480: 
                    481:     /* tell the CPU that a synchronous event of some kind has happened
                    482:        on the bus: */
                    483:     return (rc == TME_OK
                    484:            ? TME_BUS_CYCLE_SYNCHRONOUS_EVENT
                    485:            : rc);
                    486:   }
                    487: 
                    488:   /* otherwise, this must be a write: */
                    489:   if (cycle_init->tme_bus_cycle_type != TME_BUS_CYCLE_WRITE) {
                    490:     abort();
                    491:   }
                    492: 
                    493:   /* this must be the first write: */
                    494:   if (sun3->tme_sun3_memerr_pending_csr != 0) {
                    495:     abort();
                    496:   }
                    497: 
                    498:   /* remember the pending memory error address and CSR value: */
                    499:   sun3->tme_sun3_memerr_pending_csr = csr;
                    500:   sun3->tme_sun3_memerr_pending_vaddr = vaddr;
                    501: 
                    502:   /* run the cycle normally: */
                    503:   return ((*sun3->tme_sun3_memerr_cycle)
                    504:          (sun3->tme_sun3_memerr_cycle_private, 
                    505:           cycle_init));
                    506: 
                    507: #undef TME_SUN3_MEMERR_RO
                    508: }
                    509: 
                    510: #if 1
                    511: #include <stdio.h>
                    512: 
                    513: /* this dumps out the sun3 state: */
                    514: void
                    515: tme_sun3_dump(struct tme_sun3 *sun3)
                    516: {
                    517:   
                    518:   /* dump out the page map register: */
                    519:   fprintf(stderr, "CONTEXT = 0x%02x\n", sun3->tme_sun3_context);
                    520:   fprintf(stderr, "\n");
                    521:   fprintf(stderr, "DIAG = 0x%02x\n", sun3->tme_sun3_diag);
                    522:   fprintf(stderr, "UDVMA = 0x%02x\n", sun3->tme_sun3_udvma);
                    523:   fprintf(stderr, "BUSERR = 0x%04x\n", sun3->tme_sun3_buserr);
                    524:   fprintf(stderr, "ENABLE = 0x%02x\n", sun3->tme_sun3_enable);
                    525:   fprintf(stderr, "INTS = 0x%02x\n", sun3->tme_sun3_ints);
                    526:   fprintf(stderr, "MEMERR = 0x%02x 0x%04x\n", sun3->tme_sun3_memerr_csr, sun3->tme_sun3_memerr_vaddr);
                    527: }
                    528: #endif /* 1 */

unix.superglobalmegacorp.com

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