[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     ! 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