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