[BACK]Return to m88100_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / m88k / m88k

Annotation of sys/arch/m88k/m88k/m88100_machdep.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: m88100_machdep.c,v 1.3 2007/05/20 20:12:31 miod Exp $ */
                      2: /*
                      3:  * Mach Operating System
                      4:  * Copyright (c) 1993-1991 Carnegie Mellon University
                      5:  * Copyright (c) 1991 OMRON Corporation
                      6:  * All Rights Reserved.
                      7:  *
                      8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
                     13:  *
                     14:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     15:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
                     16:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     17:  *
                     18:  * Carnegie Mellon requests users of this software to return to
                     19:  *
                     20:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     21:  *  School of Computer Science
                     22:  *  Carnegie Mellon University
                     23:  *  Pittsburgh PA 15213-3890
                     24:  *
                     25:  * any improvements or extensions that they make and grant Carnegie the
                     26:  * rights to redistribute these changes.
                     27:  */
                     28:
                     29: #include "assym.h"     /* EF_xxx */
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33:
                     34: #include <machine/asm_macro.h>
                     35: #include <m88k/m88100.h>
                     36:
                     37: /*
                     38:  *  Data Access Emulation for M88100 exceptions
                     39:  */
                     40:
                     41: #define DMT_BYTE       1
                     42: #define DMT_HALF       2
                     43: #define DMT_WORD       4
                     44:
                     45: const struct {
                     46:        unsigned char    offset;
                     47:        unsigned char    size;
                     48: } dmt_en_info[16] = {
                     49:        {0, 0}, {3, DMT_BYTE}, {2, DMT_BYTE}, {2, DMT_HALF},
                     50:        {1, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
                     51:        {0, DMT_BYTE}, {0, 0}, {0, 0}, {0, 0},
                     52:        {0, DMT_HALF}, {0, 0}, {0, 0}, {0, DMT_WORD}
                     53: };
                     54:
                     55: #ifdef DATA_DEBUG
                     56: int data_access_emulation_debug = 0;
                     57: #define DAE_DEBUG(stuff) \
                     58:        do { \
                     59:                if (data_access_emulation_debug != 0) { \
                     60:                        stuff; \
                     61:                } \
                     62:        } while (0)
                     63: #else
                     64: #define DAE_DEBUG(stuff)
                     65: #endif
                     66:
                     67: void
                     68: dae_print(unsigned *eframe)
                     69: {
                     70:        int x;
                     71:        unsigned dmax, dmdx, dmtx;
                     72:
                     73:        if (!ISSET(eframe[EF_DMT0], DMT_VALID))
                     74:                return;
                     75:
                     76:        for (x = 0; x < 3; x++) {
                     77:                dmtx = eframe[EF_DMT0 + x * 3];
                     78:                if (!ISSET(dmtx, DMT_VALID))
                     79:                        continue;
                     80:
                     81:                dmdx = eframe[EF_DMD0 + x * 3];
                     82:                dmax = eframe[EF_DMA0 + x * 3];
                     83:
                     84:                if (ISSET(dmtx, DMT_WRITE))
                     85:                        printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
                     86:                            x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
                     87:                            DMT_ENBITS(dmtx),
                     88:                            dmtx & DMT_DOUB1 ? "double": "not double",
                     89:                            dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
                     90:                else
                     91:                        printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
                     92:                            x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
                     93:                            DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
                     94:                            dmtx & DMT_DOUB1 ? "double": "not double",
                     95:                            dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
                     96:        }
                     97: }
                     98:
                     99: void
                    100: data_access_emulation(unsigned *eframe)
                    101: {
                    102:        int x;
                    103:        unsigned dmax, dmdx, dmtx;
                    104:        unsigned v, reg;
                    105:
                    106:        dmtx = eframe[EF_DMT0];
                    107:        if (!ISSET(dmtx, DMT_VALID))
                    108:                return;
                    109:
                    110:        for (x = 0; x < 3; x++) {
                    111:                dmtx = eframe[EF_DMT0 + x * 3];
                    112:                if (!ISSET(dmtx, DMT_VALID) || ISSET(dmtx, DMT_SKIP))
                    113:                        continue;
                    114:
                    115:                dmdx = eframe[EF_DMD0 + x * 3];
                    116:                dmax = eframe[EF_DMA0 + x * 3];
                    117:
                    118:       DAE_DEBUG(
                    119:                if (ISSET(dmtx, DMT_WRITE))
                    120:                        printf("[DMT%d=%x: st.%c %x to %x as %d %s %s]\n",
                    121:                            x, dmtx, dmtx & DMT_DAS ? 's' : 'u', dmdx, dmax,
                    122:                            DMT_ENBITS(dmtx),
                    123:                            dmtx & DMT_DOUB1 ? "double": "not double",
                    124:                            dmtx & DMT_LOCKBAR ? "xmem": "not xmem");
                    125:                else
                    126:                        printf("[DMT%d=%x: ld.%c r%d <- %x as %d %s %s]\n",
                    127:                            x, dmtx, dmtx & DMT_DAS ? 's' : 'u',
                    128:                            DMT_DREGBITS(dmtx), dmax, DMT_ENBITS(dmtx),
                    129:                            dmtx & DMT_DOUB1 ? "double": "not double",
                    130:                            dmtx & DMT_LOCKBAR ? "xmem": "not xmem")
                    131:        );
                    132:
                    133:                dmax += dmt_en_info[DMT_ENBITS(dmtx)].offset;
                    134:                reg = DMT_DREGBITS(dmtx);
                    135:
                    136:                if (!ISSET(dmtx, DMT_LOCKBAR)) {
                    137:                        /* the fault is not during an XMEM */
                    138:
                    139:                        if (x == 2 && ISSET(dmtx, DMT_DOUB1)) {
                    140:                                /* pipeline 2 (earliest stage) for a double */
                    141:
                    142:                                if (ISSET(dmtx, DMT_WRITE)) {
                    143:                                        /*
                    144:                                         * STORE DOUBLE WILL BE REINITIATED
                    145:                                         * BY rte
                    146:                                         */
                    147:                                } else {
                    148:                                        /* EMULATE ld.d INSTRUCTION */
                    149:                                        v = do_load_word(dmax, dmtx & DMT_DAS);
                    150:                                        if (reg != 0)
                    151:                                                eframe[EF_R0 + reg] = v;
                    152:                                        v = do_load_word(dmax ^ 4,
                    153:                                            dmtx & DMT_DAS);
                    154:                                        if (reg != 31)
                    155:                                                eframe[EF_R0 + reg + 1] = v;
                    156:                                }
                    157:                        } else {
                    158:                                /* not pipeline #2 with a double */
                    159:                                if (dmtx & DMT_WRITE) {
                    160:                                        switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
                    161:                                        case DMT_BYTE:
                    162:                                        DAE_DEBUG(
                    163:                                                printf("[byte %x -> [%x(%c)]\n",
                    164:                                                    dmdx & 0xff, dmax,
                    165:                                                    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    166:                                        );
                    167:                                                do_store_byte(dmax, dmdx,
                    168:                                                    dmtx & DMT_DAS);
                    169:                                                break;
                    170:                                        case DMT_HALF:
                    171:                                        DAE_DEBUG(
                    172:                                                printf("[half %x -> [%x(%c)]\n",
                    173:                                                    dmdx & 0xffff, dmax,
                    174:                                                    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    175:                                        );
                    176:                                                do_store_half(dmax, dmdx,
                    177:                                                    dmtx & DMT_DAS);
                    178:                                                break;
                    179:                                        case DMT_WORD:
                    180:                                        DAE_DEBUG(
                    181:                                                printf("[word %x -> [%x(%c)]\n",
                    182:                                                    dmdx, dmax,
                    183:                                                    ISSET(dmtx, DMT_DAS) ? 's' : 'u')
                    184:                                        );
                    185:                                                do_store_word(dmax, dmdx,
                    186:                                                    dmtx & DMT_DAS);
                    187:                                                break;
                    188:                                        }
                    189:                                } else {
                    190:                                        /* else it's a read */
                    191:                                        switch (dmt_en_info[DMT_ENBITS(dmtx)].size) {
                    192:                                        case DMT_BYTE:
                    193:                                                v = do_load_byte(dmax,
                    194:                                                    dmtx & DMT_DAS);
                    195:                                                if (!ISSET(dmtx, DMT_SIGNED))
                    196:                                                        v &= 0x000000ff;
                    197:                                                break;
                    198:                                        case DMT_HALF:
                    199:                                                v = do_load_half(dmax,
                    200:                                                    dmtx & DMT_DAS);
                    201:                                                if (!ISSET(dmtx, DMT_SIGNED))
                    202:                                                        v &= 0x0000ffff;
                    203:                                                break;
                    204:                                        case DMT_WORD:
                    205:                                                v = do_load_word(dmax,
                    206:                                                    dmtx & DMT_DAS);
                    207:                                                break;
                    208:                                        }
                    209:                                        DAE_DEBUG(
                    210:                                                if (reg == 0)
                    211:                                                        printf("[no write to r0 done]\n");
                    212:                                                else
                    213:                                                        printf("[r%d <- %x]\n", reg, v);
                    214:                                        );
                    215:                                        if (reg != 0)
                    216:                                                eframe[EF_R0 + reg] = v;
                    217:                                }
                    218:                        }
                    219:                } else {
                    220:                        /* if lockbar is set... it's part of an XMEM */
                    221:                        /*
                    222:                         * According to Motorola's "General Information",
                    223:                         * the DMT_DOUB1 bit is never set in this case, as it
                    224:                         * should be.
                    225:                         * If lockbar is set (as it is if we're here) and if
                    226:                         * the write is not set, then it's the same as if DOUB1
                    227:                         * was set...
                    228:                         */
                    229:                        if (!ISSET(dmtx, DMT_WRITE)) {
                    230:                                if (x != 2) {
                    231:                                        /* RERUN xmem WITH DMD(x+1) */
                    232:                                        x++;
                    233:                                        dmdx = eframe[EF_DMD0 + x * 3];
                    234:                                } else {
                    235:                                        /* RERUN xmem WITH DMD2 */
                    236:                                }
                    237:
                    238:                                if (dmt_en_info[DMT_ENBITS(dmtx)].size ==
                    239:                                    DMT_WORD) {
                    240:                                        v = do_xmem_word(dmax, dmdx,
                    241:                                            dmtx & DMT_DAS);
                    242:                                } else {
                    243:                                        v = do_xmem_byte(dmax, dmdx,
                    244:                                            dmtx & DMT_DAS);
                    245:                                }
                    246:                                if (reg != 0)
                    247:                                        eframe[EF_R0 + reg] = v;
                    248:                        } else {
                    249:                                if (x == 0) {
                    250:                                        if (reg != 0)
                    251:                                                eframe[EF_R0 + reg] = dmdx;
                    252:                                        eframe[EF_SFIP] = eframe[EF_SNIP];
                    253:                                        eframe[EF_SNIP] = eframe[EF_SXIP];
                    254:                                        eframe[EF_SXIP] = 0;
                    255:                                        /* xmem RERUN ON rte */
                    256:                                        eframe[EF_DMT0] = 0;
                    257:                                        return;
                    258:                                }
                    259:                        }
                    260:                }
                    261:        }
                    262:        eframe[EF_DMT0] = 0;
                    263: }
                    264:
                    265: /*
                    266:  * Routines to patch the kernel code on 88100 systems not affected by
                    267:  * the xxx.usr bug.
                    268:  */
                    269:
                    270: void
                    271: m88100_apply_patches()
                    272: {
                    273: #ifdef ERRATA__XXX_USR
                    274:        if (((get_cpu_pid() & PID_VN) >> VN_SHIFT) > 10) {
                    275:                /*
                    276:                 * Patch DAE helpers.
                    277:                 *          before                  after
                    278:                 *      branch                  branch
                    279:                 *      NOP                     jmp.n r1
                    280:                 *      xxx.usr                 xxx.usr
                    281:                 *      NOP; NOP; NOP
                    282:                 *      jmp r1
                    283:                 */
                    284:                ((u_int32_t *)(do_load_word))[1] = 0xf400c401;
                    285:                ((u_int32_t *)(do_load_half))[1] = 0xf400c401;
                    286:                ((u_int32_t *)(do_load_byte))[1] = 0xf400c401;
                    287:                ((u_int32_t *)(do_store_word))[1] = 0xf400c401;
                    288:                ((u_int32_t *)(do_store_half))[1] = 0xf400c401;
                    289:                ((u_int32_t *)(do_store_byte))[1] = 0xf400c401;
                    290:                ((u_int32_t *)(do_xmem_word))[1] = 0xf400c401;
                    291:                ((u_int32_t *)(do_xmem_byte))[1] = 0xf400c401;
                    292:        }
                    293: #endif
                    294: }

CVSweb