1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <time.h> 5 #include <errno.h> 6 7 #include <nwtypes.h> 8 #include <nwdfs.h> 9 #include <nwconio.h> 10 #include <nwadv.h> 11 #include <nwdbgapi.h> 12 #include <nwthread.h> 13 #include "ppc.h" 14 15 extern char *mem2hex (void *mem, char *buf, int count, int may_fault); 16 extern char *hex2mem (char *buf, void *mem, int count, int may_fault); 17 extern int computeSignal (int exceptionVector); 18 19 void 20 flush_i_cache (void) 21 { 22 } 23 24 /* Get the registers out of the frame information. */ 25 26 void 27 frame_to_registers (struct StackFrame *frame, char *regs) 28 { 29 mem2hex (&frame->ExceptionState.CsavedRegs, ®s[GP0_REGNUM * 4 * 2], 4 * 32, 0); 30 31 mem2hex (&frame->ExceptionState.CSavedFPRegs, ®s[FP0_REGNUM * 4 * 2], 4 * 32, 0); 32 33 mem2hex (&frame->ExceptionPC, ®s[PC_REGNUM * 4 * 2], 4 * 1, 0); 34 35 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, ®s[CR_REGNUM * 4 * 2], 4 * 1, 0); 36 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, ®s[LR_REGNUM * 4 * 2], 4 * 1, 0); 37 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, ®s[CTR_REGNUM * 4 * 2], 4 * 1, 0); 38 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, ®s[XER_REGNUM * 4 * 2], 4 * 1, 0); 39 mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, ®s[MQ_REGNUM * 4 * 2], 4 * 1, 0); 40 } 41 42 /* Put the registers back into the frame information. */ 43 44 void 45 registers_to_frame (char *regs, struct StackFrame *frame) 46 { 47 hex2mem (®s[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0); 48 49 hex2mem (®s[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0); 50 51 hex2mem (®s[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0); 52 53 hex2mem (®s[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0); 54 hex2mem (®s[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0); 55 hex2mem (®s[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0); 56 hex2mem (®s[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0); 57 hex2mem (®s[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0); 58 } 59 60 61 extern volatile int mem_err; 62 63 #ifdef ALTERNATE_MEM_FUNCS 64 extern int ReadByteAltDebugger (char* addr, char *theByte); 65 extern int WriteByteAltDebugger (char* addr, char theByte); 66 int 67 get_char (char *addr) 68 { 69 char c; 70 71 if (!ReadByteAltDebugger (addr, &c)) 72 mem_err = 1; 73 74 return c; 75 } 76 77 void 78 set_char (char *addr, int val) 79 { 80 if (!WriteByteAltDebugger (addr, val)) 81 mem_err = 1; 82 } 83 #endif 84 85 int 86 mem_write (char *dst, char *src, int len) 87 { 88 while (len-- && !mem_err) 89 set_char (dst++, *src++); 90 91 return mem_err; 92 } 93 94 union inst 95 { 96 LONG l; 97 98 struct 99 { 100 union 101 { 102 struct /* Unconditional branch */ 103 { 104 unsigned opcode : 6; /* 18 */ 105 signed li : 24; 106 unsigned aa : 1; 107 unsigned lk : 1; 108 } b; 109 struct /* Conditional branch */ 110 { 111 unsigned opcode : 6; /* 16 */ 112 unsigned bo : 5; 113 unsigned bi : 5; 114 signed bd : 14; 115 unsigned aa : 1; 116 unsigned lk : 1; 117 } bc; 118 struct /* Conditional branch to ctr or lr reg */ 119 { 120 unsigned opcode : 6; /* 19 */ 121 unsigned bo : 5; 122 unsigned bi : 5; 123 unsigned type : 15; /* 528 = ctr, 16 = lr */ 124 unsigned lk : 1; 125 } bclr; 126 } variant; 127 } inst; 128 }; 129 130 static LONG saved_inst; 131 static LONG *saved_inst_pc = 0; 132 static LONG saved_target_inst; 133 static LONG *saved_target_inst_pc = 0; 134 135 void 136 set_step_traps (struct StackFrame *frame) 137 { 138 union inst inst; 139 LONG *target; 140 int opcode; 141 int ra, rb; 142 LONG *pc = (LONG *)frame->ExceptionPC; 143 144 inst.l = *pc++; 145 146 opcode = inst.inst.variant.b.opcode; 147 148 target = pc; 149 150 switch (opcode) 151 { 152 case 18: /* Unconditional branch */ 153 154 if (inst.inst.variant.b.aa) /* Absolute? */ 155 target = 0; 156 target += inst.inst.variant.b.li; 157 158 break; 159 case 16: /* Conditional branch */ 160 161 if (!inst.inst.variant.bc.aa) /* Absolute? */ 162 target = 0; 163 target += inst.inst.variant.bc.bd; 164 165 break; 166 case 19: /* Cond. branch via ctr or lr reg */ 167 switch (inst.inst.variant.bclr.type) 168 { 169 case 528: /* ctr */ 170 target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR; 171 break; 172 case 16: /* lr */ 173 target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR; 174 break; 175 } 176 break; 177 } 178 179 saved_inst = *pc; 180 mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE); 181 saved_inst_pc = pc; 182 183 if (target != pc) 184 { 185 saved_target_inst = *target; 186 mem_write (target, breakpoint_insn, BREAKPOINT_SIZE); 187 saved_target_inst_pc = target; 188 } 189 } 190 191 /* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint, 192 zero otherwise. This routine works even if there were no step breakpoints 193 set. */ 194 195 int 196 clear_step_traps (struct StackFrame *frame) 197 { 198 int retcode; 199 LONG *pc = (LONG *)frame->ExceptionPC; 200 201 if (saved_inst_pc == pc || saved_target_inst_pc == pc) 202 retcode = 1; 203 else 204 retcode = 0; 205 206 if (saved_inst_pc) 207 { 208 mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE); 209 saved_inst_pc = 0; 210 } 211 212 if (saved_target_inst_pc) 213 { 214 mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE); 215 saved_target_inst_pc = 0; 216 } 217 218 return retcode; 219 } 220 221 void 222 do_status (char *ptr, struct StackFrame *frame) 223 { 224 int sigval; 225 226 sigval = computeSignal (frame->ExceptionNumber); 227 228 sprintf (ptr, "T%02x", sigval); 229 ptr += 3; 230 231 sprintf (ptr, "%02x:", PC_REGNUM); 232 ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0); 233 *ptr++ = ';'; 234 235 sprintf (ptr, "%02x:", SP_REGNUM); 236 ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0); 237 *ptr++ = ';'; 238 239 sprintf (ptr, "%02x:", LR_REGNUM); 240 ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0); 241 *ptr++ = ';'; 242 243 *ptr = '\000'; 244 } 245