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