]>
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 | |
fba45db2 | 27 | frame_to_registers (struct StackFrame *frame, char *regs) |
c906108c SS |
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 | |
fba45db2 | 45 | registers_to_frame (char *regs, struct StackFrame *frame) |
c906108c SS |
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 | |
fba45db2 | 67 | get_char (char *addr) |
c906108c SS |
68 | { |
69 | char c; | |
70 | ||
71 | if (!ReadByteAltDebugger (addr, &c)) | |
72 | mem_err = 1; | |
73 | ||
74 | return c; | |
75 | } | |
76 | ||
77 | void | |
fba45db2 | 78 | set_char (char *addr, int val) |
c906108c SS |
79 | { |
80 | if (!WriteByteAltDebugger (addr, val)) | |
81 | mem_err = 1; | |
82 | } | |
83 | #endif | |
84 | ||
85 | int | |
fba45db2 | 86 | mem_write (char *dst, char *src, int len) |
c906108c SS |
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 | |
fba45db2 | 136 | set_step_traps (struct StackFrame *frame) |
c906108c SS |
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 | |
fba45db2 | 196 | clear_step_traps (struct StackFrame *frame) |
c906108c SS |
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 | |
fba45db2 | 222 | do_status (char *ptr, struct StackFrame *frame) |
c906108c SS |
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 | } |