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 (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
sparc_cpu_gdb_write_register(CPUState * cs,uint8_t * mem_buf,int n)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