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, &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
44void
45registers_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
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