Add qemu 2.4.0
[kvmfornfv.git] / qemu / target-ppc / gdbstub.c
1 /*
2  * PowerPC gdb server stub
3  *
4  * Copyright (c) 2003-2005 Fabrice Bellard
5  * Copyright (c) 2013 SUSE LINUX Products GmbH
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 #include "config.h"
21 #include "qemu-common.h"
22 #include "exec/gdbstub.h"
23
24 static int ppc_gdb_register_len_apple(int n)
25 {
26     switch (n) {
27     case 0 ... 31:
28         /* gprs */
29         return 8;
30     case 32 ... 63:
31         /* fprs */
32         return 8;
33     case 64 ... 95:
34         return 16;
35     case 64+32: /* nip */
36     case 65+32: /* msr */
37     case 67+32: /* lr */
38     case 68+32: /* ctr */
39     case 69+32: /* xer */
40     case 70+32: /* fpscr */
41         return 8;
42     case 66+32: /* cr */
43         return 4;
44     default:
45         return 0;
46     }
47 }
48
49 static int ppc_gdb_register_len(int n)
50 {
51     switch (n) {
52     case 0 ... 31:
53         /* gprs */
54         return sizeof(target_ulong);
55     case 32 ... 63:
56         /* fprs */
57         if (gdb_has_xml) {
58             return 0;
59         }
60         return 8;
61     case 66:
62         /* cr */
63         return 4;
64     case 64:
65         /* nip */
66     case 65:
67         /* msr */
68     case 67:
69         /* lr */
70     case 68:
71         /* ctr */
72     case 69:
73         /* xer */
74         return sizeof(target_ulong);
75     case 70:
76         /* fpscr */
77         if (gdb_has_xml) {
78             return 0;
79         }
80         return sizeof(target_ulong);
81     default:
82         return 0;
83     }
84 }
85
86 /* We need to present the registers to gdb in the "current" memory ordering.
87    For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
88    the proper ordering for the binary, and cannot be changed.
89    For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
90    the current mode of the chip to see if we're running in little-endian.  */
91 static void maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
92 {
93 #ifndef CONFIG_USER_ONLY
94     if (!msr_le) {
95         /* do nothing */
96     } else if (len == 4) {
97         bswap32s((uint32_t *)mem_buf);
98     } else if (len == 8) {
99         bswap64s((uint64_t *)mem_buf);
100     } else {
101         g_assert_not_reached();
102     }
103 #endif
104 }
105
106 /* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
107  * expects whatever the target description contains.  Due to a
108  * historical mishap the FP registers appear in between core integer
109  * regs and PC, MSR, CR, and so forth.  We hack round this by giving the
110  * FP regs zero size when talking to a newer gdb.
111  */
112
113 int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
114 {
115     PowerPCCPU *cpu = POWERPC_CPU(cs);
116     CPUPPCState *env = &cpu->env;
117     int r = ppc_gdb_register_len(n);
118
119     if (!r) {
120         return r;
121     }
122
123     if (n < 32) {
124         /* gprs */
125         gdb_get_regl(mem_buf, env->gpr[n]);
126     } else if (n < 64) {
127         /* fprs */
128         stfq_p(mem_buf, env->fpr[n-32]);
129     } else {
130         switch (n) {
131         case 64:
132             gdb_get_regl(mem_buf, env->nip);
133             break;
134         case 65:
135             gdb_get_regl(mem_buf, env->msr);
136             break;
137         case 66:
138             {
139                 uint32_t cr = 0;
140                 int i;
141                 for (i = 0; i < 8; i++) {
142                     cr |= env->crf[i] << (32 - ((i + 1) * 4));
143                 }
144                 gdb_get_reg32(mem_buf, cr);
145                 break;
146             }
147         case 67:
148             gdb_get_regl(mem_buf, env->lr);
149             break;
150         case 68:
151             gdb_get_regl(mem_buf, env->ctr);
152             break;
153         case 69:
154             gdb_get_regl(mem_buf, env->xer);
155             break;
156         case 70:
157             gdb_get_reg32(mem_buf, env->fpscr);
158             break;
159         }
160     }
161     maybe_bswap_register(env, mem_buf, r);
162     return r;
163 }
164
165 int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
166 {
167     PowerPCCPU *cpu = POWERPC_CPU(cs);
168     CPUPPCState *env = &cpu->env;
169     int r = ppc_gdb_register_len_apple(n);
170
171     if (!r) {
172         return r;
173     }
174
175     if (n < 32) {
176         /* gprs */
177         gdb_get_reg64(mem_buf, env->gpr[n]);
178     } else if (n < 64) {
179         /* fprs */
180         stfq_p(mem_buf, env->fpr[n-32]);
181     } else if (n < 96) {
182         /* Altivec */
183         stq_p(mem_buf, n - 64);
184         stq_p(mem_buf + 8, 0);
185     } else {
186         switch (n) {
187         case 64 + 32:
188             gdb_get_reg64(mem_buf, env->nip);
189             break;
190         case 65 + 32:
191             gdb_get_reg64(mem_buf, env->msr);
192             break;
193         case 66 + 32:
194             {
195                 uint32_t cr = 0;
196                 int i;
197                 for (i = 0; i < 8; i++) {
198                     cr |= env->crf[i] << (32 - ((i + 1) * 4));
199                 }
200                 gdb_get_reg32(mem_buf, cr);
201                 break;
202             }
203         case 67 + 32:
204             gdb_get_reg64(mem_buf, env->lr);
205             break;
206         case 68 + 32:
207             gdb_get_reg64(mem_buf, env->ctr);
208             break;
209         case 69 + 32:
210             gdb_get_reg64(mem_buf, env->xer);
211             break;
212         case 70 + 32:
213             gdb_get_reg64(mem_buf, env->fpscr);
214             break;
215         }
216     }
217     maybe_bswap_register(env, mem_buf, r);
218     return r;
219 }
220
221 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
222 {
223     PowerPCCPU *cpu = POWERPC_CPU(cs);
224     CPUPPCState *env = &cpu->env;
225     int r = ppc_gdb_register_len(n);
226
227     if (!r) {
228         return r;
229     }
230     maybe_bswap_register(env, mem_buf, r);
231     if (n < 32) {
232         /* gprs */
233         env->gpr[n] = ldtul_p(mem_buf);
234     } else if (n < 64) {
235         /* fprs */
236         env->fpr[n-32] = ldfq_p(mem_buf);
237     } else {
238         switch (n) {
239         case 64:
240             env->nip = ldtul_p(mem_buf);
241             break;
242         case 65:
243             ppc_store_msr(env, ldtul_p(mem_buf));
244             break;
245         case 66:
246             {
247                 uint32_t cr = ldl_p(mem_buf);
248                 int i;
249                 for (i = 0; i < 8; i++) {
250                     env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
251                 }
252                 break;
253             }
254         case 67:
255             env->lr = ldtul_p(mem_buf);
256             break;
257         case 68:
258             env->ctr = ldtul_p(mem_buf);
259             break;
260         case 69:
261             env->xer = ldtul_p(mem_buf);
262             break;
263         case 70:
264             /* fpscr */
265             store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
266             break;
267         }
268     }
269     return r;
270 }
271 int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
272 {
273     PowerPCCPU *cpu = POWERPC_CPU(cs);
274     CPUPPCState *env = &cpu->env;
275     int r = ppc_gdb_register_len_apple(n);
276
277     if (!r) {
278         return r;
279     }
280     maybe_bswap_register(env, mem_buf, r);
281     if (n < 32) {
282         /* gprs */
283         env->gpr[n] = ldq_p(mem_buf);
284     } else if (n < 64) {
285         /* fprs */
286         env->fpr[n-32] = ldfq_p(mem_buf);
287     } else {
288         switch (n) {
289         case 64 + 32:
290             env->nip = ldq_p(mem_buf);
291             break;
292         case 65 + 32:
293             ppc_store_msr(env, ldq_p(mem_buf));
294             break;
295         case 66 + 32:
296             {
297                 uint32_t cr = ldl_p(mem_buf);
298                 int i;
299                 for (i = 0; i < 8; i++) {
300                     env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
301                 }
302                 break;
303             }
304         case 67 + 32:
305             env->lr = ldq_p(mem_buf);
306             break;
307         case 68 + 32:
308             env->ctr = ldq_p(mem_buf);
309             break;
310         case 69 + 32:
311             env->xer = ldq_p(mem_buf);
312             break;
313         case 70 + 32:
314             /* fpscr */
315             store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
316             break;
317         }
318     }
319     return r;
320 }