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