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