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 15extern char *mem2hex (void *mem, char *buf, int count, int may_fault); 16extern char *hex2mem (char *buf, void *mem, int count, int may_fault); 17extern int computeSignal (int exceptionVector); 18 19void 20flush_i_cache (void) 21{ 22} 23 24/* Get the registers out of the frame information. */ 25 26void 27frame_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 44void 45registers_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 61extern volatile int mem_err; 62 63#ifdef ALTERNATE_MEM_FUNCS 64extern int ReadByteAltDebugger (char* addr, char *theByte); 65extern int WriteByteAltDebugger (char* addr, char theByte); 66int 67get_char (char *addr) 68{ 69 char c; 70 71 if (!ReadByteAltDebugger (addr, &c)) 72 mem_err = 1; 73 74 return c; 75} 76 77void 78set_char (char *addr, int val) 79{ 80 if (!WriteByteAltDebugger (addr, val)) 81 mem_err = 1; 82} 83#endif 84 85int 86mem_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 94union 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 130static LONG saved_inst; 131static LONG *saved_inst_pc = 0; 132static LONG saved_target_inst; 133static LONG *saved_target_inst_pc = 0; 134 135void 136set_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 195int 196clear_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 221void 222do_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