Annotation of tme/machine/sun3/sun3-control.c, revision 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.