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