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
flush_i_cache(void)20 flush_i_cache (void)
21 {
22 }
23 
24 /* Get the registers out of the frame information.  */
25 
26 void
frame_to_registers(struct StackFrame * frame,char * regs)27 frame_to_registers (struct StackFrame *frame, char *regs)
28 {
29   mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
30 
31   mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
32 
33   mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
34 
35   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
36   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
37   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
38   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
39   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
40 }
41 
42 /* Put the registers back into the frame information.  */
43 
44 void
registers_to_frame(char * regs,struct StackFrame * frame)45 registers_to_frame (char *regs, struct StackFrame *frame)
46 {
47   hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
48 
49   hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
50 
51   hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
52 
53   hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
54   hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
55   hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
56   hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
57   hex2mem (&regs[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
get_char(char * addr)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
set_char(char * addr,int val)78 set_char (char *addr, int val)
79 {
80   if (!WriteByteAltDebugger (addr, val))
81     mem_err = 1;
82 }
83 #endif
84 
85 int
mem_write(char * dst,char * src,int len)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
set_step_traps(struct StackFrame * frame)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
clear_step_traps(struct StackFrame * frame)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
do_status(char * ptr,struct StackFrame * frame)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