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

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

1.1       nbrk        1: /*     $OpenBSD: trap.c,v 1.40 2007/05/11 10:06:55 pedro Exp $ */
                      2: /*
                      3:  * Copyright (c) 2004, Miodrag Vallat.
                      4:  * Copyright (c) 1998 Steve Murphree, Jr.
                      5:  * Copyright (c) 1996 Nivas Madhur
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Nivas Madhur.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  *
                     33:  */
                     34: /*
                     35:  * Mach Operating System
                     36:  * Copyright (c) 1991 Carnegie Mellon University
                     37:  * Copyright (c) 1991 OMRON Corporation
                     38:  * All Rights Reserved.
                     39:  *
                     40:  * Permission to use, copy, modify and distribute this software and its
                     41:  * documentation is hereby granted, provided that both the copyright
                     42:  * notice and this permission notice appear in all copies of the
                     43:  * software, derivative works or modified versions, and any portions
                     44:  * thereof, and that both notices appear in supporting documentation.
                     45:  *
                     46:  */
                     47:
                     48: #include <sys/types.h>
                     49: #include <sys/param.h>
                     50: #include <sys/proc.h>
                     51: #include <sys/signalvar.h>
                     52: #include <sys/user.h>
                     53: #include <sys/syscall.h>
                     54: #include <sys/systm.h>
                     55: #include <sys/ktrace.h>
                     56:
                     57: #include "systrace.h"
                     58: #include <dev/systrace.h>
                     59:
                     60: #include <uvm/uvm_extern.h>
                     61:
                     62: #include <machine/asm_macro.h>   /* enable/disable interrupts */
                     63: #include <machine/cmmu.h>
                     64: #include <machine/cpu.h>
                     65: #ifdef M88100
                     66: #include <machine/m88100.h>            /* DMT_xxx */
                     67: #include <machine/m8820x.h>            /* CMMU_PFSR_xxx */
                     68: #endif
                     69: #ifdef M88110
                     70: #include <machine/m88110.h>
                     71: #endif
                     72: #include <machine/pcb.h>               /* FIP_E, etc. */
                     73: #include <machine/psl.h>               /* FIP_E, etc. */
                     74: #include <machine/trap.h>
                     75:
                     76: #include <machine/db_machdep.h>
                     77:
                     78: #define SSBREAKPOINT (0xF000D1F8U) /* Single Step Breakpoint */
                     79:
                     80: #define USERMODE(PSR)   (((PSR) & PSR_MODE) == 0)
                     81: #define SYSTEMMODE(PSR) (((PSR) & PSR_MODE) != 0)
                     82:
                     83: __dead void panictrap(int, struct trapframe *);
                     84: __dead void error_fatal(struct trapframe *);
                     85: int double_reg_fixup(struct trapframe *);
                     86: int ss_put_value(struct proc *, vaddr_t, u_int);
                     87:
                     88: extern void regdump(struct trapframe *f);
                     89:
                     90: const char *trap_type[] = {
                     91:        "Reset",
                     92:        "Interrupt Exception",
                     93:        "Instruction Access",
                     94:        "Data Access Exception",
                     95:        "Misaligned Access",
                     96:        "Unimplemented Opcode",
                     97:        "Privilege Violation"
                     98:        "Bounds Check Violation",
                     99:        "Illegal Integer Divide",
                    100:        "Integer Overflow",
                    101:        "Error Exception",
                    102:        "Non-Maskable Exception",
                    103: };
                    104:
                    105: const int trap_types = sizeof trap_type / sizeof trap_type[0];
                    106:
                    107: #ifdef M88100
                    108: const char *pbus_exception_type[] = {
                    109:        "Success (No Fault)",
                    110:        "unknown 1",
                    111:        "unknown 2",
                    112:        "Bus Error",
                    113:        "Segment Fault",
                    114:        "Page Fault",
                    115:        "Supervisor Violation",
                    116:        "Write Violation",
                    117: };
                    118: #endif
                    119:
                    120: static inline void
                    121: userret(struct proc *p)
                    122: {
                    123:        int sig;
                    124:
                    125:        /* take pending signals */
                    126:        while ((sig = CURSIG(p)) != 0)
                    127:                postsig(sig);
                    128:
                    129:        curcpu()->ci_schedstate.spc_curpriority = p->p_priority = p->p_usrpri;
                    130: }
                    131:
                    132: __dead void
                    133: panictrap(int type, struct trapframe *frame)
                    134: {
                    135:        static int panicing = 0;
                    136:
                    137:        if (panicing++ == 0) {
                    138: #ifdef M88100
                    139:                if (CPU_IS88100) {
                    140:                        if (type == 2) {
                    141:                                /* instruction exception */
                    142:                                printf("\nInstr access fault (%s) v = %x, "
                    143:                                    "frame %p\n",
                    144:                                    pbus_exception_type[
                    145:                                      CMMU_PFSR_FAULT(frame->tf_ipfsr)],
                    146:                                    frame->tf_sxip & XIP_ADDR, frame);
                    147:                        } else if (type == 3) {
                    148:                                /* data access exception */
                    149:                                printf("\nData access fault (%s) v = %x, "
                    150:                                    "frame %p\n",
                    151:                                    pbus_exception_type[
                    152:                                      CMMU_PFSR_FAULT(frame->tf_dpfsr)],
                    153:                                    frame->tf_sxip & XIP_ADDR, frame);
                    154:                        } else
                    155:                                printf("\nTrap type %d, v = %x, frame %p\n",
                    156:                                    type, frame->tf_sxip & XIP_ADDR, frame);
                    157:                }
                    158: #endif
                    159: #ifdef M88110
                    160:                if (CPU_IS88110) {
                    161:                        printf("\nTrap type %d, v = %x, frame %p\n",
                    162:                            type, frame->tf_exip, frame);
                    163:                }
                    164: #endif
                    165: #ifdef DDB
                    166:                regdump(frame);
                    167: #endif
                    168:        }
                    169:        if ((u_int)type < trap_types)
                    170:                panic(trap_type[type]);
                    171:        else
                    172:                panic("trap %d", type);
                    173:        /*NOTREACHED*/
                    174: }
                    175:
                    176: #ifdef M88100
                    177: void
                    178: m88100_trap(unsigned type, struct trapframe *frame)
                    179: {
                    180:        struct proc *p;
                    181:        struct vm_map *map;
                    182:        vaddr_t va, pcb_onfault;
                    183:        vm_prot_t ftype;
                    184:        int fault_type, pbus_type;
                    185:        u_long fault_code;
                    186:        unsigned fault_addr;
                    187:        struct vmspace *vm;
                    188:        union sigval sv;
                    189:        int result;
                    190: #ifdef DDB
                    191:        int s;
                    192:        u_int psr;
                    193: #endif
                    194:        int sig = 0;
                    195:
                    196:        extern struct vm_map *kernel_map;
                    197:
                    198:        uvmexp.traps++;
                    199:        if ((p = curproc) == NULL)
                    200:                p = &proc0;
                    201:
                    202:        if (USERMODE(frame->tf_epsr)) {
                    203:                type += T_USER;
                    204:                p->p_md.md_tf = frame;  /* for ptrace/signals */
                    205:        }
                    206:        fault_type = 0;
                    207:        fault_code = 0;
                    208:        fault_addr = frame->tf_sxip & XIP_ADDR;
                    209:
                    210:        switch (type) {
                    211:        default:
                    212:                panictrap(frame->tf_vector, frame);
                    213:                break;
                    214:                /*NOTREACHED*/
                    215:
                    216: #if defined(DDB)
                    217:        case T_KDB_BREAK:
                    218:                s = splhigh();
                    219:                set_psr((psr = get_psr()) & ~PSR_IND);
                    220:                ddb_break_trap(T_KDB_BREAK, (db_regs_t*)frame);
                    221:                set_psr(psr);
                    222:                splx(s);
                    223:                return;
                    224:        case T_KDB_ENTRY:
                    225:                s = splhigh();
                    226:                set_psr((psr = get_psr()) & ~PSR_IND);
                    227:                ddb_entry_trap(T_KDB_ENTRY, (db_regs_t*)frame);
                    228:                set_psr(psr);
                    229:                splx(s);
                    230:                return;
                    231: #endif /* DDB */
                    232:        case T_ILLFLT:
                    233:                printf("Unimplemented opcode!\n");
                    234:                panictrap(frame->tf_vector, frame);
                    235:                break;
                    236:        case T_INT:
                    237:        case T_INT+T_USER:
                    238:                curcpu()->ci_intrdepth++;
                    239:                md_interrupt_func(T_INT, frame);
                    240:                curcpu()->ci_intrdepth--;
                    241:                return;
                    242:
                    243:        case T_MISALGNFLT:
                    244:                printf("kernel misaligned access exception @ 0x%08x\n",
                    245:                    frame->tf_sxip);
                    246:                panictrap(frame->tf_vector, frame);
                    247:                break;
                    248:
                    249:        case T_INSTFLT:
                    250:                /* kernel mode instruction access fault.
                    251:                 * Should never, never happen for a non-paged kernel.
                    252:                 */
                    253: #ifdef TRAPDEBUG
                    254:                pbus_type = CMMU_PFSR_FAULT(frame->tf_ipfsr);
                    255:                printf("Kernel Instruction fault #%d (%s) v = 0x%x, frame 0x%x cpu %p\n",
                    256:                    pbus_type, pbus_exception_type[pbus_type],
                    257:                    fault_addr, frame, frame->tf_cpu);
                    258: #endif
                    259:                panictrap(frame->tf_vector, frame);
                    260:                break;
                    261:
                    262:        case T_DATAFLT:
                    263:                /* kernel mode data fault */
                    264:
                    265:                /* data fault on the user address? */
                    266:                if ((frame->tf_dmt0 & DMT_DAS) == 0) {
                    267:                        type = T_DATAFLT + T_USER;
                    268:                        goto user_fault;
                    269:                }
                    270:
                    271:                fault_addr = frame->tf_dma0;
                    272:                if (frame->tf_dmt0 & (DMT_WRITE|DMT_LOCKBAR)) {
                    273:                        ftype = VM_PROT_READ|VM_PROT_WRITE;
                    274:                        fault_code = VM_PROT_WRITE;
                    275:                } else {
                    276:                        ftype = VM_PROT_READ;
                    277:                        fault_code = VM_PROT_READ;
                    278:                }
                    279:
                    280:                va = trunc_page((vaddr_t)fault_addr);
                    281:                if (va == 0) {
                    282:                        panic("trap: bad kernel access at %x", fault_addr);
                    283:                }
                    284:
                    285:                KERNEL_LOCK();
                    286:                vm = p->p_vmspace;
                    287:                map = kernel_map;
                    288:
                    289:                pbus_type = CMMU_PFSR_FAULT(frame->tf_dpfsr);
                    290: #ifdef TRAPDEBUG
                    291:                printf("Kernel Data access fault #%d (%s) v = 0x%x, frame 0x%x cpu %p\n",
                    292:                    pbus_type, pbus_exception_type[pbus_type],
                    293:                    fault_addr, frame, frame->tf_cpu);
                    294: #endif
                    295:
                    296:                switch (pbus_type) {
                    297:                case CMMU_PFSR_SUCCESS:
                    298:                        /*
                    299:                         * The fault was resolved. Call data_access_emulation
                    300:                         * to drain the data unit pipe line and reset dmt0
                    301:                         * so that trap won't get called again.
                    302:                         */
                    303:                        data_access_emulation((unsigned *)frame);
                    304:                        frame->tf_dpfsr = 0;
                    305:                        frame->tf_dmt0 = 0;
                    306:                        KERNEL_UNLOCK();
                    307:                        return;
                    308:                case CMMU_PFSR_SFAULT:
                    309:                case CMMU_PFSR_PFAULT:
                    310:                        if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
                    311:                                p->p_addr->u_pcb.pcb_onfault = 0;
                    312:                        result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    313:                        p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    314:                        if (result == 0) {
                    315:                                /*
                    316:                                 * We could resolve the fault. Call
                    317:                                 * data_access_emulation to drain the data
                    318:                                 * unit pipe line and reset dmt0 so that trap
                    319:                                 * won't get called again.
                    320:                                 */
                    321:                                data_access_emulation((unsigned *)frame);
                    322:                                frame->tf_dpfsr = 0;
                    323:                                frame->tf_dmt0 = 0;
                    324:                                KERNEL_UNLOCK();
                    325:                                return;
                    326:                        }
                    327:                        break;
                    328:                }
                    329: #ifdef TRAPDEBUG
                    330:                printf("PBUS Fault %d (%s) va = 0x%x\n", pbus_type,
                    331:                    pbus_exception_type[pbus_type], va);
                    332: #endif
                    333:                KERNEL_UNLOCK();
                    334:                panictrap(frame->tf_vector, frame);
                    335:                /* NOTREACHED */
                    336:        case T_INSTFLT+T_USER:
                    337:                /* User mode instruction access fault */
                    338:                /* FALLTHROUGH */
                    339:        case T_DATAFLT+T_USER:
                    340: user_fault:
                    341:                if (type == T_INSTFLT + T_USER) {
                    342:                        pbus_type = CMMU_PFSR_FAULT(frame->tf_ipfsr);
                    343: #ifdef TRAPDEBUG
                    344:                        printf("User Instruction fault #%d (%s) v = 0x%x, frame 0x%x cpu %p\n",
                    345:                            pbus_type, pbus_exception_type[pbus_type],
                    346:                            fault_addr, frame, frame->tf_cpu);
                    347: #endif
                    348:                } else {
                    349:                        fault_addr = frame->tf_dma0;
                    350:                        pbus_type = CMMU_PFSR_FAULT(frame->tf_dpfsr);
                    351: #ifdef TRAPDEBUG
                    352:                        printf("User Data access fault #%d (%s) v = 0x%x, frame 0x%x cpu %p\n",
                    353:                            pbus_type, pbus_exception_type[pbus_type],
                    354:                            fault_addr, frame, frame->tf_cpu);
                    355: #endif
                    356:                }
                    357:
                    358:                if (frame->tf_dmt0 & (DMT_WRITE | DMT_LOCKBAR)) {
                    359:                        ftype = VM_PROT_READ | VM_PROT_WRITE;
                    360:                        fault_code = VM_PROT_WRITE;
                    361:                } else {
                    362:                        ftype = VM_PROT_READ;
                    363:                        fault_code = VM_PROT_READ;
                    364:                }
                    365:
                    366:                va = trunc_page((vaddr_t)fault_addr);
                    367:
                    368:                KERNEL_PROC_LOCK(p);
                    369:                vm = p->p_vmspace;
                    370:                map = &vm->vm_map;
                    371:                if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
                    372:                        p->p_addr->u_pcb.pcb_onfault = 0;
                    373:
                    374:                /* Call uvm_fault() to resolve non-bus error faults */
                    375:                switch (pbus_type) {
                    376:                case CMMU_PFSR_SUCCESS:
                    377:                        result = 0;
                    378:                        break;
                    379:                case CMMU_PFSR_BERROR:
                    380:                        result = EACCES;
                    381:                        break;
                    382:                default:
                    383:                        result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    384:                        break;
                    385:                }
                    386:
                    387:                p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    388:
                    389:                if ((caddr_t)va >= vm->vm_maxsaddr) {
                    390:                        if (result == 0)
                    391:                                uvm_grow(p, va);
                    392:                        else if (result == EACCES)
                    393:                                result = EFAULT;
                    394:                }
                    395:                KERNEL_PROC_UNLOCK(p);
                    396:
                    397:                /*
                    398:                 * This could be a fault caused in copyin*()
                    399:                 * while accessing user space.
                    400:                 */
                    401:                if (result != 0 && pcb_onfault != 0) {
                    402:                        frame->tf_snip = pcb_onfault | NIP_V;
                    403:                        frame->tf_sfip = (pcb_onfault + 4) | FIP_V;
                    404:                        frame->tf_sxip = 0;
                    405:                        /*
                    406:                         * Continue as if the fault had been resolved, but
                    407:                         * do not try to complete the faulting access.
                    408:                         */
                    409:                        frame->tf_dmt0 |= DMT_SKIP;
                    410:                        result = 0;
                    411:                }
                    412:
                    413:                if (result == 0) {
                    414:                        if (type == T_DATAFLT+T_USER) {
                    415:                                /*
                    416:                                 * We could resolve the fault. Call
                    417:                                 * data_access_emulation to drain the data unit
                    418:                                 * pipe line and reset dmt0 so that trap won't
                    419:                                 * get called again.
                    420:                                 */
                    421:                                data_access_emulation((unsigned *)frame);
                    422:                                frame->tf_dpfsr = 0;
                    423:                                frame->tf_dmt0 = 0;
                    424:                        } else {
                    425:                                /*
                    426:                                 * back up SXIP, SNIP,
                    427:                                 * clearing the Error bit
                    428:                                 */
                    429:                                frame->tf_sfip = frame->tf_snip & ~FIP_E;
                    430:                                frame->tf_snip = frame->tf_sxip & ~NIP_E;
                    431:                                frame->tf_ipfsr = 0;
                    432:                        }
                    433:                } else {
                    434:                        sig = result == EACCES ? SIGBUS : SIGSEGV;
                    435:                        fault_type = result == EACCES ?
                    436:                            BUS_ADRERR : SEGV_MAPERR;
                    437:                }
                    438:                break;
                    439:        case T_MISALGNFLT+T_USER:
                    440:                /* Fix any misaligned ld.d or st.d instructions */
                    441:                sig = double_reg_fixup(frame);
                    442:                fault_type = BUS_ADRALN;
                    443:                break;
                    444:        case T_PRIVINFLT+T_USER:
                    445:        case T_ILLFLT+T_USER:
                    446: #ifndef DDB
                    447:        case T_KDB_BREAK:
                    448:        case T_KDB_ENTRY:
                    449: #endif
                    450:        case T_KDB_BREAK+T_USER:
                    451:        case T_KDB_ENTRY+T_USER:
                    452:        case T_KDB_TRACE:
                    453:        case T_KDB_TRACE+T_USER:
                    454:                sig = SIGILL;
                    455:                break;
                    456:        case T_BNDFLT+T_USER:
                    457:                sig = SIGFPE;
                    458:                break;
                    459:        case T_ZERODIV+T_USER:
                    460:                sig = SIGFPE;
                    461:                fault_type = FPE_INTDIV;
                    462:                break;
                    463:        case T_OVFFLT+T_USER:
                    464:                sig = SIGFPE;
                    465:                fault_type = FPE_INTOVF;
                    466:                break;
                    467:        case T_FPEPFLT+T_USER:
                    468:                sig = SIGFPE;
                    469:                break;
                    470:        case T_SIGSYS+T_USER:
                    471:                sig = SIGSYS;
                    472:                break;
                    473:        case T_STEPBPT+T_USER:
                    474: #ifdef PTRACE
                    475:                /*
                    476:                 * This trap is used by the kernel to support single-step
                    477:                 * debugging (although any user could generate this trap
                    478:                 * which should probably be handled differently). When a
                    479:                 * process is continued by a debugger with the PT_STEP
                    480:                 * function of ptrace (single step), the kernel inserts
                    481:                 * one or two breakpoints in the user process so that only
                    482:                 * one instruction (or two in the case of a delayed branch)
                    483:                 * is executed.  When this breakpoint is hit, we get the
                    484:                 * T_STEPBPT trap.
                    485:                 */
                    486:                {
                    487:                        u_int instr;
                    488:                        vaddr_t pc = PC_REGS(&frame->tf_regs);
                    489:
                    490:                        /* read break instruction */
                    491:                        copyin((caddr_t)pc, &instr, sizeof(u_int));
                    492:
                    493:                        /* check and see if we got here by accident */
                    494:                        if ((p->p_md.md_bp0va != pc &&
                    495:                             p->p_md.md_bp1va != pc) ||
                    496:                            instr != SSBREAKPOINT) {
                    497:                                sig = SIGTRAP;
                    498:                                fault_type = TRAP_TRACE;
                    499:                                break;
                    500:                        }
                    501:
                    502:                        /* restore original instruction and clear breakpoint */
                    503:                        if (p->p_md.md_bp0va == pc) {
                    504:                                ss_put_value(p, pc, p->p_md.md_bp0save);
                    505:                                p->p_md.md_bp0va = 0;
                    506:                        }
                    507:                        if (p->p_md.md_bp1va == pc) {
                    508:                                ss_put_value(p, pc, p->p_md.md_bp1save);
                    509:                                p->p_md.md_bp1va = 0;
                    510:                        }
                    511:
                    512: #if 1
                    513:                        frame->tf_sfip = frame->tf_snip;
                    514:                        frame->tf_snip = pc | NIP_V;
                    515: #endif
                    516:                        sig = SIGTRAP;
                    517:                        fault_type = TRAP_BRKPT;
                    518:                }
                    519: #else
                    520:                sig = SIGTRAP;
                    521:                fault_type = TRAP_TRACE;
                    522: #endif
                    523:                break;
                    524:
                    525:        case T_USERBPT+T_USER:
                    526:                /*
                    527:                 * This trap is meant to be used by debuggers to implement
                    528:                 * breakpoint debugging.  When we get this trap, we just
                    529:                 * return a signal which gets caught by the debugger.
                    530:                 */
                    531:                frame->tf_sfip = frame->tf_snip;
                    532:                frame->tf_snip = frame->tf_sxip;
                    533:                sig = SIGTRAP;
                    534:                fault_type = TRAP_BRKPT;
                    535:                break;
                    536:
                    537:        case T_ASTFLT+T_USER:
                    538:                uvmexp.softs++;
                    539:                p->p_md.md_astpending = 0;
                    540:                if (p->p_flag & P_OWEUPC) {
                    541:                        KERNEL_PROC_LOCK(p);
                    542:                        ADDUPROF(p);
                    543:                        KERNEL_PROC_UNLOCK(p);
                    544:                }
                    545:                if (curcpu()->ci_want_resched)
                    546:                        preempt(NULL);
                    547:                break;
                    548:        }
                    549:
                    550:        /*
                    551:         * If trap from supervisor mode, just return
                    552:         */
                    553:        if (type < T_USER)
                    554:                return;
                    555:
                    556:        if (sig) {
                    557:                sv.sival_int = fault_addr;
                    558:                KERNEL_PROC_LOCK(p);
                    559:                trapsignal(p, sig, fault_code, fault_type, sv);
                    560:                KERNEL_PROC_UNLOCK(p);
                    561:                /*
                    562:                 * don't want multiple faults - we are going to
                    563:                 * deliver signal.
                    564:                 */
                    565:                frame->tf_dmt0 = 0;
                    566:                frame->tf_ipfsr = frame->tf_dpfsr = 0;
                    567:        }
                    568:
                    569:        userret(p);
                    570: }
                    571: #endif /* M88100 */
                    572:
                    573: #ifdef M88110
                    574: void
                    575: m88110_trap(unsigned type, struct trapframe *frame)
                    576: {
                    577:        struct proc *p;
                    578:        struct vm_map *map;
                    579:        vaddr_t va, pcb_onfault;
                    580:        vm_prot_t ftype;
                    581:        int fault_type;
                    582:        u_long fault_code;
                    583:        unsigned fault_addr;
                    584:        struct vmspace *vm;
                    585:        union sigval sv;
                    586:        int result;
                    587: #ifdef DDB
                    588:         int s;
                    589:        u_int psr;
                    590: #endif
                    591:        int sig = 0;
                    592:        pt_entry_t *pte;
                    593:
                    594:        extern struct vm_map *kernel_map;
                    595:        extern pt_entry_t *pmap_pte(pmap_t, vaddr_t);
                    596:
                    597:        uvmexp.traps++;
                    598:        if ((p = curproc) == NULL)
                    599:                p = &proc0;
                    600:
                    601:        if (USERMODE(frame->tf_epsr)) {
                    602:                type += T_USER;
                    603:                p->p_md.md_tf = frame;  /* for ptrace/signals */
                    604:        }
                    605:        fault_type = 0;
                    606:        fault_code = 0;
                    607:        fault_addr = frame->tf_exip & XIP_ADDR;
                    608:
                    609:        switch (type) {
                    610:        default:
                    611:                panictrap(frame->tf_vector, frame);
                    612:                break;
                    613:                /*NOTREACHED*/
                    614:
                    615:        case T_110_DRM+T_USER:
                    616:        case T_110_DRM:
                    617: #ifdef DEBUG
                    618:                printf("DMMU read miss: Hardware Table Searches should be enabled!\n");
                    619: #endif
                    620:                panictrap(frame->tf_vector, frame);
                    621:                break;
                    622:                /*NOTREACHED*/
                    623:        case T_110_DWM+T_USER:
                    624:        case T_110_DWM:
                    625: #ifdef DEBUG
                    626:                printf("DMMU write miss: Hardware Table Searches should be enabled!\n");
                    627: #endif
                    628:                panictrap(frame->tf_vector, frame);
                    629:                break;
                    630:                /*NOTREACHED*/
                    631:        case T_110_IAM+T_USER:
                    632:        case T_110_IAM:
                    633: #ifdef DEBUG
                    634:                printf("IMMU miss: Hardware Table Searches should be enabled!\n");
                    635: #endif
                    636:                panictrap(frame->tf_vector, frame);
                    637:                break;
                    638:                /*NOTREACHED*/
                    639:
                    640: #ifdef DDB
                    641:        case T_KDB_TRACE:
                    642:                s = splhigh();
                    643:                set_psr((psr = get_psr()) & ~PSR_IND);
                    644:                ddb_break_trap(T_KDB_TRACE, (db_regs_t*)frame);
                    645:                set_psr(psr);
                    646:                splx(s);
                    647:                return;
                    648:        case T_KDB_BREAK:
                    649:                s = splhigh();
                    650:                set_psr((psr = get_psr()) & ~PSR_IND);
                    651:                ddb_break_trap(T_KDB_BREAK, (db_regs_t*)frame);
                    652:                set_psr(psr);
                    653:                splx(s);
                    654:                return;
                    655:        case T_KDB_ENTRY:
                    656:                s = splhigh();
                    657:                set_psr((psr = get_psr()) & ~PSR_IND);
                    658:                ddb_entry_trap(T_KDB_ENTRY, (db_regs_t*)frame);
                    659:                set_psr(psr);
                    660:                /* skip one instruction */
                    661:                if (frame->tf_exip & 1)
                    662:                        frame->tf_exip = frame->tf_enip;
                    663:                else
                    664:                        frame->tf_exip += 4;
                    665:                splx(s);
                    666:                return;
                    667: #if 0
                    668:        case T_ILLFLT:
                    669:                s = splhigh();
                    670:                set_psr((psr = get_psr()) & ~PSR_IND);
                    671:                ddb_error_trap(type == T_ILLFLT ? "unimplemented opcode" :
                    672:                       "error fault", (db_regs_t*)frame);
                    673:                set_psr(psr);
                    674:                splx(s);
                    675:                return;
                    676: #endif /* 0 */
                    677: #endif /* DDB */
                    678:        case T_ILLFLT:
                    679:                printf("Unimplemented opcode!\n");
                    680:                panictrap(frame->tf_vector, frame);
                    681:                break;
                    682:        case T_NON_MASK:
                    683:        case T_NON_MASK+T_USER:
                    684:                curcpu()->ci_intrdepth++;
                    685:                md_interrupt_func(T_NON_MASK, frame);
                    686:                curcpu()->ci_intrdepth--;
                    687:                return;
                    688:        case T_INT:
                    689:        case T_INT+T_USER:
                    690:                curcpu()->ci_intrdepth++;
                    691:                md_interrupt_func(T_INT, frame);
                    692:                curcpu()->ci_intrdepth--;
                    693:                return;
                    694:        case T_MISALGNFLT:
                    695:                printf("kernel mode misaligned access exception @ 0x%08x\n",
                    696:                    frame->tf_exip);
                    697:                panictrap(frame->tf_vector, frame);
                    698:                break;
                    699:                /*NOTREACHED*/
                    700:
                    701:        case T_INSTFLT:
                    702:                /* kernel mode instruction access fault.
                    703:                 * Should never, never happen for a non-paged kernel.
                    704:                 */
                    705: #ifdef TRAPDEBUG
                    706:                printf("Kernel Instruction fault exip %x isr %x ilar %x\n",
                    707:                    frame->tf_exip, frame->tf_isr, frame->tf_ilar);
                    708: #endif
                    709:                panictrap(frame->tf_vector, frame);
                    710:                break;
                    711:                /*NOTREACHED*/
                    712:
                    713:        case T_DATAFLT:
                    714:                /* kernel mode data fault */
                    715:
                    716:                /* data fault on the user address? */
                    717:                if ((frame->tf_dsr & CMMU_DSR_SU) == 0) {
                    718:                        type = T_DATAFLT + T_USER;
                    719:                        goto m88110_user_fault;
                    720:                }
                    721:
                    722: #ifdef TRAPDEBUG
                    723:                printf("Kernel Data access fault exip %x dsr %x dlar %x\n",
                    724:                    frame->tf_exip, frame->tf_dsr, frame->tf_dlar);
                    725: #endif
                    726:
                    727:                fault_addr = frame->tf_dlar;
                    728:                if (frame->tf_dsr & CMMU_DSR_RW) {
                    729:                        ftype = VM_PROT_READ;
                    730:                        fault_code = VM_PROT_READ;
                    731:                } else {
                    732:                        ftype = VM_PROT_READ|VM_PROT_WRITE;
                    733:                        fault_code = VM_PROT_WRITE;
                    734:                }
                    735:
                    736:                va = trunc_page((vaddr_t)fault_addr);
                    737:                if (va == 0) {
                    738:                        panic("trap: bad kernel access at %x", fault_addr);
                    739:                }
                    740:
                    741:                KERNEL_LOCK();
                    742:                vm = p->p_vmspace;
                    743:                map = kernel_map;
                    744:
                    745:                if (frame->tf_dsr & (CMMU_DSR_SI | CMMU_DSR_PI)) {
                    746:                        frame->tf_dsr &= ~CMMU_DSR_WE;  /* undefined */
                    747:                        /*
                    748:                         * On a segment or a page fault, call uvm_fault() to
                    749:                         * resolve the fault.
                    750:                         */
                    751:                        if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
                    752:                                p->p_addr->u_pcb.pcb_onfault = 0;
                    753:                        result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    754:                        p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    755:                        if (result == 0) {
                    756:                                KERNEL_UNLOCK();
                    757:                                return;
                    758:                        }
                    759:                }
                    760:                if (frame->tf_dsr & CMMU_DSR_WE) {      /* write fault  */
                    761:                        /*
                    762:                         * This could be a write protection fault or an
                    763:                         * exception to set the used and modified bits
                    764:                         * in the pte. Basically, if we got a write error,
                    765:                         * then we already have a pte entry that faulted
                    766:                         * in from a previous seg fault or page fault.
                    767:                         * Get the pte and check the status of the
                    768:                         * modified and valid bits to determine if this
                    769:                         * indeed a real write fault.  XXX smurph
                    770:                         */
                    771:                        pte = pmap_pte(map->pmap, va);
                    772: #ifdef DEBUG
                    773:                        if (pte == NULL) {
                    774:                                KERNEL_UNLOCK();
                    775:                                panic("NULL pte on write fault??");
                    776:                        }
                    777: #endif
                    778:                        if (!(*pte & PG_M) && !(*pte & PG_RO)) {
                    779:                                /* Set modified bit and try the write again. */
                    780: #ifdef TRAPDEBUG
                    781:                                printf("Corrected kernel write fault, map %x pte %x\n",
                    782:                                    map->pmap, *pte);
                    783: #endif
                    784:                                *pte |= PG_M;
                    785:                                KERNEL_UNLOCK();
                    786:                                return;
                    787: #if 1  /* shouldn't happen */
                    788:                        } else {
                    789:                                /* must be a real wp fault */
                    790: #ifdef TRAPDEBUG
                    791:                                printf("Uncorrected kernel write fault, map %x pte %x\n",
                    792:                                    map->pmap, *pte);
                    793: #endif
                    794:                                if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
                    795:                                        p->p_addr->u_pcb.pcb_onfault = 0;
                    796:                                result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    797:                                p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    798:                                if (result == 0) {
                    799:                                        KERNEL_UNLOCK();
                    800:                                        return;
                    801:                                }
                    802: #endif
                    803:                        }
                    804:                }
                    805:                KERNEL_UNLOCK();
                    806:                panictrap(frame->tf_vector, frame);
                    807:                /* NOTREACHED */
                    808:        case T_INSTFLT+T_USER:
                    809:                /* User mode instruction access fault */
                    810:                /* FALLTHROUGH */
                    811:        case T_DATAFLT+T_USER:
                    812: m88110_user_fault:
                    813:                if (type == T_INSTFLT+T_USER) {
                    814:                        ftype = VM_PROT_READ;
                    815:                        fault_code = VM_PROT_READ;
                    816: #ifdef TRAPDEBUG
                    817:                        printf("User Instruction fault exip %x isr %x ilar %x\n",
                    818:                            frame->tf_exip, frame->tf_isr, frame->tf_ilar);
                    819: #endif
                    820:                } else {
                    821:                        fault_addr = frame->tf_dlar;
                    822:                        if (frame->tf_dsr & CMMU_DSR_RW) {
                    823:                                ftype = VM_PROT_READ;
                    824:                                fault_code = VM_PROT_READ;
                    825:                        } else {
                    826:                                ftype = VM_PROT_READ|VM_PROT_WRITE;
                    827:                                fault_code = VM_PROT_WRITE;
                    828:                        }
                    829: #ifdef TRAPDEBUG
                    830:                        printf("User Data access fault exip %x dsr %x dlar %x\n",
                    831:                            frame->tf_exip, frame->tf_dsr, frame->tf_dlar);
                    832: #endif
                    833:                }
                    834:
                    835:                va = trunc_page((vaddr_t)fault_addr);
                    836:
                    837:                KERNEL_PROC_LOCK(p);
                    838:                vm = p->p_vmspace;
                    839:                map = &vm->vm_map;
                    840:                if ((pcb_onfault = p->p_addr->u_pcb.pcb_onfault) != 0)
                    841:                        p->p_addr->u_pcb.pcb_onfault = 0;
                    842:
                    843:                /*
                    844:                 * Call uvm_fault() to resolve non-bus error faults
                    845:                 * whenever possible.
                    846:                 */
                    847:                if (type == T_DATAFLT+T_USER) {
                    848:                        /* data faults */
                    849:                        if (frame->tf_dsr & CMMU_DSR_BE) {
                    850:                                /* bus error */
                    851:                                result = EACCES;
                    852:                        } else
                    853:                        if (frame->tf_dsr & (CMMU_DSR_SI | CMMU_DSR_PI)) {
                    854:                                /* segment or page fault */
                    855:                                result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    856:                                p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    857:                        } else
                    858:                        if (frame->tf_dsr & (CMMU_DSR_CP | CMMU_DSR_WA)) {
                    859:                                /* copyback or write allocate error */
                    860:                                result = EACCES;
                    861:                        } else
                    862:                        if (frame->tf_dsr & CMMU_DSR_WE) {
                    863:                                /* write fault  */
                    864:                                /* This could be a write protection fault or an
                    865:                                 * exception to set the used and modified bits
                    866:                                 * in the pte. Basically, if we got a write
                    867:                                 * error, then we already have a pte entry that
                    868:                                 * faulted in from a previous seg fault or page
                    869:                                 * fault.
                    870:                                 * Get the pte and check the status of the
                    871:                                 * modified and valid bits to determine if this
                    872:                                 * indeed a real write fault.  XXX smurph
                    873:                                 */
                    874:                                pte = pmap_pte(vm_map_pmap(map), va);
                    875: #ifdef DEBUG
                    876:                                if (pte == NULL) {
                    877:                                        KERNEL_PROC_UNLOCK(p);
                    878:                                        panic("NULL pte on write fault??");
                    879:                                }
                    880: #endif
                    881:                                if (!(*pte & PG_M) && !(*pte & PG_RO)) {
                    882:                                        /*
                    883:                                         * Set modified bit and try the
                    884:                                         * write again.
                    885:                                         */
                    886: #ifdef TRAPDEBUG
                    887:                                        printf("Corrected userland write fault, map %x pte %x\n",
                    888:                                            map->pmap, *pte);
                    889: #endif
                    890:                                        *pte |= PG_M;
                    891:                                        /*
                    892:                                         * invalidate ATCs to force
                    893:                                         * table search
                    894:                                         */
                    895:                                        set_dcmd(CMMU_DCMD_INV_UATC);
                    896:                                        KERNEL_PROC_UNLOCK(p);
                    897:                                        return;
                    898:                                } else {
                    899:                                        /* must be a real wp fault */
                    900: #ifdef TRAPDEBUG
                    901:                                        printf("Uncorrected userland write fault, map %x pte %x\n",
                    902:                                            map->pmap, *pte);
                    903: #endif
                    904:                                        result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    905:                                        p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    906:                                }
                    907:                        } else {
                    908: #ifdef TRAPDEBUG
                    909:                                printf("Unexpected Data access fault dsr %x\n",
                    910:                                    frame->tf_dsr);
                    911: #endif
                    912:                                KERNEL_PROC_UNLOCK(p);
                    913:                                panictrap(frame->tf_vector, frame);
                    914:                        }
                    915:                } else {
                    916:                        /* instruction faults */
                    917:                        if (frame->tf_isr &
                    918:                            (CMMU_ISR_BE | CMMU_ISR_SP | CMMU_ISR_TBE)) {
                    919:                                /* bus error, supervisor protection */
                    920:                                result = EACCES;
                    921:                        } else
                    922:                        if (frame->tf_isr & (CMMU_ISR_SI | CMMU_ISR_PI)) {
                    923:                                /* segment or page fault */
                    924:                                result = uvm_fault(map, va, VM_FAULT_INVALID, ftype);
                    925:                                p->p_addr->u_pcb.pcb_onfault = pcb_onfault;
                    926:                        } else {
                    927: #ifdef TRAPDEBUG
                    928:                                printf("Unexpected Instruction fault isr %x\n",
                    929:                                    frame->tf_isr);
                    930: #endif
                    931:                                KERNEL_PROC_UNLOCK(p);
                    932:                                panictrap(frame->tf_vector, frame);
                    933:                        }
                    934:                }
                    935:
                    936:                if ((caddr_t)va >= vm->vm_maxsaddr) {
                    937:                        if (result == 0)
                    938:                                uvm_grow(p, va);
                    939:                        else if (result == EACCES)
                    940:                                result = EFAULT;
                    941:                }
                    942:                KERNEL_PROC_UNLOCK(p);
                    943:
                    944:                /*
                    945:                 * This could be a fault caused in copyin*()
                    946:                 * while accessing user space.
                    947:                 */
                    948:                if (result != 0 && pcb_onfault != 0) {
                    949:                        frame->tf_exip = pcb_onfault;
                    950:                        /*
                    951:                         * Continue as if the fault had been resolved.
                    952:                         */
                    953:                        result = 0;
                    954:                }
                    955:
                    956:                if (result != 0) {
                    957:                        sig = result == EACCES ? SIGBUS : SIGSEGV;
                    958:                        fault_type = result == EACCES ?
                    959:                            BUS_ADRERR : SEGV_MAPERR;
                    960:                }
                    961:                break;
                    962:        case T_MISALGNFLT+T_USER:
                    963:                /* Fix any misaligned ld.d or st.d instructions */
                    964:                sig = double_reg_fixup(frame);
                    965:                fault_type = BUS_ADRALN;
                    966:                break;
                    967:        case T_PRIVINFLT+T_USER:
                    968:        case T_ILLFLT+T_USER:
                    969: #ifndef DDB
                    970:        case T_KDB_BREAK:
                    971:        case T_KDB_ENTRY:
                    972:        case T_KDB_TRACE:
                    973: #endif
                    974:        case T_KDB_BREAK+T_USER:
                    975:        case T_KDB_ENTRY+T_USER:
                    976:        case T_KDB_TRACE+T_USER:
                    977:                sig = SIGILL;
                    978:                break;
                    979:        case T_BNDFLT+T_USER:
                    980:                sig = SIGFPE;
                    981:                break;
                    982:        case T_ZERODIV+T_USER:
                    983:                sig = SIGFPE;
                    984:                fault_type = FPE_INTDIV;
                    985:                break;
                    986:        case T_OVFFLT+T_USER:
                    987:                sig = SIGFPE;
                    988:                fault_type = FPE_INTOVF;
                    989:                break;
                    990:        case T_FPEPFLT+T_USER:
                    991:                sig = SIGFPE;
                    992:                break;
                    993:        case T_SIGSYS+T_USER:
                    994:                sig = SIGSYS;
                    995:                break;
                    996:        case T_STEPBPT+T_USER:
                    997: #ifdef PTRACE
                    998:                /*
                    999:                 * This trap is used by the kernel to support single-step
                   1000:                 * debugging (although any user could generate this trap
                   1001:                 * which should probably be handled differently). When a
                   1002:                 * process is continued by a debugger with the PT_STEP
                   1003:                 * function of ptrace (single step), the kernel inserts
                   1004:                 * one or two breakpoints in the user process so that only
                   1005:                 * one instruction (or two in the case of a delayed branch)
                   1006:                 * is executed.  When this breakpoint is hit, we get the
                   1007:                 * T_STEPBPT trap.
                   1008:                 */
                   1009:                {
                   1010:                        u_int instr;
                   1011:                        vaddr_t pc = PC_REGS(&frame->tf_regs);
                   1012:
                   1013:                        /* read break instruction */
                   1014:                        copyin((caddr_t)pc, &instr, sizeof(u_int));
                   1015:
                   1016:                        /* check and see if we got here by accident */
                   1017:                        if ((p->p_md.md_bp0va != pc &&
                   1018:                             p->p_md.md_bp1va != pc) ||
                   1019:                            instr != SSBREAKPOINT) {
                   1020:                                sig = SIGTRAP;
                   1021:                                fault_type = TRAP_TRACE;
                   1022:                                break;
                   1023:                        }
                   1024:
                   1025:                        /* restore original instruction and clear breakpoint */
                   1026:                        if (p->p_md.md_bp0va == pc) {
                   1027:                                ss_put_value(p, pc, p->p_md.md_bp0save);
                   1028:                                p->p_md.md_bp0va = 0;
                   1029:                        }
                   1030:                        if (p->p_md.md_bp1va == pc) {
                   1031:                                ss_put_value(p, pc, p->p_md.md_bp1save);
                   1032:                                p->p_md.md_bp1va = 0;
                   1033:                        }
                   1034:
                   1035:                        sig = SIGTRAP;
                   1036:                        fault_type = TRAP_BRKPT;
                   1037:                }
                   1038: #else
                   1039:                sig = SIGTRAP;
                   1040:                fault_type = TRAP_TRACE;
                   1041: #endif
                   1042:                break;
                   1043:        case T_USERBPT+T_USER:
                   1044:                /*
                   1045:                 * This trap is meant to be used by debuggers to implement
                   1046:                 * breakpoint debugging.  When we get this trap, we just
                   1047:                 * return a signal which gets caught by the debugger.
                   1048:                 */
                   1049:                sig = SIGTRAP;
                   1050:                fault_type = TRAP_BRKPT;
                   1051:                break;
                   1052:
                   1053:        case T_ASTFLT+T_USER:
                   1054:                uvmexp.softs++;
                   1055:                p->p_md.md_astpending = 0;
                   1056:                if (p->p_flag & P_OWEUPC) {
                   1057:                        KERNEL_PROC_LOCK(p);
                   1058:                        ADDUPROF(p);
                   1059:                        KERNEL_PROC_UNLOCK(p);
                   1060:                }
                   1061:                if (curcpu()->ci_want_resched)
                   1062:                        preempt(NULL);
                   1063:                break;
                   1064:        }
                   1065:
                   1066:        /*
                   1067:         * If trap from supervisor mode, just return
                   1068:         */
                   1069:        if (type < T_USER)
                   1070:                return;
                   1071:
                   1072:        if (sig) {
                   1073:                sv.sival_int = fault_addr;
                   1074:                KERNEL_PROC_LOCK(p);
                   1075:                trapsignal(p, sig, fault_code, fault_type, sv);
                   1076:                KERNEL_PROC_UNLOCK(p);
                   1077:        }
                   1078:
                   1079:        userret(p);
                   1080: }
                   1081: #endif /* M88110 */
                   1082:
                   1083: __dead void
                   1084: error_fatal(struct trapframe *frame)
                   1085: {
                   1086:        if (frame->tf_vector == 0)
                   1087:                printf("\nCPU %d Reset Exception\n", cpu_number());
                   1088:        else
                   1089:                printf("\nCPU %d Error Exception\n", cpu_number());
                   1090:
                   1091: #ifdef DDB
                   1092:        regdump((struct trapframe*)frame);
                   1093: #endif
                   1094:        panic("unrecoverable exception %d", frame->tf_vector);
                   1095: }
                   1096:
                   1097: #ifdef M88100
                   1098: void
                   1099: m88100_syscall(register_t code, struct trapframe *tf)
                   1100: {
                   1101:        int i, nsys, nap;
                   1102:        struct sysent *callp;
                   1103:        struct proc *p;
                   1104:        int error;
                   1105:        register_t args[8], rval[2], *ap;
                   1106:
                   1107:        uvmexp.syscalls++;
                   1108:
                   1109:        p = curproc;
                   1110:
                   1111:        callp = p->p_emul->e_sysent;
                   1112:        nsys  = p->p_emul->e_nsysent;
                   1113:
                   1114:        p->p_md.md_tf = tf;
                   1115:
                   1116:        /*
                   1117:         * For 88k, all the arguments are passed in the registers (r2-r9),
                   1118:         * and further arguments (if any) on stack.
                   1119:         * For syscall (and __syscall), r2 (and r3) has the actual code.
                   1120:         * __syscall  takes a quad syscall number, so that other
                   1121:         * arguments are at their natural alignments.
                   1122:         */
                   1123:        ap = &tf->tf_r[2];
                   1124:        nap = 8; /* r2-r9 */
                   1125:
                   1126:        switch (code) {
                   1127:        case SYS_syscall:
                   1128:                code = *ap++;
                   1129:                nap--;
                   1130:                break;
                   1131:        case SYS___syscall:
                   1132:                if (callp != sysent)
                   1133:                        break;
                   1134:                code = ap[_QUAD_LOWWORD];
                   1135:                ap += 2;
                   1136:                nap -= 2;
                   1137:                break;
                   1138:        }
                   1139:
                   1140:        if (code < 0 || code >= nsys)
                   1141:                callp += p->p_emul->e_nosys;
                   1142:        else
                   1143:                callp += code;
                   1144:
                   1145:        i = callp->sy_argsize / sizeof(register_t);
                   1146:        if (i > sizeof(args) / sizeof(register_t))
                   1147:                panic("syscall nargs");
                   1148:        if (i > nap) {
                   1149:                bcopy((caddr_t)ap, (caddr_t)args, nap * sizeof(register_t));
                   1150:                error = copyin((caddr_t)tf->tf_r[31], (caddr_t)(args + nap),
                   1151:                    (i - nap) * sizeof(register_t));
                   1152:        } else {
                   1153:                bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
                   1154:                error = 0;
                   1155:        }
                   1156:
                   1157:        if (error != 0)
                   1158:                goto bad;
                   1159:        KERNEL_PROC_LOCK(p);
                   1160: #ifdef SYSCALL_DEBUG
                   1161:        scdebug_call(p, code, args);
                   1162: #endif
                   1163: #ifdef KTRACE
                   1164:        if (KTRPOINT(p, KTR_SYSCALL))
                   1165:                ktrsyscall(p, code, callp->sy_argsize, args);
                   1166: #endif
                   1167:        rval[0] = 0;
                   1168:        rval[1] = tf->tf_r[3];
                   1169: #if NSYSTRACE > 0
                   1170:        if (ISSET(p->p_flag, P_SYSTRACE))
                   1171:                error = systrace_redirect(code, p, args, rval);
                   1172:        else
                   1173: #endif
                   1174:                error = (*callp->sy_call)(p, args, rval);
                   1175:        /*
                   1176:         * system call will look like:
                   1177:         *       or r13, r0, <code>
                   1178:         *       tb0 0, r0, <128> <- sxip
                   1179:         *       br err           <- snip
                   1180:         *       jmp r1           <- sfip
                   1181:         *  err: or.u r3, r0, hi16(errno)
                   1182:         *       st r2, r3, lo16(errno)
                   1183:         *       subu r2, r0, 1
                   1184:         *       jmp r1
                   1185:         *
                   1186:         * So, when we take syscall trap, sxip/snip/sfip will be as
                   1187:         * shown above.
                   1188:         * Given this,
                   1189:         * 1. If the system call returned 0, need to skip nip.
                   1190:         *      nip = fip, fip += 4
                   1191:         *    (doesn't matter what fip + 4 will be but we will never
                   1192:         *    execute this since jmp r1 at nip will change the execution flow.)
                   1193:         * 2. If the system call returned an errno > 0, plug the value
                   1194:         *    in r2, and leave nip and fip unchanged. This will have us
                   1195:         *    executing "br err" on return to user space.
                   1196:         * 3. If the system call code returned ERESTART,
                   1197:         *    we need to rexecute the trap instruction. Back up the pipe
                   1198:         *    line.
                   1199:         *     fip = nip, nip = xip
                   1200:         * 4. If the system call returned EJUSTRETURN, don't need to adjust
                   1201:         *    any pointers.
                   1202:         */
                   1203:
                   1204:        KERNEL_PROC_UNLOCK(p);
                   1205:        switch (error) {
                   1206:        case 0:
                   1207:                tf->tf_r[2] = rval[0];
                   1208:                tf->tf_r[3] = rval[1];
                   1209:                tf->tf_epsr &= ~PSR_C;
                   1210:                tf->tf_snip = tf->tf_sfip & ~NIP_E;
                   1211:                tf->tf_sfip = tf->tf_snip + 4;
                   1212:                break;
                   1213:        case ERESTART:
                   1214:                tf->tf_epsr &= ~PSR_C;
                   1215:                tf->tf_sfip = tf->tf_snip & ~FIP_E;
                   1216:                tf->tf_snip = tf->tf_sxip & ~NIP_E;
                   1217:                break;
                   1218:        case EJUSTRETURN:
                   1219:                tf->tf_epsr &= ~PSR_C;
                   1220:                break;
                   1221:        default:
                   1222: bad:
                   1223:                if (p->p_emul->e_errno)
                   1224:                        error = p->p_emul->e_errno[error];
                   1225:                tf->tf_r[2] = error;
                   1226:                tf->tf_epsr |= PSR_C;   /* fail */
                   1227:                tf->tf_snip = tf->tf_snip & ~NIP_E;
                   1228:                tf->tf_sfip = tf->tf_sfip & ~FIP_E;
                   1229:                break;
                   1230:        }
                   1231: #ifdef SYSCALL_DEBUG
                   1232:        KERNEL_PROC_LOCK(p);
                   1233:        scdebug_ret(p, code, error, rval);
                   1234:        KERNEL_PROC_UNLOCK(p);
                   1235: #endif
                   1236:        userret(p);
                   1237: #ifdef KTRACE
                   1238:        if (KTRPOINT(p, KTR_SYSRET)) {
                   1239:                KERNEL_PROC_LOCK(p);
                   1240:                ktrsysret(p, code, error, rval[0]);
                   1241:                KERNEL_PROC_UNLOCK(p);
                   1242:        }
                   1243: #endif
                   1244: }
                   1245: #endif /* M88100 */
                   1246:
                   1247: #ifdef M88110
                   1248: /* Instruction pointers operate differently on mc88110 */
                   1249: void
                   1250: m88110_syscall(register_t code, struct trapframe *tf)
                   1251: {
                   1252:        int i, nsys, nap;
                   1253:        struct sysent *callp;
                   1254:        struct proc *p;
                   1255:        int error;
                   1256:        register_t args[8], rval[2], *ap;
                   1257:
                   1258:        uvmexp.syscalls++;
                   1259:
                   1260:        p = curproc;
                   1261:
                   1262:        callp = p->p_emul->e_sysent;
                   1263:        nsys  = p->p_emul->e_nsysent;
                   1264:
                   1265:        p->p_md.md_tf = tf;
                   1266:
                   1267:        /*
                   1268:         * For 88k, all the arguments are passed in the registers (r2-r9),
                   1269:         * and further arguments (if any) on stack.
                   1270:         * For syscall (and __syscall), r2 (and r3) has the actual code.
                   1271:         * __syscall  takes a quad syscall number, so that other
                   1272:         * arguments are at their natural alignments.
                   1273:         */
                   1274:        ap = &tf->tf_r[2];
                   1275:        nap = 8;        /* r2-r9 */
                   1276:
                   1277:        switch (code) {
                   1278:        case SYS_syscall:
                   1279:                code = *ap++;
                   1280:                nap--;
                   1281:                break;
                   1282:        case SYS___syscall:
                   1283:                if (callp != sysent)
                   1284:                        break;
                   1285:                code = ap[_QUAD_LOWWORD];
                   1286:                ap += 2;
                   1287:                nap -= 2;
                   1288:                break;
                   1289:        }
                   1290:
                   1291:        if (code < 0 || code >= nsys)
                   1292:                callp += p->p_emul->e_nosys;
                   1293:        else
                   1294:                callp += code;
                   1295:
                   1296:        i = callp->sy_argsize / sizeof(register_t);
                   1297:        if (i > sizeof(args) > sizeof(register_t))
                   1298:                panic("syscall nargs");
                   1299:        if (i > nap) {
                   1300:                bcopy((caddr_t)ap, (caddr_t)args, nap * sizeof(register_t));
                   1301:                error = copyin((caddr_t)tf->tf_r[31], (caddr_t)(args + nap),
                   1302:                    (i - nap) * sizeof(register_t));
                   1303:        } else {
                   1304:                bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
                   1305:                error = 0;
                   1306:        }
                   1307:
                   1308:        if (error != 0)
                   1309:                goto bad;
                   1310:        KERNEL_PROC_LOCK(p);
                   1311: #ifdef SYSCALL_DEBUG
                   1312:        scdebug_call(p, code, args);
                   1313: #endif
                   1314: #ifdef KTRACE
                   1315:        if (KTRPOINT(p, KTR_SYSCALL))
                   1316:                ktrsyscall(p, code, callp->sy_argsize, args);
                   1317: #endif
                   1318:        rval[0] = 0;
                   1319:        rval[1] = tf->tf_r[3];
                   1320: #if NSYSTRACE > 0
                   1321:        if (ISSET(p->p_flag, P_SYSTRACE))
                   1322:                error = systrace_redirect(code, p, args, rval);
                   1323:        else
                   1324: #endif
                   1325:                error = (*callp->sy_call)(p, args, rval);
                   1326:        /*
                   1327:         * system call will look like:
                   1328:         *       or r13, r0, <code>
                   1329:         *       tb0 0, r0, <128> <- exip
                   1330:         *       br err           <- enip
                   1331:         *       jmp r1
                   1332:         *  err: or.u r3, r0, hi16(errno)
                   1333:         *       st r2, r3, lo16(errno)
                   1334:         *       subu r2, r0, 1
                   1335:         *       jmp r1
                   1336:         *
                   1337:         * So, when we take syscall trap, exip/enip will be as
                   1338:         * shown above.
                   1339:         * Given this,
                   1340:         * 1. If the system call returned 0, need to jmp r1.
                   1341:         *    exip += 8
                   1342:         * 2. If the system call returned an errno > 0, increment
                   1343:         *    exip += 4 and plug the value in r2. This will have us
                   1344:         *    executing "br err" on return to user space.
                   1345:         * 3. If the system call code returned ERESTART,
                   1346:         *    we need to rexecute the trap instruction. leave exip as is.
                   1347:         * 4. If the system call returned EJUSTRETURN, just return.
                   1348:         *    exip += 4
                   1349:         */
                   1350:
                   1351:        KERNEL_PROC_UNLOCK(p);
                   1352:        switch (error) {
                   1353:        case 0:
                   1354:                tf->tf_r[2] = rval[0];
                   1355:                tf->tf_r[3] = rval[1];
                   1356:                tf->tf_epsr &= ~PSR_C;
                   1357:                /* skip two instructions */
                   1358:                if (tf->tf_exip & 1)
                   1359:                        tf->tf_exip = tf->tf_enip + 4;
                   1360:                else
                   1361:                        tf->tf_exip += 4 + 4;
                   1362:                break;
                   1363:        case ERESTART:
                   1364:                /*
                   1365:                 * Reexecute the trap.
                   1366:                 * exip is already at the trap instruction, so
                   1367:                 * there is nothing to do.
                   1368:                 */
                   1369:                tf->tf_epsr &= ~PSR_C;
                   1370:                break;
                   1371:        case EJUSTRETURN:
                   1372:                tf->tf_epsr &= ~PSR_C;
                   1373:                /* skip one instruction */
                   1374:                if (tf->tf_exip & 1)
                   1375:                        tf->tf_exip = tf->tf_enip;
                   1376:                else
                   1377:                        tf->tf_exip += 4;
                   1378:                break;
                   1379:        default:
                   1380: bad:
                   1381:                if (p->p_emul->e_errno)
                   1382:                        error = p->p_emul->e_errno[error];
                   1383:                tf->tf_r[2] = error;
                   1384:                tf->tf_epsr |= PSR_C;   /* fail */
                   1385:                /* skip one instruction */
                   1386:                if (tf->tf_exip & 1)
                   1387:                        tf->tf_exip = tf->tf_enip;
                   1388:                else
                   1389:                        tf->tf_exip += 4;
                   1390:                break;
                   1391:        }
                   1392:
                   1393: #ifdef SYSCALL_DEBUG
                   1394:        KERNEL_PROC_LOCK(p);
                   1395:        scdebug_ret(p, code, error, rval);
                   1396:        KERNEL_PROC_UNLOCK(p);
                   1397: #endif
                   1398:        userret(p);
                   1399: #ifdef KTRACE
                   1400:        if (KTRPOINT(p, KTR_SYSRET)) {
                   1401:                KERNEL_PROC_LOCK(p);
                   1402:                ktrsysret(p, code, error, rval[0]);
                   1403:                KERNEL_PROC_UNLOCK(p);
                   1404:        }
                   1405: #endif
                   1406: }
                   1407: #endif /* M88110 */
                   1408:
                   1409: /*
                   1410:  * Set up return-value registers as fork() libc stub expects,
                   1411:  * and do normal return-to-user-mode stuff.
                   1412:  */
                   1413: void
                   1414: child_return(arg)
                   1415:        void *arg;
                   1416: {
                   1417:        struct proc *p = arg;
                   1418:        struct trapframe *tf;
                   1419:
                   1420:        tf = (struct trapframe *)USER_REGS(p);
                   1421:        tf->tf_r[2] = 0;
                   1422:        tf->tf_r[3] = 0;
                   1423:        tf->tf_epsr &= ~PSR_C;
                   1424:        /* skip br instruction as in syscall() */
                   1425: #ifdef M88100
                   1426:        if (CPU_IS88100) {
                   1427:                tf->tf_snip = tf->tf_sfip & XIP_ADDR;
                   1428:                tf->tf_sfip = tf->tf_snip + 4;
                   1429:        }
                   1430: #endif
                   1431: #ifdef M88110
                   1432:        if (CPU_IS88110) {
                   1433:                /* skip two instructions */
                   1434:                if (tf->tf_exip & 1)
                   1435:                        tf->tf_exip = tf->tf_enip + 4;
                   1436:                else
                   1437:                        tf->tf_exip += 4 + 4;
                   1438:        }
                   1439: #endif
                   1440:
                   1441:        KERNEL_PROC_UNLOCK(p);
                   1442:        userret(p);
                   1443:
                   1444: #ifdef KTRACE
                   1445:        if (KTRPOINT(p, KTR_SYSRET)) {
                   1446:                KERNEL_PROC_LOCK(p);
                   1447:                ktrsysret(p,
                   1448:                    (p->p_flag & P_PPWAIT) ? SYS_vfork : SYS_fork, 0, 0);
                   1449:                KERNEL_PROC_UNLOCK(p);
                   1450:        }
                   1451: #endif
                   1452: }
                   1453:
                   1454: #ifdef PTRACE
                   1455:
                   1456: /*
                   1457:  * User Single Step Debugging Support
                   1458:  */
                   1459:
                   1460: #include <sys/ptrace.h>
                   1461:
                   1462: vaddr_t        ss_branch_taken(u_int, vaddr_t, struct reg *);
                   1463: int    ss_get_value(struct proc *, vaddr_t, u_int *);
                   1464: int    ss_inst_branch_or_call(u_int);
                   1465: int    ss_put_breakpoint(struct proc *, vaddr_t, vaddr_t *, u_int *);
                   1466:
                   1467: #define        SYSCALL_INSTR   0xf000d080      /* tb0 0,r0,128 */
                   1468:
                   1469: int
                   1470: ss_get_value(struct proc *p, vaddr_t addr, u_int *value)
                   1471: {
                   1472:        struct uio uio;
                   1473:        struct iovec iov;
                   1474:
                   1475:        iov.iov_base = (caddr_t)value;
                   1476:        iov.iov_len = sizeof(u_int);
                   1477:        uio.uio_iov = &iov;
                   1478:        uio.uio_iovcnt = 1;
                   1479:        uio.uio_offset = (off_t)addr;
                   1480:        uio.uio_resid = sizeof(u_int);
                   1481:        uio.uio_segflg = UIO_SYSSPACE;
                   1482:        uio.uio_rw = UIO_READ;
                   1483:        uio.uio_procp = curproc;
                   1484:        return (process_domem(curproc, p, &uio, PT_READ_I));
                   1485: }
                   1486:
                   1487: int
                   1488: ss_put_value(struct proc *p, vaddr_t addr, u_int value)
                   1489: {
                   1490:        struct uio uio;
                   1491:        struct iovec iov;
                   1492:
                   1493:        iov.iov_base = (caddr_t)&value;
                   1494:        iov.iov_len = sizeof(u_int);
                   1495:        uio.uio_iov = &iov;
                   1496:        uio.uio_iovcnt = 1;
                   1497:        uio.uio_offset = (off_t)addr;
                   1498:        uio.uio_resid = sizeof(u_int);
                   1499:        uio.uio_segflg = UIO_SYSSPACE;
                   1500:        uio.uio_rw = UIO_WRITE;
                   1501:        uio.uio_procp = curproc;
                   1502:        return (process_domem(curproc, p, &uio, PT_WRITE_I));
                   1503: }
                   1504:
                   1505: /*
                   1506:  * ss_branch_taken(instruction, pc, regs)
                   1507:  *
                   1508:  * instruction will be a control flow instruction location at address pc.
                   1509:  * Branch taken is supposed to return the address to which the instruction
                   1510:  * would jump if the branch is taken.
                   1511:  *
                   1512:  * This is different from branch_taken() in ddb, as we also need to process
                   1513:  * system calls.
                   1514:  */
                   1515: vaddr_t
                   1516: ss_branch_taken(u_int inst, vaddr_t pc, struct reg *regs)
                   1517: {
                   1518:        u_int regno;
                   1519:
                   1520:        /*
                   1521:         * Quick check of the instruction. Note that we know we are only
                   1522:         * invoked if ss_inst_branch_or_call() returns TRUE, so we do not
                   1523:         * need to repeat the jpm, jsr and syscall stricter checks here.
                   1524:         */
                   1525:        switch (inst >> (32 - 5)) {
                   1526:        case 0x18:      /* br */
                   1527:        case 0x19:      /* bsr */
                   1528:                /* signed 26 bit pc relative displacement, shift left 2 bits */
                   1529:                inst = (inst & 0x03ffffff) << 2;
                   1530:                /* check if sign extension is needed */
                   1531:                if (inst & 0x08000000)
                   1532:                        inst |= 0xf0000000;
                   1533:                return (pc + inst);
                   1534:
                   1535:        case 0x1a:      /* bb0 */
                   1536:        case 0x1b:      /* bb1 */
                   1537:        case 0x1d:      /* bcnd */
                   1538:                /* signed 16 bit pc relative displacement, shift left 2 bits */
                   1539:                inst = (inst & 0x0000ffff) << 2;
                   1540:                /* check if sign extension is needed */
                   1541:                if (inst & 0x00020000)
                   1542:                        inst |= 0xfffc0000;
                   1543:                return (pc + inst);
                   1544:
                   1545:        case 0x1e:      /* jmp or jsr */
                   1546:                regno = inst & 0x1f;    /* get the register value */
                   1547:                return (regno == 0 ? 0 : regs->r[regno]);
                   1548:
                   1549:        default:        /* system call */
                   1550:                /*
                   1551:                 * The regular (pc + 4) breakpoint will match the error
                   1552:                 * return. Successfull system calls return at (pc + 8),
                   1553:                 * so we'll set up a branch breakpoint there.
                   1554:                 */
                   1555:                return (pc + 8);
                   1556:        }
                   1557: }
                   1558:
                   1559: int
                   1560: ss_inst_branch_or_call(u_int ins)
                   1561: {
                   1562:        /* check high five bits */
                   1563:        switch (ins >> (32 - 5)) {
                   1564:        case 0x18: /* br */
                   1565:        case 0x19: /* bsr */
                   1566:        case 0x1a: /* bb0 */
                   1567:        case 0x1b: /* bb1 */
                   1568:        case 0x1d: /* bcnd */
                   1569:                return (TRUE);
                   1570:        case 0x1e: /* could be jmp or jsr */
                   1571:                if ((ins & 0xfffff3e0) == 0xf400c000)
                   1572:                        return (TRUE);
                   1573:        }
                   1574:
                   1575:        return (FALSE);
                   1576: }
                   1577:
                   1578: int
                   1579: ss_put_breakpoint(struct proc *p, vaddr_t va, vaddr_t *bpva, u_int *bpsave)
                   1580: {
                   1581:        int rc;
                   1582:
                   1583:        /* Restore previous breakpoint if we did not trigger it. */
                   1584:        if (*bpva != 0) {
                   1585:                ss_put_value(p, *bpva, *bpsave);
                   1586:                *bpva = 0;
                   1587:        }
                   1588:
                   1589:        /* Save instruction. */
                   1590:        if ((rc = ss_get_value(p, va, bpsave)) != 0)
                   1591:                return (rc);
                   1592:
                   1593:        /* Store breakpoint instruction at the location now. */
                   1594:        *bpva = va;
                   1595:        return (ss_put_value(p, va, SSBREAKPOINT));
                   1596: }
                   1597:
                   1598: int
                   1599: process_sstep(struct proc *p, int sstep)
                   1600: {
                   1601:        struct reg *sstf = USER_REGS(p);
                   1602:        unsigned pc, brpc;
                   1603:        unsigned instr;
                   1604:        int rc;
                   1605:
                   1606:        if (sstep == 0) {
                   1607:                /* Restore previous breakpoints if any. */
                   1608:                if (p->p_md.md_bp0va != 0) {
                   1609:                        ss_put_value(p, p->p_md.md_bp0va, p->p_md.md_bp0save);
                   1610:                        p->p_md.md_bp0va = 0;
                   1611:                }
                   1612:                if (p->p_md.md_bp1va != 0) {
                   1613:                        ss_put_value(p, p->p_md.md_bp1va, p->p_md.md_bp1save);
                   1614:                        p->p_md.md_bp1va = 0;
                   1615:                }
                   1616:
                   1617:                return (0);
                   1618:        }
                   1619:
                   1620:        /*
                   1621:         * User was stopped at pc, e.g. the instruction at pc was not executed.
                   1622:         * Fetch what's at the current location.
                   1623:         */
                   1624:        pc = PC_REGS(sstf);
                   1625:        if ((rc = ss_get_value(p, pc, &instr)) != 0)
                   1626:                return (rc);
                   1627:
                   1628:        /*
                   1629:         * Find if this instruction may cause a branch, and set up a breakpoint
                   1630:         * at the branch location.
                   1631:         */
                   1632:        if (ss_inst_branch_or_call(instr) || instr == SYSCALL_INSTR) {
                   1633:                brpc = ss_branch_taken(instr, pc, sstf);
                   1634:
                   1635:                /* self-branches are hopeless */
                   1636:                if (brpc != pc && brpc != 0) {
                   1637:                        if ((rc = ss_put_breakpoint(p, brpc,
                   1638:                            &p->p_md.md_bp1va, &p->p_md.md_bp1save)) != 0)
                   1639:                                return (rc);
                   1640:                }
                   1641:        }
                   1642:
                   1643:        if ((rc = ss_put_breakpoint(p, pc + 4,
                   1644:            &p->p_md.md_bp0va, &p->p_md.md_bp0save)) != 0)
                   1645:                return (rc);
                   1646:
                   1647:        return (0);
                   1648: }
                   1649:
                   1650: #endif /* PTRACE */
                   1651:
                   1652: #ifdef DIAGNOSTIC
                   1653: void
                   1654: splassert_check(int wantipl, const char *func)
                   1655: {
                   1656:        int oldipl;
                   1657:
                   1658:        /*
                   1659:         * This will raise the spl if too low,
                   1660:         * in a feeble attempt to reduce further damage.
                   1661:         */
                   1662:        oldipl = raiseipl(wantipl);
                   1663:
                   1664:        if (oldipl < wantipl) {
                   1665:                splassert_fail(wantipl, oldipl, func);
                   1666:        }
                   1667: }
                   1668: #endif
                   1669:
                   1670: /*
                   1671:  * ld.d and st.d instructions referencing long aligned but not long long
                   1672:  * aligned addresses will trigger a misaligned address exception.
                   1673:  *
                   1674:  * This routine attempts to recover these (valid) statements, by simulating
                   1675:  * the split form of the instruction. If it fails, it returns the appropriate
                   1676:  * signal number to deliver.
                   1677:  *
                   1678:  * Note that we do not attempt to do anything for .d.usr instructions - the
                   1679:  * kernel never issues such instructions, and they cause a privileged
                   1680:  * isntruction exception from userland.
                   1681:  */
                   1682: int
                   1683: double_reg_fixup(struct trapframe *frame)
                   1684: {
                   1685:        u_int32_t pc, instr, value;
                   1686:        int regno, store;
                   1687:        vaddr_t addr;
                   1688:
                   1689:        /*
                   1690:         * Decode the faulting instruction.
                   1691:         */
                   1692:
                   1693:        pc = PC_REGS(&frame->tf_regs);
                   1694:        if (copyin((void *)pc, &instr, sizeof(u_int32_t)) != 0)
                   1695:                return SIGSEGV;
                   1696:
                   1697:        switch (instr & 0xfc00ff00) {
                   1698:        case 0xf4001000:        /* ld.d rD, rS1, rS2 */
                   1699:                addr = frame->tf_r[(instr >> 16) & 0x1f]
                   1700:                    + frame->tf_r[(instr & 0x1f)];
                   1701:                store = 0;
                   1702:                break;
                   1703:        case 0xf4002000:        /* st.d rD, rS1, rS2 */
                   1704:                addr = frame->tf_r[(instr >> 16) & 0x1f]
                   1705:                    + frame->tf_r[(instr & 0x1f)];
                   1706:                store = 1;
                   1707:                break;
                   1708:        default:
                   1709:                switch (instr & 0xfc000000) {
                   1710:                case 0x10000000:        /* ld.d rD, rS, imm16 */
                   1711:                        addr = (instr & 0x0000ffff) +
                   1712:                            frame->tf_r[(instr >> 16) & 0x1f];
                   1713:                        store = 0;
                   1714:                        break;
                   1715:                case 0x20000000:        /* st.d rD, rS, imm16 */
                   1716:                        addr = (instr & 0x0000ffff) +
                   1717:                            frame->tf_r[(instr >> 16) & 0x1f];
                   1718:                        store = 1;
                   1719:                        break;
                   1720:                default:
                   1721:                        return SIGBUS;
                   1722:                }
                   1723:                break;
                   1724:        }
                   1725:
                   1726:        /* We only handle long but not long long aligned access here */
                   1727:        if ((addr & 0x07) != 4)
                   1728:                return SIGBUS;
                   1729:
                   1730:        regno = (instr >> 21) & 0x1f;
                   1731:
                   1732:        if (store) {
                   1733:                /*
                   1734:                 * Two word stores.
                   1735:                 */
                   1736:                value = frame->tf_r[regno++];
                   1737:                if (copyout(&value, (void *)addr, sizeof(u_int32_t)) != 0)
                   1738:                        return SIGSEGV;
                   1739:                if (regno == 32)
                   1740:                        value = 0;
                   1741:                else
                   1742:                        value = frame->tf_r[regno];
                   1743:                if (copyout(&value, (void *)(addr + 4), sizeof(u_int32_t)) != 0)
                   1744:                        return SIGSEGV;
                   1745:        } else {
                   1746:                /*
                   1747:                 * Two word loads. r0 should be left unaltered, but the
                   1748:                 * value should still be fetched even if it is discarded.
                   1749:                 */
                   1750:                if (copyin((void *)addr, &value, sizeof(u_int32_t)) != 0)
                   1751:                        return SIGSEGV;
                   1752:                if (regno != 0)
                   1753:                        frame->tf_r[regno] = value;
                   1754:                if (copyin((void *)(addr + 4), &value, sizeof(u_int32_t)) != 0)
                   1755:                        return SIGSEGV;
                   1756:                if (regno != 31)
                   1757:                        frame->tf_r[regno + 1] = value;
                   1758:        }
                   1759:
                   1760:        return 0;
                   1761: }
                   1762:
                   1763: void
                   1764: cache_flush(struct trapframe *tf)
                   1765: {
                   1766:        struct proc *p;
                   1767:        struct pmap *pmap;
                   1768:        paddr_t pa;
                   1769:        vaddr_t va;
                   1770:        vsize_t len, count;
                   1771:
                   1772:        if ((p = curproc) == NULL)
                   1773:                p = &proc0;
                   1774:
                   1775:        p->p_md.md_tf = tf;
                   1776:
                   1777:        pmap = vm_map_pmap(&p->p_vmspace->vm_map);
                   1778:        va = tf->tf_r[2];
                   1779:        len = tf->tf_r[3];
                   1780:
                   1781:        if (/* va < VM_MIN_ADDRESS || */ va >= VM_MAXUSER_ADDRESS ||
                   1782:            va + len <= va || va + len >= VM_MAXUSER_ADDRESS)
                   1783:                len = 0;
                   1784:
                   1785:        while (len != 0) {
                   1786:                count = min(len, PAGE_SIZE - (va & PAGE_MASK));
                   1787:                if (pmap_extract(pmap, va, &pa) != FALSE)
                   1788:                        dma_cachectl_pa(pa, count, DMA_CACHE_SYNC);
                   1789:                va += count;
                   1790:                len -= count;
                   1791:        }
                   1792:
                   1793:        if (CPU_IS88100) {
                   1794:                tf->tf_snip = tf->tf_snip & ~NIP_E;
                   1795:                tf->tf_sfip = tf->tf_sfip & ~FIP_E;
                   1796:        } else {
                   1797:                /* skip instruction */
                   1798:                if (tf->tf_exip & 1)
                   1799:                        tf->tf_exip = tf->tf_enip;
                   1800:                else
                   1801:                        tf->tf_exip += 4;
                   1802:        }
                   1803:
                   1804:        userret(p);
                   1805: }

CVSweb