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