xref: /openbmc/qemu/target/sparc/gdbstub.c (revision 5f69e42d)
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 
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 (double width, even numbers only) */
83         return gdb_get_reg64(mem_buf, env->fpr[(n - 32) / 2].ll);
84     }
85     switch (n) {
86     case 80:
87         return gdb_get_regl(mem_buf, env->pc);
88     case 81:
89         return gdb_get_regl(mem_buf, env->npc);
90     case 82:
91         return gdb_get_regl(mem_buf, (cpu_get_ccr(env) << 32) |
92                                      ((env->asi & 0xff) << 24) |
93                                      ((env->pstate & 0xfff) << 8) |
94                                      cpu_get_cwp64(env));
95     case 83:
96         return gdb_get_regl(mem_buf, cpu_get_fsr(env));
97     case 84:
98         return gdb_get_regl(mem_buf, env->fprs);
99     case 85:
100         return gdb_get_regl(mem_buf, env->y);
101     }
102 #endif
103     return 0;
104 }
105 
106 int sparc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
107 {
108     SPARCCPU *cpu = SPARC_CPU(cs);
109     CPUSPARCState *env = &cpu->env;
110 #if defined(TARGET_ABI32)
111     uint32_t tmp;
112 
113     tmp = ldl_p(mem_buf);
114 #else
115     target_ulong tmp;
116 
117     tmp = ldtul_p(mem_buf);
118 #endif
119 
120     if (n < 8) {
121         /* g0..g7 */
122         env->gregs[n] = tmp;
123     } else if (n < 32) {
124         /* register window */
125         env->regwptr[n - 8] = tmp;
126     }
127 #if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
128     else if (n < 64) {
129         /* fprs */
130         /* f0-f31 */
131         if (n & 1) {
132             env->fpr[(n - 32) / 2].l.lower = tmp;
133         } else {
134             env->fpr[(n - 32) / 2].l.upper = tmp;
135         }
136     } else {
137         /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
138         switch (n) {
139         case 64:
140             env->y = tmp;
141             break;
142         case 65:
143             cpu_put_psr(env, tmp);
144             break;
145         case 66:
146             env->wim = tmp;
147             break;
148         case 67:
149             env->tbr = tmp;
150             break;
151         case 68:
152             env->pc = tmp;
153             break;
154         case 69:
155             env->npc = tmp;
156             break;
157         case 70:
158             cpu_put_fsr(env, tmp);
159             break;
160         default:
161             return 0;
162         }
163     }
164     return 4;
165 #else
166     else if (n < 64) {
167         /* f0-f31 */
168         tmp = ldl_p(mem_buf);
169         if (n & 1) {
170             env->fpr[(n - 32) / 2].l.lower = tmp;
171         } else {
172             env->fpr[(n - 32) / 2].l.upper = tmp;
173         }
174         return 4;
175     } else if (n < 80) {
176         /* f32-f62 (double width, even numbers only) */
177         env->fpr[(n - 32) / 2].ll = tmp;
178     } else {
179         switch (n) {
180         case 80:
181             env->pc = tmp;
182             break;
183         case 81:
184             env->npc = tmp;
185             break;
186         case 82:
187             cpu_put_ccr(env, tmp >> 32);
188             env->asi = (tmp >> 24) & 0xff;
189             env->pstate = (tmp >> 8) & 0xfff;
190             cpu_put_cwp64(env, tmp & 0xff);
191             break;
192         case 83:
193             cpu_put_fsr(env, tmp);
194             break;
195         case 84:
196             env->fprs = tmp;
197             break;
198         case 85:
199             env->y = tmp;
200             break;
201         default:
202             return 0;
203         }
204     }
205     return 8;
206 #endif
207 }
208