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