1 /* 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kgdb_glue.c 7.2 (Berkeley) 10/11/92 8 */ 9 10 /* 11 * This file must be compiled with gcc -fno-defer-pop. 12 */ 13 14 #ifdef KGDB 15 16 #include <sys/param.h> 17 18 #include <machine/frame.h> 19 #include <machine/reg.h> 20 21 #ifndef lint 22 static char rcsid[] = 23 "@(#) $Header: kgdb_glue.c,v 1.4 91/03/08 07:02:37 van Exp $ (LBL)"; 24 #endif 25 26 /* 27 * # of additional bytes in 680x0 exception frame format n. 28 */ 29 static int frame_bytes[16] = { 30 0, 0, sizeof(struct fmt2), 0, 31 0, 0, 0, 0, 32 0, sizeof(struct fmt9), sizeof(struct fmtA), sizeof(struct fmtB), 33 0, 0, 0, 0 34 }; 35 36 #define KGDB_STACKSIZE 0x800 37 #define KGDB_STACKWORDS (KGDB_STACKSIZE / sizeof(u_long)) 38 39 u_long kgdb_stack[KGDB_STACKWORDS]; 40 41 #define getsp(v) asm("movl sp, %0" : "=r" (v)) 42 #define setsp(v) asm("movl %0, sp" :: "r" (v)) 43 44 static inline void 45 copywords(src, dst, nbytes) 46 register u_long *src, *dst; 47 register u_int nbytes; 48 { 49 u_long *limit = src + (nbytes / sizeof(u_long)); 50 51 do { 52 *dst++ = *src++; 53 } while (src < limit); 54 if (nbytes & 2) 55 *(u_short *)dst = *(u_short *)src; 56 } 57 58 kgdb_trap_glue(type, frame) 59 int type; 60 struct frame frame; 61 { 62 u_long osp, nsp; 63 u_int fsize, s; 64 65 /* 66 * After a kernel mode trap, the saved sp doesn't point to the right 67 * place. The correct value is the top of the frame. 68 */ 69 fsize = sizeof(frame) - sizeof(frame.F_u) + frame_bytes[frame.f_format]; 70 frame.f_regs[SP] = (u_long)&frame + fsize; 71 72 /* 73 * Copy the interrupt context and frame to the new stack. 74 * We're throwing away trap()'s frame since we're going to do 75 * our own rte. 76 */ 77 nsp = (u_long)&kgdb_stack[KGDB_STACKWORDS] - 78 roundup(fsize, sizeof(u_long)); 79 80 copywords((u_long *)&frame, (u_long *)nsp, fsize); 81 82 s = splhigh(); 83 84 getsp(osp); 85 setsp(nsp); 86 87 if (kgdb_trap(type, (struct frame *)nsp) == 0) { 88 /* 89 * Get back on kernel stack. This thread of control 90 * will return back up through trap(). If kgdb_trap() 91 * returns 0, it didn't handle the trap at all so 92 * the stack is still intact and everything will 93 * unwind okay from here up. 94 */ 95 setsp(osp); 96 splx(s); 97 return 0; 98 } 99 /* 100 * Copy back context, which has possibly changed. Even the 101 * sp might have changed. 102 */ 103 osp = ((struct frame *)nsp)->f_regs[SP] - fsize; 104 copywords((u_long *)nsp, (u_long *)osp, fsize); 105 setsp(osp); 106 107 /* 108 * Restore the possible new context from frame, pop the 109 * unneeded usp (we trapped from kernel mode) and pad word, 110 * and return to the trapped thread. 111 */ 112 asm("moveml sp@+,#0x7FFF; addql #6,sp; rte"); 113 } 114 115 int kgdb_testval; 116 117 kgdb_test(i) 118 { 119 ++kgdb_testval; 120 return i + 1; 121 } 122 123 #endif 124