master
c 300 lines 6.43 KB
Raw
1 /*
2 * HPPA gdb server stub
3 *
4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "gdbstub/helpers.h"
23
24 static int hppa_num_regs(CPUHPPAState *env)
25 {
26 return hppa_is_pa20(env) ? 96 : 128;
27 }
28
29 static int hppa_reg_size(CPUHPPAState *env)
30 {
31 return hppa_is_pa20(env) ? 8 : 4;
32 }
33
34 int hppa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
35 {
36 CPUHPPAState *env = cpu_env(cs);
37 target_ulong val;
38
39 if (n >= hppa_num_regs(env)) {
40 return 0;
41 }
42
43 switch (n) {
44 case 0:
45 val = cpu_hppa_get_psw(env);
46 break;
47 case 1 ... 31:
48 val = env->gr[n];
49 break;
50 case 32:
51 val = env->cr[CR_SAR];
52 break;
53 case 33:
54 val = env->iaoq_f;
55 break;
56 case 34:
57 val = env->iasq_f >> 32;
58 break;
59 case 35:
60 val = env->iaoq_b;
61 break;
62 case 36:
63 val = env->iasq_b >> 32;
64 break;
65 case 37:
66 val = env->cr[CR_EIEM];
67 break;
68 case 38:
69 val = env->cr[CR_IIR];
70 break;
71 case 39:
72 val = env->cr[CR_ISR];
73 break;
74 case 40:
75 val = env->cr[CR_IOR];
76 break;
77 case 41:
78 val = env->cr[CR_IPSW];
79 break;
80 case 43:
81 val = env->sr[4] >> 32;
82 break;
83 case 44:
84 val = env->sr[0] >> 32;
85 break;
86 case 45:
87 val = env->sr[1] >> 32;
88 break;
89 case 46:
90 val = env->sr[2] >> 32;
91 break;
92 case 47:
93 val = env->sr[3] >> 32;
94 break;
95 case 48:
96 val = env->sr[5] >> 32;
97 break;
98 case 49:
99 val = env->sr[6] >> 32;
100 break;
101 case 50:
102 val = env->sr[7] >> 32;
103 break;
104 case 51:
105 val = env->cr[CR_RC];
106 break;
107 case 52:
108 val = env->cr[CR_PID1];
109 break;
110 case 53:
111 val = env->cr[CR_PID2];
112 break;
113 case 54:
114 val = env->cr[CR_SCRCCR];
115 break;
116 case 55:
117 val = env->cr[CR_PID3];
118 break;
119 case 56:
120 val = env->cr[CR_PID4];
121 break;
122 case 57:
123 val = env->cr[24];
124 break;
125 case 58:
126 val = env->cr[25];
127 break;
128 case 59:
129 val = env->cr[26];
130 break;
131 case 60:
132 val = env->cr[27];
133 break;
134 case 61:
135 val = env->cr[28];
136 break;
137 case 62:
138 val = env->cr[29];
139 break;
140 case 63:
141 val = env->cr[30];
142 break;
143 case 64 ... 127:
144 if (hppa_is_pa20(env)) {
145 val = env->fr[n - 64];
146 } else {
147 val = extract64(env->fr[(n - 64) / 2], (n & 1 ? 0 : 32), 32);
148 }
149 break;
150 default:
151 val = 0;
152 break;
153 }
154
155 if (hppa_is_pa20(env)) {
156 return gdb_get_reg64(mem_buf, val);
157 } else {
158 return gdb_get_reg32(mem_buf, val);
159 }
160 }
161
162 int hppa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
163 {
164 CPUHPPAState *env = cpu_env(cs);
165 target_ulong val;
166
167 if (n >= hppa_num_regs(env)) {
168 return 0;
169 }
170
171 val = ldn_be_p(mem_buf, hppa_reg_size(env));
172
173 switch (n) {
174 case 0:
175 cpu_hppa_put_psw(env, val);
176 break;
177 case 1 ... 31:
178 env->gr[n] = val;
179 break;
180 case 32:
181 env->cr[CR_SAR] = val & (hppa_is_pa20(env) ? 63 : 31);
182 break;
183 case 33:
184 #ifdef CONFIG_USER_ONLY
185 val |= PRIV_USER;
186 #endif
187 env->iaoq_f = val;
188 break;
189 case 34:
190 env->iasq_f = (uint64_t)val << 32;
191 break;
192 case 35:
193 #ifdef CONFIG_USER_ONLY
194 val |= PRIV_USER;
195 #endif
196 env->iaoq_b = val;
197 break;
198 case 36:
199 env->iasq_b = (uint64_t)val << 32;
200 break;
201 case 37:
202 env->cr[CR_EIEM] = val;
203 break;
204 case 38:
205 env->cr[CR_IIR] = val;
206 break;
207 case 39:
208 env->cr[CR_ISR] = val;
209 break;
210 case 40:
211 env->cr[CR_IOR] = val;
212 break;
213 case 41:
214 env->cr[CR_IPSW] = val;
215 break;
216 case 43:
217 env->sr[4] = (uint64_t)val << 32;
218 break;
219 case 44:
220 env->sr[0] = (uint64_t)val << 32;
221 break;
222 case 45:
223 env->sr[1] = (uint64_t)val << 32;
224 break;
225 case 46:
226 env->sr[2] = (uint64_t)val << 32;
227 break;
228 case 47:
229 env->sr[3] = (uint64_t)val << 32;
230 break;
231 case 48:
232 env->sr[5] = (uint64_t)val << 32;
233 break;
234 case 49:
235 env->sr[6] = (uint64_t)val << 32;
236 break;
237 case 50:
238 env->sr[7] = (uint64_t)val << 32;
239 break;
240 case 51:
241 env->cr[CR_RC] = val;
242 break;
243 case 52:
244 env->cr[CR_PID1] = val;
245 cpu_hppa_change_prot_id(env);
246 break;
247 case 53:
248 env->cr[CR_PID2] = val;
249 cpu_hppa_change_prot_id(env);
250 break;
251 case 54:
252 env->cr[CR_SCRCCR] = val;
253 break;
254 case 55:
255 env->cr[CR_PID3] = val;
256 cpu_hppa_change_prot_id(env);
257 break;
258 case 56:
259 env->cr[CR_PID4] = val;
260 cpu_hppa_change_prot_id(env);
261 break;
262 case 57:
263 env->cr[24] = val;
264 break;
265 case 58:
266 env->cr[25] = val;
267 break;
268 case 59:
269 env->cr[26] = val;
270 break;
271 case 60:
272 env->cr[27] = val;
273 break;
274 case 61:
275 env->cr[28] = val;
276 break;
277 case 62:
278 env->cr[29] = val;
279 break;
280 case 63:
281 env->cr[30] = val;
282 break;
283 case 64:
284 env->fr[0] = deposit64(env->fr[0], 32, 32, val);
285 cpu_hppa_loaded_fr0(env);
286 break;
287 case 65 ... 127:
288 if (hppa_is_pa20(env)) {
289 env->fr[n - 64] = val;
290 } else {
291 uint64_t *fr = &env->fr[(n - 64) / 2];
292 *fr = deposit64(*fr, (n & 1 ? 0 : 32), 32, val);
293 }
294 break;
295 default:
296 break;
297 }
298
299 return hppa_reg_size(env);
300 }