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