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
printtrap(int type,struct trapframe * frame)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
panictrap(int type,struct trapframe * frame)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
interrupt(struct trapframe * frame)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
nmi(struct trapframe * frame)183 nmi(struct trapframe *frame)
184 {
185 return md_nmi_func(frame);
186 }
187
188 /*
189 * Reenable non-maskable interrupts.
190 */
191 void
nmi_wrapup(struct trapframe * frame)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
ast(struct trapframe * frame)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
m88100_trap(u_int type,struct trapframe * frame)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
m88110_trap(u_int type,struct trapframe * frame)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
error_fatal(struct trapframe * frame)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
m88100_syscall(register_t code,struct trapframe * tf)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
m88110_syscall(register_t code,struct trapframe * tf)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
child_return(arg)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
ss_get_value(struct proc * p,vaddr_t addr,u_int * value)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
ss_put_value(struct proc * p,vaddr_t addr,u_int value)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
ss_branch_taken(u_int inst,vaddr_t pc,struct reg * regs)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
ss_inst_branch_or_call(u_int ins)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
ss_put_breakpoint(struct proc * p,vaddr_t va,vaddr_t * bpva,u_int * bpsave)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
process_sstep(struct proc * p,int sstep)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
splassert_check(int wantipl,const char * func)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
double_reg_fixup(struct trapframe * frame,int fault)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
cache_flush(struct trapframe * tf)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