xref: /openbmc/qemu/target/sparc/gdbstub.c (revision 1ccd6e13ccc0913bd3750f47c697c3d7c31cd418)
1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth  * SPARC 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
105650b549SChetan 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"
224ea5fe99SAlex Bennée #include "gdbstub/helpers.h"
23fcf5ef2aSThomas Huth 
24fcf5ef2aSThomas Huth #ifdef TARGET_ABI32
25fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_reg32(buf, val)
26fcf5ef2aSThomas Huth #else
27fcf5ef2aSThomas Huth #define gdb_get_rega(buf, val) gdb_get_regl(buf, val)
28fcf5ef2aSThomas Huth #endif
29fcf5ef2aSThomas Huth 
30a010bdbeSAlex Bennée int sparc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
31fcf5ef2aSThomas Huth {
32fcf5ef2aSThomas Huth     SPARCCPU *cpu = SPARC_CPU(cs);
33fcf5ef2aSThomas Huth     CPUSPARCState *env = &cpu->env;
34fcf5ef2aSThomas Huth 
35fcf5ef2aSThomas Huth     if (n < 8) {
36fcf5ef2aSThomas Huth         /* g0..g7 */
37fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->gregs[n]);
38fcf5ef2aSThomas Huth     }
39fcf5ef2aSThomas Huth     if (n < 32) {
40fcf5ef2aSThomas Huth         /* register window */
41fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->regwptr[n - 8]);
42fcf5ef2aSThomas Huth     }
43fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
44fcf5ef2aSThomas Huth     if (n < 64) {
45fcf5ef2aSThomas Huth         /* fprs */
46fcf5ef2aSThomas Huth         if (n & 1) {
47fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
48fcf5ef2aSThomas Huth         } else {
49fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
50fcf5ef2aSThomas Huth         }
51fcf5ef2aSThomas Huth     }
52fcf5ef2aSThomas Huth     /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
53fcf5ef2aSThomas Huth     switch (n) {
54fcf5ef2aSThomas Huth     case 64:
55fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->y);
56fcf5ef2aSThomas Huth     case 65:
57fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, cpu_get_psr(env));
58fcf5ef2aSThomas Huth     case 66:
59fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->wim);
60fcf5ef2aSThomas Huth     case 67:
61fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->tbr);
62fcf5ef2aSThomas Huth     case 68:
63fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->pc);
64fcf5ef2aSThomas Huth     case 69:
65fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, env->npc);
66fcf5ef2aSThomas Huth     case 70:
67*1ccd6e13SRichard Henderson         return gdb_get_rega(mem_buf, cpu_get_fsr(env));
68fcf5ef2aSThomas Huth     case 71:
69fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, 0); /* csr */
70fcf5ef2aSThomas Huth     default:
71fcf5ef2aSThomas Huth         return gdb_get_rega(mem_buf, 0);
72fcf5ef2aSThomas Huth     }
73fcf5ef2aSThomas Huth #else
74fcf5ef2aSThomas Huth     if (n < 64) {
75fcf5ef2aSThomas Huth         /* f0-f31 */
76fcf5ef2aSThomas Huth         if (n & 1) {
77fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.lower);
78fcf5ef2aSThomas Huth         } else {
79fcf5ef2aSThomas Huth             return gdb_get_reg32(mem_buf, env->fpr[(n - 32) / 2].l.upper);
80fcf5ef2aSThomas Huth         }
81fcf5ef2aSThomas Huth     }
82fcf5ef2aSThomas Huth     if (n < 80) {
83fcf5ef2aSThomas Huth         /* f32-f62 (double width, even numbers only) */
84fcf5ef2aSThomas Huth         return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
85fcf5ef2aSThomas Huth     }
86fcf5ef2aSThomas Huth     switch (n) {
87fcf5ef2aSThomas Huth     case 80:
88fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->pc);
89fcf5ef2aSThomas Huth     case 81:
90fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->npc);
91fcf5ef2aSThomas Huth     case 82:
92fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
93fcf5ef2aSThomas Huth                                      ((env->asi & 0xff) << 24) |
94fcf5ef2aSThomas Huth                                      ((env->pstate & 0xfff) << 8) |
95fcf5ef2aSThomas Huth                                      cpu_get_cwp64(env));
96fcf5ef2aSThomas Huth     case 83:
97*1ccd6e13SRichard Henderson         return gdb_get_regl(mem_buf, cpu_get_fsr(env));
98fcf5ef2aSThomas Huth     case 84:
99fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->fprs);
100fcf5ef2aSThomas Huth     case 85:
101fcf5ef2aSThomas Huth         return gdb_get_regl(mem_buf, env->y);
102fcf5ef2aSThomas Huth     }
103fcf5ef2aSThomas Huth #endif
104fcf5ef2aSThomas Huth     return 0;
105fcf5ef2aSThomas Huth }
106fcf5ef2aSThomas Huth 
107fcf5ef2aSThomas Huth int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
108fcf5ef2aSThomas Huth {
109fcf5ef2aSThomas Huth     SPARCCPU *cpu = SPARC_CPU(cs);
110fcf5ef2aSThomas Huth     CPUSPARCState *env = &cpu->env;
111fcf5ef2aSThomas Huth #if defined(TARGET_ABI32)
112fcf5ef2aSThomas Huth     abi_ulong tmp;
113fcf5ef2aSThomas Huth 
114fcf5ef2aSThomas Huth     tmp = ldl_p(mem_buf);
115fcf5ef2aSThomas Huth #else
116fcf5ef2aSThomas Huth     target_ulong tmp;
117fcf5ef2aSThomas Huth 
118fcf5ef2aSThomas Huth     tmp = ldtul_p(mem_buf);
119fcf5ef2aSThomas Huth #endif
120fcf5ef2aSThomas Huth 
121fcf5ef2aSThomas Huth     if (n < 8) {
122fcf5ef2aSThomas Huth         /* g0..g7 */
123fcf5ef2aSThomas Huth         env->gregs[n] = tmp;
124fcf5ef2aSThomas Huth     } else if (n < 32) {
125fcf5ef2aSThomas Huth         /* register window */
126fcf5ef2aSThomas Huth         env->regwptr[n - 8] = tmp;
127fcf5ef2aSThomas Huth     }
128fcf5ef2aSThomas Huth #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
129fcf5ef2aSThomas Huth     else if (n < 64) {
130fcf5ef2aSThomas Huth         /* fprs */
131fcf5ef2aSThomas Huth         /* f0-f31 */
132fcf5ef2aSThomas Huth         if (n & 1) {
133fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.lower = tmp;
134fcf5ef2aSThomas Huth         } else {
135fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.upper = tmp;
136fcf5ef2aSThomas Huth         }
137fcf5ef2aSThomas Huth     } else {
138fcf5ef2aSThomas Huth         /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
139fcf5ef2aSThomas Huth         switch (n) {
140fcf5ef2aSThomas Huth         case 64:
141fcf5ef2aSThomas Huth             env->y = tmp;
142fcf5ef2aSThomas Huth             break;
143fcf5ef2aSThomas Huth         case 65:
144fcf5ef2aSThomas Huth             cpu_put_psr(env, tmp);
145fcf5ef2aSThomas Huth             break;
146fcf5ef2aSThomas Huth         case 66:
147fcf5ef2aSThomas Huth             env->wim = tmp;
148fcf5ef2aSThomas Huth             break;
149fcf5ef2aSThomas Huth         case 67:
150fcf5ef2aSThomas Huth             env->tbr = tmp;
151fcf5ef2aSThomas Huth             break;
152fcf5ef2aSThomas Huth         case 68:
153fcf5ef2aSThomas Huth             env->pc = tmp;
154fcf5ef2aSThomas Huth             break;
155fcf5ef2aSThomas Huth         case 69:
156fcf5ef2aSThomas Huth             env->npc = tmp;
157fcf5ef2aSThomas Huth             break;
158fcf5ef2aSThomas Huth         case 70:
159*1ccd6e13SRichard Henderson             cpu_put_fsr(env, tmp);
160fcf5ef2aSThomas Huth             break;
161fcf5ef2aSThomas Huth         default:
162fcf5ef2aSThomas Huth             return 0;
163fcf5ef2aSThomas Huth         }
164fcf5ef2aSThomas Huth     }
165fcf5ef2aSThomas Huth     return 4;
166fcf5ef2aSThomas Huth #else
167fcf5ef2aSThomas Huth     else if (n < 64) {
168fcf5ef2aSThomas Huth         /* f0-f31 */
169fcf5ef2aSThomas Huth         tmp = ldl_p(mem_buf);
170fcf5ef2aSThomas Huth         if (n & 1) {
171fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.lower = tmp;
172fcf5ef2aSThomas Huth         } else {
173fcf5ef2aSThomas Huth             env->fpr[(n - 32) / 2].l.upper = tmp;
174fcf5ef2aSThomas Huth         }
175fcf5ef2aSThomas Huth         return 4;
176fcf5ef2aSThomas Huth     } else if (n < 80) {
177fcf5ef2aSThomas Huth         /* f32-f62 (double width, even numbers only) */
178fcf5ef2aSThomas Huth         env->fpr[(n - 32) / 2].ll = tmp;
179fcf5ef2aSThomas Huth     } else {
180fcf5ef2aSThomas Huth         switch (n) {
181fcf5ef2aSThomas Huth         case 80:
182fcf5ef2aSThomas Huth             env->pc = tmp;
183fcf5ef2aSThomas Huth             break;
184fcf5ef2aSThomas Huth         case 81:
185fcf5ef2aSThomas Huth             env->npc = tmp;
186fcf5ef2aSThomas Huth             break;
187fcf5ef2aSThomas Huth         case 82:
188fcf5ef2aSThomas Huth             cpu_put_ccr(env, tmp >> 32);
189fcf5ef2aSThomas Huth             env->asi = (tmp >> 24) & 0xff;
190fcf5ef2aSThomas Huth             env->pstate = (tmp >> 8) & 0xfff;
191fcf5ef2aSThomas Huth             cpu_put_cwp64(env, tmp & 0xff);
192fcf5ef2aSThomas Huth             break;
193fcf5ef2aSThomas Huth         case 83:
194*1ccd6e13SRichard Henderson             cpu_put_fsr(env, tmp);
195fcf5ef2aSThomas Huth             break;
196fcf5ef2aSThomas Huth         case 84:
197fcf5ef2aSThomas Huth             env->fprs = tmp;
198fcf5ef2aSThomas Huth             break;
199fcf5ef2aSThomas Huth         case 85:
200fcf5ef2aSThomas Huth             env->y = tmp;
201fcf5ef2aSThomas Huth             break;
202fcf5ef2aSThomas Huth         default:
203fcf5ef2aSThomas Huth             return 0;
204fcf5ef2aSThomas Huth         }
205fcf5ef2aSThomas Huth     }
206fcf5ef2aSThomas Huth     return 8;
207fcf5ef2aSThomas Huth #endif
208fcf5ef2aSThomas Huth }
209