xref: /openbmc/qemu/target/ppc/gdbstub.c (revision 7901c12bd77e2da20b3a93e7012f998ce5379402)
1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth  * PowerPC gdb server stub
3fcf5ef2aSThomas Huth  *
4fcf5ef2aSThomas Huth  * Copyright (c) 2003-2005 Fabrice Bellard
5fcf5ef2aSThomas Huth  * Copyright (c) 2013 SUSE LINUX Products GmbH
6fcf5ef2aSThomas Huth  *
7fcf5ef2aSThomas Huth  * This library is free software; you can redistribute it and/or
8fcf5ef2aSThomas Huth  * modify it under the terms of the GNU Lesser General Public
9fcf5ef2aSThomas Huth  * License as published by the Free Software Foundation; either
106bd039cdSChetan Pant  * version 2.1 of the License, or (at your option) any later version.
11fcf5ef2aSThomas Huth  *
12fcf5ef2aSThomas Huth  * This library is distributed in the hope that it will be useful,
13fcf5ef2aSThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14fcf5ef2aSThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15fcf5ef2aSThomas Huth  * Lesser General Public License for more details.
16fcf5ef2aSThomas Huth  *
17fcf5ef2aSThomas Huth  * You should have received a copy of the GNU Lesser General Public
18fcf5ef2aSThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19fcf5ef2aSThomas Huth  */
20fcf5ef2aSThomas Huth #include "qemu/osdep.h"
21fcf5ef2aSThomas Huth #include "cpu.h"
22fcf5ef2aSThomas Huth #include "exec/gdbstub.h"
234ea5fe99SAlex Bennée #include "gdbstub/helpers.h"
2435a5d74eSBruno Larsen (billionai) #include "internal.h"
25fcf5ef2aSThomas Huth 
ppc_gdb_register_len_apple(int n)26fcf5ef2aSThomas Huth static int ppc_gdb_register_len_apple(int n)
27fcf5ef2aSThomas Huth {
28fcf5ef2aSThomas Huth     switch (n) {
29fcf5ef2aSThomas Huth     case 0 ... 31:
30fcf5ef2aSThomas Huth         /* gprs */
31fcf5ef2aSThomas Huth         return 8;
32fcf5ef2aSThomas Huth     case 32 ... 63:
33fcf5ef2aSThomas Huth         /* fprs */
34fcf5ef2aSThomas Huth         return 8;
35fcf5ef2aSThomas Huth     case 64 ... 95:
36fcf5ef2aSThomas Huth         return 16;
37fcf5ef2aSThomas Huth     case 64 + 32: /* nip */
38fcf5ef2aSThomas Huth     case 65 + 32: /* msr */
39fcf5ef2aSThomas Huth     case 67 + 32: /* lr */
40fcf5ef2aSThomas Huth     case 68 + 32: /* ctr */
41fcf5ef2aSThomas Huth     case 70 + 32: /* fpscr */
42fcf5ef2aSThomas Huth         return 8;
43fcf5ef2aSThomas Huth     case 66 + 32: /* cr */
44a2f04333SMichael Matz     case 69 + 32: /* xer */
45fcf5ef2aSThomas Huth         return 4;
46fcf5ef2aSThomas Huth     default:
47fcf5ef2aSThomas Huth         return 0;
48fcf5ef2aSThomas Huth     }
49fcf5ef2aSThomas Huth }
50fcf5ef2aSThomas Huth 
ppc_gdb_register_len(int n)51fcf5ef2aSThomas Huth static int ppc_gdb_register_len(int n)
52fcf5ef2aSThomas Huth {
53fcf5ef2aSThomas Huth     switch (n) {
54fcf5ef2aSThomas Huth     case 0 ... 31:
55fcf5ef2aSThomas Huth         /* gprs */
56fcf5ef2aSThomas Huth         return sizeof(target_ulong);
57fcf5ef2aSThomas Huth     case 66:
58fcf5ef2aSThomas Huth         /* cr */
59a2f04333SMichael Matz     case 69:
60a2f04333SMichael Matz         /* xer */
61fcf5ef2aSThomas Huth         return 4;
62fcf5ef2aSThomas Huth     case 64:
63fcf5ef2aSThomas Huth         /* nip */
64fcf5ef2aSThomas Huth     case 65:
65fcf5ef2aSThomas Huth         /* msr */
66fcf5ef2aSThomas Huth     case 67:
67fcf5ef2aSThomas Huth         /* lr */
68fcf5ef2aSThomas Huth     case 68:
69fcf5ef2aSThomas Huth         /* ctr */
70fcf5ef2aSThomas Huth         return sizeof(target_ulong);
71fcf5ef2aSThomas Huth     default:
72fcf5ef2aSThomas Huth         return 0;
73fcf5ef2aSThomas Huth     }
74fcf5ef2aSThomas Huth }
75fcf5ef2aSThomas Huth 
7602381ec1SDavid Gibson /*
7702381ec1SDavid Gibson  * We need to present the registers to gdb in the "current" memory
7802381ec1SDavid Gibson  * ordering.  For user-only mode we get this for free;
79ee3eb3a7SMarc-André Lureau  * TARGET_BIG_ENDIAN is set to the proper ordering for the
8002381ec1SDavid Gibson  * binary, and cannot be changed.  For system mode,
81ee3eb3a7SMarc-André Lureau  * TARGET_BIG_ENDIAN is always set, and we must check the current
8202381ec1SDavid Gibson  * mode of the chip to see if we're running in little-endian.
8302381ec1SDavid Gibson  */
ppc_maybe_bswap_register(CPUPPCState * env,uint8_t * mem_buf,int len)84fcf5ef2aSThomas Huth void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
85fcf5ef2aSThomas Huth {
86fcf5ef2aSThomas Huth #ifndef CONFIG_USER_ONLY
871922322cSVíctor Colombo     if (!FIELD_EX64(env->msr, MSR, LE)) {
88fcf5ef2aSThomas Huth         /* do nothing */
89fcf5ef2aSThomas Huth     } else if (len == 4) {
90fcf5ef2aSThomas Huth         bswap32s((uint32_t *)mem_buf);
91fcf5ef2aSThomas Huth     } else if (len == 8) {
92fcf5ef2aSThomas Huth         bswap64s((uint64_t *)mem_buf);
930ff16b6bSMatheus Ferst     } else if (len == 16) {
940ff16b6bSMatheus Ferst         bswap128s((Int128 *)mem_buf);
95fcf5ef2aSThomas Huth     } else {
96fcf5ef2aSThomas Huth         g_assert_not_reached();
97fcf5ef2aSThomas Huth     }
98fcf5ef2aSThomas Huth #endif
99fcf5ef2aSThomas Huth }
100fcf5ef2aSThomas Huth 
10102381ec1SDavid Gibson /*
10202381ec1SDavid Gibson  * Old gdb always expects FP registers.  Newer (xml-aware) gdb only
103fcf5ef2aSThomas Huth  * expects whatever the target description contains.  Due to a
104fcf5ef2aSThomas Huth  * historical mishap the FP registers appear in between core integer
10502381ec1SDavid Gibson  * regs and PC, MSR, CR, and so forth.  We hack round this by giving
10602381ec1SDavid Gibson  * the FP regs zero size when talking to a newer gdb.
107fcf5ef2aSThomas Huth  */
108fcf5ef2aSThomas Huth 
ppc_cpu_gdb_read_register(CPUState * cs,GByteArray * buf,int n)109a010bdbeSAlex Bennée int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
110fcf5ef2aSThomas Huth {
111794511bcSPhilippe Mathieu-Daudé     CPUPPCState *env = cpu_env(cs);
112a010bdbeSAlex Bennée     uint8_t *mem_buf;
113fcf5ef2aSThomas Huth     int r = ppc_gdb_register_len(n);
114fcf5ef2aSThomas Huth 
115fcf5ef2aSThomas Huth     if (!r) {
116fcf5ef2aSThomas Huth         return r;
117fcf5ef2aSThomas Huth     }
118fcf5ef2aSThomas Huth 
119fcf5ef2aSThomas Huth     if (n < 32) {
120fcf5ef2aSThomas Huth         /* gprs */
121a010bdbeSAlex Bennée         gdb_get_regl(buf, env->gpr[n]);
122fcf5ef2aSThomas Huth     } else {
123fcf5ef2aSThomas Huth         switch (n) {
124fcf5ef2aSThomas Huth         case 64:
125a010bdbeSAlex Bennée             gdb_get_regl(buf, env->nip);
126fcf5ef2aSThomas Huth             break;
127fcf5ef2aSThomas Huth         case 65:
128a010bdbeSAlex Bennée             gdb_get_regl(buf, env->msr);
129fcf5ef2aSThomas Huth             break;
130fcf5ef2aSThomas Huth         case 66:
131fcf5ef2aSThomas Huth             {
1322060436aSHarsh Prateek Bora                 uint32_t cr = ppc_get_cr(env);
133a010bdbeSAlex Bennée                 gdb_get_reg32(buf, cr);
134fcf5ef2aSThomas Huth                 break;
135fcf5ef2aSThomas Huth             }
136fcf5ef2aSThomas Huth         case 67:
137a010bdbeSAlex Bennée             gdb_get_regl(buf, env->lr);
138fcf5ef2aSThomas Huth             break;
139fcf5ef2aSThomas Huth         case 68:
140a010bdbeSAlex Bennée             gdb_get_regl(buf, env->ctr);
141fcf5ef2aSThomas Huth             break;
142fcf5ef2aSThomas Huth         case 69:
1437974dc59SMatheus Ferst             gdb_get_reg32(buf, cpu_read_xer(env));
144fcf5ef2aSThomas Huth             break;
145fcf5ef2aSThomas Huth         }
146fcf5ef2aSThomas Huth     }
147a010bdbeSAlex Bennée     mem_buf = buf->data + buf->len - r;
148fcf5ef2aSThomas Huth     ppc_maybe_bswap_register(env, mem_buf, r);
149fcf5ef2aSThomas Huth     return r;
150fcf5ef2aSThomas Huth }
151fcf5ef2aSThomas Huth 
ppc_cpu_gdb_read_register_apple(CPUState * cs,GByteArray * buf,int n)152a010bdbeSAlex Bennée int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
153fcf5ef2aSThomas Huth {
154794511bcSPhilippe Mathieu-Daudé     CPUPPCState *env = cpu_env(cs);
155a010bdbeSAlex Bennée     uint8_t *mem_buf;
156fcf5ef2aSThomas Huth     int r = ppc_gdb_register_len_apple(n);
157fcf5ef2aSThomas Huth 
158fcf5ef2aSThomas Huth     if (!r) {
159fcf5ef2aSThomas Huth         return r;
160fcf5ef2aSThomas Huth     }
161fcf5ef2aSThomas Huth 
162fcf5ef2aSThomas Huth     if (n < 32) {
163fcf5ef2aSThomas Huth         /* gprs */
164a010bdbeSAlex Bennée         gdb_get_reg64(buf, env->gpr[n]);
165fcf5ef2aSThomas Huth     } else if (n < 64) {
166fcf5ef2aSThomas Huth         /* fprs */
16734510e32SPeter Maydell         gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
168fcf5ef2aSThomas Huth     } else if (n < 96) {
169fcf5ef2aSThomas Huth         /* Altivec */
170a010bdbeSAlex Bennée         gdb_get_reg64(buf, n - 64);
171a010bdbeSAlex Bennée         gdb_get_reg64(buf, 0);
172fcf5ef2aSThomas Huth     } else {
173fcf5ef2aSThomas Huth         switch (n) {
174fcf5ef2aSThomas Huth         case 64 + 32:
175a010bdbeSAlex Bennée             gdb_get_reg64(buf, env->nip);
176fcf5ef2aSThomas Huth             break;
177fcf5ef2aSThomas Huth         case 65 + 32:
178a010bdbeSAlex Bennée             gdb_get_reg64(buf, env->msr);
179fcf5ef2aSThomas Huth             break;
180fcf5ef2aSThomas Huth         case 66 + 32:
181fcf5ef2aSThomas Huth             {
1822060436aSHarsh Prateek Bora                 uint32_t cr = ppc_get_cr(env);
183a010bdbeSAlex Bennée                 gdb_get_reg32(buf, cr);
184fcf5ef2aSThomas Huth                 break;
185fcf5ef2aSThomas Huth             }
186fcf5ef2aSThomas Huth         case 67 + 32:
187a010bdbeSAlex Bennée             gdb_get_reg64(buf, env->lr);
188fcf5ef2aSThomas Huth             break;
189fcf5ef2aSThomas Huth         case 68 + 32:
190a010bdbeSAlex Bennée             gdb_get_reg64(buf, env->ctr);
191fcf5ef2aSThomas Huth             break;
192fcf5ef2aSThomas Huth         case 69 + 32:
1937974dc59SMatheus Ferst             gdb_get_reg32(buf, cpu_read_xer(env));
194fcf5ef2aSThomas Huth             break;
195fcf5ef2aSThomas Huth         case 70 + 32:
196a010bdbeSAlex Bennée             gdb_get_reg64(buf, env->fpscr);
197fcf5ef2aSThomas Huth             break;
198fcf5ef2aSThomas Huth         }
199fcf5ef2aSThomas Huth     }
200a010bdbeSAlex Bennée     mem_buf = buf->data + buf->len - r;
201fcf5ef2aSThomas Huth     ppc_maybe_bswap_register(env, mem_buf, r);
202fcf5ef2aSThomas Huth     return r;
203fcf5ef2aSThomas Huth }
204fcf5ef2aSThomas Huth 
ppc_cpu_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)205fcf5ef2aSThomas Huth int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
206fcf5ef2aSThomas Huth {
207794511bcSPhilippe Mathieu-Daudé     CPUPPCState *env = cpu_env(cs);
208fcf5ef2aSThomas Huth     int r = ppc_gdb_register_len(n);
209fcf5ef2aSThomas Huth 
210fcf5ef2aSThomas Huth     if (!r) {
211fcf5ef2aSThomas Huth         return r;
212fcf5ef2aSThomas Huth     }
213fcf5ef2aSThomas Huth     ppc_maybe_bswap_register(env, mem_buf, r);
214fcf5ef2aSThomas Huth     if (n < 32) {
215fcf5ef2aSThomas Huth         /* gprs */
216fcf5ef2aSThomas Huth         env->gpr[n] = ldtul_p(mem_buf);
217fcf5ef2aSThomas Huth     } else if (n < 64) {
218fcf5ef2aSThomas Huth         /* fprs */
21934510e32SPeter Maydell         *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
220fcf5ef2aSThomas Huth     } else {
221fcf5ef2aSThomas Huth         switch (n) {
222fcf5ef2aSThomas Huth         case 64:
223fcf5ef2aSThomas Huth             env->nip = ldtul_p(mem_buf);
224fcf5ef2aSThomas Huth             break;
225fcf5ef2aSThomas Huth         case 65:
226fcf5ef2aSThomas Huth             ppc_store_msr(env, ldtul_p(mem_buf));
227fcf5ef2aSThomas Huth             break;
228fcf5ef2aSThomas Huth         case 66:
229fcf5ef2aSThomas Huth             {
230fcf5ef2aSThomas Huth                 uint32_t cr = ldl_p(mem_buf);
2312060436aSHarsh Prateek Bora                 ppc_set_cr(env, cr);
232fcf5ef2aSThomas Huth                 break;
233fcf5ef2aSThomas Huth             }
234fcf5ef2aSThomas Huth         case 67:
235fcf5ef2aSThomas Huth             env->lr = ldtul_p(mem_buf);
236fcf5ef2aSThomas Huth             break;
237fcf5ef2aSThomas Huth         case 68:
238fcf5ef2aSThomas Huth             env->ctr = ldtul_p(mem_buf);
239fcf5ef2aSThomas Huth             break;
240fcf5ef2aSThomas Huth         case 69:
2417974dc59SMatheus Ferst             cpu_write_xer(env, ldl_p(mem_buf));
242fcf5ef2aSThomas Huth             break;
243fcf5ef2aSThomas Huth         case 70:
244fcf5ef2aSThomas Huth             /* fpscr */
245fe43ba97SBruno Larsen (billionai)             ppc_store_fpscr(env, ldtul_p(mem_buf));
246fcf5ef2aSThomas Huth             break;
247fcf5ef2aSThomas Huth         }
248fcf5ef2aSThomas Huth     }
249fcf5ef2aSThomas Huth     return r;
250fcf5ef2aSThomas Huth }
ppc_cpu_gdb_write_register_apple(CPUState * cs,uint8_t * mem_buf,int n)251fcf5ef2aSThomas Huth int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
252fcf5ef2aSThomas Huth {
253794511bcSPhilippe Mathieu-Daudé     CPUPPCState *env = cpu_env(cs);
254fcf5ef2aSThomas Huth     int r = ppc_gdb_register_len_apple(n);
255fcf5ef2aSThomas Huth 
256fcf5ef2aSThomas Huth     if (!r) {
257fcf5ef2aSThomas Huth         return r;
258fcf5ef2aSThomas Huth     }
259fcf5ef2aSThomas Huth     ppc_maybe_bswap_register(env, mem_buf, r);
260fcf5ef2aSThomas Huth     if (n < 32) {
261fcf5ef2aSThomas Huth         /* gprs */
262fcf5ef2aSThomas Huth         env->gpr[n] = ldq_p(mem_buf);
263fcf5ef2aSThomas Huth     } else if (n < 64) {
264fcf5ef2aSThomas Huth         /* fprs */
26534510e32SPeter Maydell         *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
266fcf5ef2aSThomas Huth     } else {
267fcf5ef2aSThomas Huth         switch (n) {
268fcf5ef2aSThomas Huth         case 64 + 32:
269fcf5ef2aSThomas Huth             env->nip = ldq_p(mem_buf);
270fcf5ef2aSThomas Huth             break;
271fcf5ef2aSThomas Huth         case 65 + 32:
272fcf5ef2aSThomas Huth             ppc_store_msr(env, ldq_p(mem_buf));
273fcf5ef2aSThomas Huth             break;
274fcf5ef2aSThomas Huth         case 66 + 32:
275fcf5ef2aSThomas Huth             {
276fcf5ef2aSThomas Huth                 uint32_t cr = ldl_p(mem_buf);
2772060436aSHarsh Prateek Bora                 ppc_set_cr(env, cr);
278fcf5ef2aSThomas Huth                 break;
279fcf5ef2aSThomas Huth             }
280fcf5ef2aSThomas Huth         case 67 + 32:
281fcf5ef2aSThomas Huth             env->lr = ldq_p(mem_buf);
282fcf5ef2aSThomas Huth             break;
283fcf5ef2aSThomas Huth         case 68 + 32:
284fcf5ef2aSThomas Huth             env->ctr = ldq_p(mem_buf);
285fcf5ef2aSThomas Huth             break;
286fcf5ef2aSThomas Huth         case 69 + 32:
2877974dc59SMatheus Ferst             cpu_write_xer(env, ldl_p(mem_buf));
288fcf5ef2aSThomas Huth             break;
289fcf5ef2aSThomas Huth         case 70 + 32:
290fcf5ef2aSThomas Huth             /* fpscr */
291fe43ba97SBruno Larsen (billionai)             ppc_store_fpscr(env, ldq_p(mem_buf));
292fcf5ef2aSThomas Huth             break;
293fcf5ef2aSThomas Huth         }
294fcf5ef2aSThomas Huth     }
295fcf5ef2aSThomas Huth     return r;
296fcf5ef2aSThomas Huth }
297707c7c2eSFabiano Rosas 
298707c7c2eSFabiano Rosas #ifndef CONFIG_USER_ONLY
gdb_gen_spr_feature(CPUState * cs)2991b53948fSAkihiko Odaki static void gdb_gen_spr_feature(CPUState *cs)
300707c7c2eSFabiano Rosas {
3011b53948fSAkihiko Odaki     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
3021b53948fSAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
303707c7c2eSFabiano Rosas     CPUPPCState *env = &cpu->env;
3041b53948fSAkihiko Odaki     GDBFeatureBuilder builder;
305707c7c2eSFabiano Rosas     unsigned int num_regs = 0;
306707c7c2eSFabiano Rosas     int i;
307707c7c2eSFabiano Rosas 
308*ed399adeSBenjamin Gray     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
309*ed399adeSBenjamin Gray         ppc_spr_t *spr = &env->spr_cb[i];
310*ed399adeSBenjamin Gray 
311*ed399adeSBenjamin Gray         if (!spr->name) {
312*ed399adeSBenjamin Gray             continue;
313*ed399adeSBenjamin Gray         }
314*ed399adeSBenjamin Gray 
315*ed399adeSBenjamin Gray         /*
316*ed399adeSBenjamin Gray          * GDB identifies registers based on the order they are
317*ed399adeSBenjamin Gray          * presented in the XML. These ids will not match QEMU's
318*ed399adeSBenjamin Gray          * representation (which follows the PowerISA).
319*ed399adeSBenjamin Gray          *
320*ed399adeSBenjamin Gray          * Store the position of the current register description so
321*ed399adeSBenjamin Gray          * we can make the correspondence later.
322*ed399adeSBenjamin Gray          */
323*ed399adeSBenjamin Gray         spr->gdb_id = num_regs;
324*ed399adeSBenjamin Gray         num_regs++;
325*ed399adeSBenjamin Gray     }
326*ed399adeSBenjamin Gray 
3271b53948fSAkihiko Odaki     if (pcc->gdb_spr.xml) {
3281b53948fSAkihiko Odaki         return;
3291b53948fSAkihiko Odaki     }
3301b53948fSAkihiko Odaki 
3311b53948fSAkihiko Odaki     gdb_feature_builder_init(&builder, &pcc->gdb_spr,
3321b53948fSAkihiko Odaki                              "org.qemu.power.spr", "power-spr.xml",
3331b53948fSAkihiko Odaki                              cs->gdb_num_regs);
3341b53948fSAkihiko Odaki 
335981562edSNicholas Piggin     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
336981562edSNicholas Piggin         ppc_spr_t *spr = &env->spr_cb[i];
337981562edSNicholas Piggin 
338981562edSNicholas Piggin         if (!spr->name) {
339981562edSNicholas Piggin             continue;
340981562edSNicholas Piggin         }
341981562edSNicholas Piggin 
34299ea316eSNicholas Piggin         gdb_feature_builder_append_reg(&builder, g_ascii_strdown(spr->name, -1),
343*ed399adeSBenjamin Gray                                        TARGET_LONG_BITS, spr->gdb_id,
34499ea316eSNicholas Piggin                                        "int", "spr");
345981562edSNicholas Piggin     }
346981562edSNicholas Piggin 
3471b53948fSAkihiko Odaki     gdb_feature_builder_end(&builder);
348707c7c2eSFabiano Rosas }
349707c7c2eSFabiano Rosas #endif
35035a5d74eSBruno Larsen (billionai) 
35135a5d74eSBruno Larsen (billionai) #if !defined(CONFIG_USER_ONLY)
gdb_find_spr_idx(CPUPPCState * env,int n)35235a5d74eSBruno Larsen (billionai) static int gdb_find_spr_idx(CPUPPCState *env, int n)
35335a5d74eSBruno Larsen (billionai) {
35435a5d74eSBruno Larsen (billionai)     int i;
35535a5d74eSBruno Larsen (billionai) 
35635a5d74eSBruno Larsen (billionai)     for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
35735a5d74eSBruno Larsen (billionai)         ppc_spr_t *spr = &env->spr_cb[i];
35835a5d74eSBruno Larsen (billionai) 
35935a5d74eSBruno Larsen (billionai)         if (spr->name && spr->gdb_id == n) {
36035a5d74eSBruno Larsen (billionai)             return i;
36135a5d74eSBruno Larsen (billionai)         }
36235a5d74eSBruno Larsen (billionai)     }
36335a5d74eSBruno Larsen (billionai)     return -1;
36435a5d74eSBruno Larsen (billionai) }
36535a5d74eSBruno Larsen (billionai) 
gdb_get_spr_reg(CPUState * cs,GByteArray * buf,int n)36666260159SAkihiko Odaki static int gdb_get_spr_reg(CPUState *cs, GByteArray *buf, int n)
36735a5d74eSBruno Larsen (billionai) {
36866260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
36966260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
37035a5d74eSBruno Larsen (billionai)     int reg;
37135a5d74eSBruno Larsen (billionai)     int len;
37235a5d74eSBruno Larsen (billionai) 
37335a5d74eSBruno Larsen (billionai)     reg = gdb_find_spr_idx(env, n);
37435a5d74eSBruno Larsen (billionai)     if (reg < 0) {
37535a5d74eSBruno Larsen (billionai)         return 0;
37635a5d74eSBruno Larsen (billionai)     }
37735a5d74eSBruno Larsen (billionai) 
37835a5d74eSBruno Larsen (billionai)     len = TARGET_LONG_SIZE;
3790c0fc268SSaif Abrar 
3800c0fc268SSaif Abrar     /* Handle those SPRs that are not part of the env->spr[] array */
3810c0fc268SSaif Abrar     target_ulong val;
3820c0fc268SSaif Abrar     switch (reg) {
3830c0fc268SSaif Abrar #if defined(TARGET_PPC64)
3840c0fc268SSaif Abrar     case SPR_CFAR:
3850c0fc268SSaif Abrar         val = env->cfar;
3860c0fc268SSaif Abrar         break;
3870c0fc268SSaif Abrar #endif
3880c0fc268SSaif Abrar     case SPR_HDEC:
3890c0fc268SSaif Abrar         val = cpu_ppc_load_hdecr(env);
3900c0fc268SSaif Abrar         break;
3910c0fc268SSaif Abrar     case SPR_TBL:
3920c0fc268SSaif Abrar         val = cpu_ppc_load_tbl(env);
3930c0fc268SSaif Abrar         break;
3940c0fc268SSaif Abrar     case SPR_TBU:
3950c0fc268SSaif Abrar         val = cpu_ppc_load_tbu(env);
3960c0fc268SSaif Abrar         break;
3970c0fc268SSaif Abrar     case SPR_DECR:
3980c0fc268SSaif Abrar         val = cpu_ppc_load_decr(env);
3990c0fc268SSaif Abrar         break;
4000c0fc268SSaif Abrar     default:
4010c0fc268SSaif Abrar         val = env->spr[reg];
4020c0fc268SSaif Abrar     }
4030c0fc268SSaif Abrar     gdb_get_regl(buf, val);
4040c0fc268SSaif Abrar 
40535a5d74eSBruno Larsen (billionai)     ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
40635a5d74eSBruno Larsen (billionai)     return len;
40735a5d74eSBruno Larsen (billionai) }
40835a5d74eSBruno Larsen (billionai) 
gdb_set_spr_reg(CPUState * cs,uint8_t * mem_buf,int n)40966260159SAkihiko Odaki static int gdb_set_spr_reg(CPUState *cs, uint8_t *mem_buf, int n)
41035a5d74eSBruno Larsen (billionai) {
41166260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
41266260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
41335a5d74eSBruno Larsen (billionai)     int reg;
41435a5d74eSBruno Larsen (billionai)     int len;
41535a5d74eSBruno Larsen (billionai) 
41635a5d74eSBruno Larsen (billionai)     reg = gdb_find_spr_idx(env, n);
41735a5d74eSBruno Larsen (billionai)     if (reg < 0) {
41835a5d74eSBruno Larsen (billionai)         return 0;
41935a5d74eSBruno Larsen (billionai)     }
42035a5d74eSBruno Larsen (billionai) 
42135a5d74eSBruno Larsen (billionai)     len = TARGET_LONG_SIZE;
42235a5d74eSBruno Larsen (billionai)     ppc_maybe_bswap_register(env, mem_buf, len);
4230c0fc268SSaif Abrar 
4240c0fc268SSaif Abrar     /* Handle those SPRs that are not part of the env->spr[] array */
4250c0fc268SSaif Abrar     target_ulong val = ldn_p(mem_buf, len);
4260c0fc268SSaif Abrar     switch (reg) {
4270c0fc268SSaif Abrar #if defined(TARGET_PPC64)
4280c0fc268SSaif Abrar     case SPR_CFAR:
4290c0fc268SSaif Abrar         env->cfar = val;
4300c0fc268SSaif Abrar         break;
4310c0fc268SSaif Abrar #endif
4320c0fc268SSaif Abrar     default:
4330c0fc268SSaif Abrar         env->spr[reg] = val;
4340c0fc268SSaif Abrar     }
43535a5d74eSBruno Larsen (billionai) 
43635a5d74eSBruno Larsen (billionai)     return len;
43735a5d74eSBruno Larsen (billionai) }
43835a5d74eSBruno Larsen (billionai) #endif
43935a5d74eSBruno Larsen (billionai) 
gdb_get_float_reg(CPUState * cs,GByteArray * buf,int n)44066260159SAkihiko Odaki static int gdb_get_float_reg(CPUState *cs, GByteArray *buf, int n)
44135a5d74eSBruno Larsen (billionai) {
44266260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
44366260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
44435a5d74eSBruno Larsen (billionai)     uint8_t *mem_buf;
44535a5d74eSBruno Larsen (billionai)     if (n < 32) {
44635a5d74eSBruno Larsen (billionai)         gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
44735a5d74eSBruno Larsen (billionai)         mem_buf = gdb_get_reg_ptr(buf, 8);
44835a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 8);
44935a5d74eSBruno Larsen (billionai)         return 8;
45035a5d74eSBruno Larsen (billionai)     }
45135a5d74eSBruno Larsen (billionai)     if (n == 32) {
45235a5d74eSBruno Larsen (billionai)         gdb_get_reg32(buf, env->fpscr);
45335a5d74eSBruno Larsen (billionai)         mem_buf = gdb_get_reg_ptr(buf, 4);
45435a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
45535a5d74eSBruno Larsen (billionai)         return 4;
45635a5d74eSBruno Larsen (billionai)     }
45735a5d74eSBruno Larsen (billionai)     return 0;
45835a5d74eSBruno Larsen (billionai) }
45935a5d74eSBruno Larsen (billionai) 
gdb_set_float_reg(CPUState * cs,uint8_t * mem_buf,int n)46066260159SAkihiko Odaki static int gdb_set_float_reg(CPUState *cs, uint8_t *mem_buf, int n)
46135a5d74eSBruno Larsen (billionai) {
46266260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
46366260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
46466260159SAkihiko Odaki 
46535a5d74eSBruno Larsen (billionai)     if (n < 32) {
46635a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 8);
46735a5d74eSBruno Larsen (billionai)         *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
46835a5d74eSBruno Larsen (billionai)         return 8;
46935a5d74eSBruno Larsen (billionai)     }
47035a5d74eSBruno Larsen (billionai)     if (n == 32) {
47135a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
472fe43ba97SBruno Larsen (billionai)         ppc_store_fpscr(env, ldl_p(mem_buf));
47335a5d74eSBruno Larsen (billionai)         return 4;
47435a5d74eSBruno Larsen (billionai)     }
47535a5d74eSBruno Larsen (billionai)     return 0;
47635a5d74eSBruno Larsen (billionai) }
47735a5d74eSBruno Larsen (billionai) 
gdb_get_avr_reg(CPUState * cs,GByteArray * buf,int n)47866260159SAkihiko Odaki static int gdb_get_avr_reg(CPUState *cs, GByteArray *buf, int n)
47935a5d74eSBruno Larsen (billionai) {
48066260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
48166260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
48235a5d74eSBruno Larsen (billionai)     uint8_t *mem_buf;
48335a5d74eSBruno Larsen (billionai) 
48435a5d74eSBruno Larsen (billionai)     if (n < 32) {
48535a5d74eSBruno Larsen (billionai)         ppc_avr_t *avr = cpu_avr_ptr(env, n);
4860ff16b6bSMatheus Ferst         gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
48735a5d74eSBruno Larsen (billionai)         mem_buf = gdb_get_reg_ptr(buf, 16);
4880ff16b6bSMatheus Ferst         ppc_maybe_bswap_register(env, mem_buf, 16);
48935a5d74eSBruno Larsen (billionai)         return 16;
49035a5d74eSBruno Larsen (billionai)     }
49135a5d74eSBruno Larsen (billionai)     if (n == 32) {
492c19940dbSBruno Larsen (billionai)         gdb_get_reg32(buf, ppc_get_vscr(env));
49335a5d74eSBruno Larsen (billionai)         mem_buf = gdb_get_reg_ptr(buf, 4);
49435a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
49535a5d74eSBruno Larsen (billionai)         return 4;
49635a5d74eSBruno Larsen (billionai)     }
49735a5d74eSBruno Larsen (billionai)     if (n == 33) {
49835a5d74eSBruno Larsen (billionai)         gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
49935a5d74eSBruno Larsen (billionai)         mem_buf = gdb_get_reg_ptr(buf, 4);
50035a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
50135a5d74eSBruno Larsen (billionai)         return 4;
50235a5d74eSBruno Larsen (billionai)     }
50335a5d74eSBruno Larsen (billionai)     return 0;
50435a5d74eSBruno Larsen (billionai) }
50535a5d74eSBruno Larsen (billionai) 
gdb_set_avr_reg(CPUState * cs,uint8_t * mem_buf,int n)50666260159SAkihiko Odaki static int gdb_set_avr_reg(CPUState *cs, uint8_t *mem_buf, int n)
50735a5d74eSBruno Larsen (billionai) {
50866260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
50966260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
51066260159SAkihiko Odaki 
51135a5d74eSBruno Larsen (billionai)     if (n < 32) {
51235a5d74eSBruno Larsen (billionai)         ppc_avr_t *avr = cpu_avr_ptr(env, n);
5130ff16b6bSMatheus Ferst         ppc_maybe_bswap_register(env, mem_buf, 16);
5140ff16b6bSMatheus Ferst         avr->VsrD(0) = ldq_p(mem_buf);
5150ff16b6bSMatheus Ferst         avr->VsrD(1) = ldq_p(mem_buf + 8);
51635a5d74eSBruno Larsen (billionai)         return 16;
51735a5d74eSBruno Larsen (billionai)     }
51835a5d74eSBruno Larsen (billionai)     if (n == 32) {
51935a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
520c19940dbSBruno Larsen (billionai)         ppc_store_vscr(env, ldl_p(mem_buf));
52135a5d74eSBruno Larsen (billionai)         return 4;
52235a5d74eSBruno Larsen (billionai)     }
52335a5d74eSBruno Larsen (billionai)     if (n == 33) {
52435a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
52535a5d74eSBruno Larsen (billionai)         env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
52635a5d74eSBruno Larsen (billionai)         return 4;
52735a5d74eSBruno Larsen (billionai)     }
52835a5d74eSBruno Larsen (billionai)     return 0;
52935a5d74eSBruno Larsen (billionai) }
53035a5d74eSBruno Larsen (billionai) 
gdb_get_spe_reg(CPUState * cs,GByteArray * buf,int n)53166260159SAkihiko Odaki static int gdb_get_spe_reg(CPUState *cs, GByteArray *buf, int n)
53235a5d74eSBruno Larsen (billionai) {
53366260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
53466260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
53566260159SAkihiko Odaki 
53635a5d74eSBruno Larsen (billionai)     if (n < 32) {
53735a5d74eSBruno Larsen (billionai) #if defined(TARGET_PPC64)
53835a5d74eSBruno Larsen (billionai)         gdb_get_reg32(buf, env->gpr[n] >> 32);
53935a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
54035a5d74eSBruno Larsen (billionai) #else
54135a5d74eSBruno Larsen (billionai)         gdb_get_reg32(buf, env->gprh[n]);
54235a5d74eSBruno Larsen (billionai) #endif
54335a5d74eSBruno Larsen (billionai)         return 4;
54435a5d74eSBruno Larsen (billionai)     }
54535a5d74eSBruno Larsen (billionai)     if (n == 32) {
54635a5d74eSBruno Larsen (billionai)         gdb_get_reg64(buf, env->spe_acc);
54735a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
54835a5d74eSBruno Larsen (billionai)         return 8;
54935a5d74eSBruno Larsen (billionai)     }
55035a5d74eSBruno Larsen (billionai)     if (n == 33) {
55135a5d74eSBruno Larsen (billionai)         gdb_get_reg32(buf, env->spe_fscr);
55235a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
55335a5d74eSBruno Larsen (billionai)         return 4;
55435a5d74eSBruno Larsen (billionai)     }
55535a5d74eSBruno Larsen (billionai)     return 0;
55635a5d74eSBruno Larsen (billionai) }
55735a5d74eSBruno Larsen (billionai) 
gdb_set_spe_reg(CPUState * cs,uint8_t * mem_buf,int n)55866260159SAkihiko Odaki static int gdb_set_spe_reg(CPUState *cs, uint8_t *mem_buf, int n)
55935a5d74eSBruno Larsen (billionai) {
56066260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
56166260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
56266260159SAkihiko Odaki 
56335a5d74eSBruno Larsen (billionai)     if (n < 32) {
56435a5d74eSBruno Larsen (billionai) #if defined(TARGET_PPC64)
56535a5d74eSBruno Larsen (billionai)         target_ulong lo = (uint32_t)env->gpr[n];
56635a5d74eSBruno Larsen (billionai)         target_ulong hi;
56735a5d74eSBruno Larsen (billionai) 
56835a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
56935a5d74eSBruno Larsen (billionai) 
57035a5d74eSBruno Larsen (billionai)         hi = (target_ulong)ldl_p(mem_buf) << 32;
57135a5d74eSBruno Larsen (billionai)         env->gpr[n] = lo | hi;
57235a5d74eSBruno Larsen (billionai) #else
57335a5d74eSBruno Larsen (billionai)         env->gprh[n] = ldl_p(mem_buf);
57435a5d74eSBruno Larsen (billionai) #endif
57535a5d74eSBruno Larsen (billionai)         return 4;
57635a5d74eSBruno Larsen (billionai)     }
57735a5d74eSBruno Larsen (billionai)     if (n == 32) {
57835a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 8);
57935a5d74eSBruno Larsen (billionai)         env->spe_acc = ldq_p(mem_buf);
58035a5d74eSBruno Larsen (billionai)         return 8;
58135a5d74eSBruno Larsen (billionai)     }
58235a5d74eSBruno Larsen (billionai)     if (n == 33) {
58335a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 4);
58435a5d74eSBruno Larsen (billionai)         env->spe_fscr = ldl_p(mem_buf);
58535a5d74eSBruno Larsen (billionai)         return 4;
58635a5d74eSBruno Larsen (billionai)     }
58735a5d74eSBruno Larsen (billionai)     return 0;
58835a5d74eSBruno Larsen (billionai) }
58935a5d74eSBruno Larsen (billionai) 
gdb_get_vsx_reg(CPUState * cs,GByteArray * buf,int n)59066260159SAkihiko Odaki static int gdb_get_vsx_reg(CPUState *cs, GByteArray *buf, int n)
59135a5d74eSBruno Larsen (billionai) {
59266260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
59366260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
59466260159SAkihiko Odaki 
59535a5d74eSBruno Larsen (billionai)     if (n < 32) {
59635a5d74eSBruno Larsen (billionai)         gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
59735a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
59835a5d74eSBruno Larsen (billionai)         return 8;
59935a5d74eSBruno Larsen (billionai)     }
60035a5d74eSBruno Larsen (billionai)     return 0;
60135a5d74eSBruno Larsen (billionai) }
60235a5d74eSBruno Larsen (billionai) 
gdb_set_vsx_reg(CPUState * cs,uint8_t * mem_buf,int n)60366260159SAkihiko Odaki static int gdb_set_vsx_reg(CPUState *cs, uint8_t *mem_buf, int n)
60435a5d74eSBruno Larsen (billionai) {
60566260159SAkihiko Odaki     PowerPCCPU *cpu = POWERPC_CPU(cs);
60666260159SAkihiko Odaki     CPUPPCState *env = &cpu->env;
60766260159SAkihiko Odaki 
60835a5d74eSBruno Larsen (billionai)     if (n < 32) {
60935a5d74eSBruno Larsen (billionai)         ppc_maybe_bswap_register(env, mem_buf, 8);
61035a5d74eSBruno Larsen (billionai)         *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
61135a5d74eSBruno Larsen (billionai)         return 8;
61235a5d74eSBruno Larsen (billionai)     }
61335a5d74eSBruno Larsen (billionai)     return 0;
61435a5d74eSBruno Larsen (billionai) }
61535a5d74eSBruno Larsen (billionai) 
ppc_gdb_arch_name(CPUState * cs)616a6506838SAkihiko Odaki const gchar *ppc_gdb_arch_name(CPUState *cs)
61735a5d74eSBruno Larsen (billionai) {
61835a5d74eSBruno Larsen (billionai) #if defined(TARGET_PPC64)
619a6506838SAkihiko Odaki     return "powerpc:common64";
62035a5d74eSBruno Larsen (billionai) #else
621a6506838SAkihiko Odaki     return "powerpc:common";
62235a5d74eSBruno Larsen (billionai) #endif
62335a5d74eSBruno Larsen (billionai) }
62435a5d74eSBruno Larsen (billionai) 
ppc_gdb_init(CPUState * cs,PowerPCCPUClass * pcc)62535a5d74eSBruno Larsen (billionai) void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
62635a5d74eSBruno Larsen (billionai) {
62735a5d74eSBruno Larsen (billionai)     if (pcc->insns_flags & PPC_FLOAT) {
62835a5d74eSBruno Larsen (billionai)         gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
629ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("power-fpu.xml"), 0);
63035a5d74eSBruno Larsen (billionai)     }
63135a5d74eSBruno Larsen (billionai)     if (pcc->insns_flags & PPC_ALTIVEC) {
63235a5d74eSBruno Larsen (billionai)         gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
633ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("power-altivec.xml"),
634ac1e8671SAkihiko Odaki                                  0);
63535a5d74eSBruno Larsen (billionai)     }
63635a5d74eSBruno Larsen (billionai)     if (pcc->insns_flags & PPC_SPE) {
63735a5d74eSBruno Larsen (billionai)         gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
638ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("power-spe.xml"), 0);
63935a5d74eSBruno Larsen (billionai)     }
64035a5d74eSBruno Larsen (billionai)     if (pcc->insns_flags2 & PPC2_VSX) {
64135a5d74eSBruno Larsen (billionai)         gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
642ac1e8671SAkihiko Odaki                                  gdb_find_static_feature("power-vsx.xml"), 0);
64335a5d74eSBruno Larsen (billionai)     }
64435a5d74eSBruno Larsen (billionai) #ifndef CONFIG_USER_ONLY
6451b53948fSAkihiko Odaki     gdb_gen_spr_feature(cs);
64635a5d74eSBruno Larsen (billionai)     gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
647ac1e8671SAkihiko Odaki                              &pcc->gdb_spr, 0);
64835a5d74eSBruno Larsen (billionai) #endif
64935a5d74eSBruno Larsen (billionai) }
650