gdbserver/s390: Add fast tracepoint support.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-s390-ipa.c
CommitLineData
abd9baf9
MK
1/* GNU/Linux S/390 specific low level interface, for the in-process
2 agent library for GDB.
3
4 Copyright (C) 2016 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include "server.h"
22#include "tracepoint.h"
23#include "linux-s390-tdesc.h"
24
25#define FT_FPR(x) (0x000 + (x) * 0x10)
26#define FT_VR(x) (0x000 + (x) * 0x10)
27#define FT_VR_L(x) (0x008 + (x) * 0x10)
28#define FT_GPR(x) (0x200 + (x) * 8)
29#define FT_GPR_U(x) (0x200 + (x) * 8)
30#define FT_GPR_L(x) (0x204 + (x) * 8)
31#define FT_GPR(x) (0x200 + (x) * 8)
32#define FT_ACR(x) (0x280 + (x) * 4)
33#define FT_PSWM 0x2c0
34#define FT_PSWM_U 0x2c0
35#define FT_PSWA 0x2c8
36#define FT_PSWA_L 0x2cc
37#define FT_FPC 0x2d0
38
39/* Mappings between registers collected by the jump pad and GDB's register
40 array layout used by regcache.
41
42 See linux-s390-low.c (s390_install_fast_tracepoint_jump_pad) for more
43 details. */
44
45#ifndef __s390x__
46
47/* Used for s390-linux32, s390-linux32v1, s390-linux32v2. */
48
49static const int s390_linux32_ft_collect_regmap[] = {
50 /* 32-bit PSWA and PSWM. */
51 FT_PSWM_U, FT_PSWA_L,
52 /* 32-bit GPRs (mapped to lower halves of 64-bit slots). */
53 FT_GPR_L (0), FT_GPR_L (1), FT_GPR_L (2), FT_GPR_L (3),
54 FT_GPR_L (4), FT_GPR_L (5), FT_GPR_L (6), FT_GPR_L (7),
55 FT_GPR_L (8), FT_GPR_L (9), FT_GPR_L (10), FT_GPR_L (11),
56 FT_GPR_L (12), FT_GPR_L (13), FT_GPR_L (14), FT_GPR_L (15),
57 /* ACRs */
58 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
59 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
60 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
61 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
62 /* FPRs (mapped to upper halves of 128-bit VR slots). */
63 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
64 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
65 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
66 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
67 /* orig_r2, last_break, system_call */
68 -1, -1, -1,
69};
70
71/* Used for s390-linux64, s390-linux64v1, s390-linux64v2, s390-vx-linux64. */
72
73static const int s390_linux64_ft_collect_regmap[] = {
74 /* 32-bit PSWA and PSWM. */
75 FT_PSWM_U, FT_PSWA_L,
76 /* 32-bit halves of 64-bit GPRs. */
77 FT_GPR_U (0), FT_GPR_L (0),
78 FT_GPR_U (1), FT_GPR_L (1),
79 FT_GPR_U (2), FT_GPR_L (2),
80 FT_GPR_U (3), FT_GPR_L (3),
81 FT_GPR_U (4), FT_GPR_L (4),
82 FT_GPR_U (5), FT_GPR_L (5),
83 FT_GPR_U (6), FT_GPR_L (6),
84 FT_GPR_U (7), FT_GPR_L (7),
85 FT_GPR_U (8), FT_GPR_L (8),
86 FT_GPR_U (9), FT_GPR_L (9),
87 FT_GPR_U (10), FT_GPR_L (10),
88 FT_GPR_U (11), FT_GPR_L (11),
89 FT_GPR_U (12), FT_GPR_L (12),
90 FT_GPR_U (13), FT_GPR_L (13),
91 FT_GPR_U (14), FT_GPR_L (14),
92 FT_GPR_U (15), FT_GPR_L (15),
93 /* ACRs */
94 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
95 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
96 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
97 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
98 /* FPRs (mapped to upper halves of 128-bit VR slots). */
99 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
100 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
101 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
102 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
103 /* orig_r2, last_break, system_call */
104 -1, -1, -1,
105 /* Lower halves of 128-bit VRs. */
106 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
107 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
108 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
109 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
110 /* And the next 16 VRs. */
111 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
112 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
113 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
114 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
115};
116
117/* Used for s390-te-linux64, s390-tevx-linux64. */
118
119static const int s390_te_linux64_ft_collect_regmap[] = {
120 /* 32-bit PSWA and PSWM. */
121 FT_PSWM_U, FT_PSWA_L,
122 /* 32-bit halves of 64-bit GPRs. */
123 FT_GPR_U (0), FT_GPR_L (0),
124 FT_GPR_U (1), FT_GPR_L (1),
125 FT_GPR_U (2), FT_GPR_L (2),
126 FT_GPR_U (3), FT_GPR_L (3),
127 FT_GPR_U (4), FT_GPR_L (4),
128 FT_GPR_U (5), FT_GPR_L (5),
129 FT_GPR_U (6), FT_GPR_L (6),
130 FT_GPR_U (7), FT_GPR_L (7),
131 FT_GPR_U (8), FT_GPR_L (8),
132 FT_GPR_U (9), FT_GPR_L (9),
133 FT_GPR_U (10), FT_GPR_L (10),
134 FT_GPR_U (11), FT_GPR_L (11),
135 FT_GPR_U (12), FT_GPR_L (12),
136 FT_GPR_U (13), FT_GPR_L (13),
137 FT_GPR_U (14), FT_GPR_L (14),
138 FT_GPR_U (15), FT_GPR_L (15),
139 /* ACRs */
140 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
141 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
142 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
143 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
144 /* FPRs (mapped to upper halves of 128-bit VR slots). */
145 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
146 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
147 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
148 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
149 /* orig_r2, last_break, system_call */
150 -1, -1, -1,
151 /* TDB */
152 -1, -1, -1, -1,
153 -1, -1, -1, -1,
154 -1, -1, -1, -1,
155 -1, -1, -1, -1,
156 -1, -1, -1, -1,
157 /* Lower halves of 128-bit VRs. */
158 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
159 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
160 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
161 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
162 /* And the next 16 VRs. */
163 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
164 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
165 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
166 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
167};
168
169#else /* __s390x__ */
170
171/* Used for s390x-linux64, s390x-linux64v1, s390x-linux64v2, s390x-vx-linux64. */
172
173static const int s390x_ft_collect_regmap[] = {
174 /* 64-bit PSWA and PSWM. */
175 FT_PSWM, FT_PSWA,
176 /* 64-bit GPRs. */
177 FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3),
178 FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7),
179 FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11),
180 FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15),
181 /* ACRs */
182 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
183 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
184 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
185 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
186 /* FPRs (mapped to upper halves of 128-bit VR slots). */
187 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
188 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
189 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
190 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
191 /* orig_r2, last_break, system_call */
192 -1, -1, -1,
193 /* Lower halves of 128-bit VRs. */
194 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
195 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
196 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
197 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
198 /* And the next 16 VRs. */
199 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
200 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
201 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
202 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
203};
204
205/* Used for s390x-te-linux64, s390x-tevx-linux64. */
206
207static const int s390x_te_ft_collect_regmap[] = {
208 /* 64-bit PSWA and PSWM. */
209 FT_PSWM, FT_PSWA,
210 /* 64-bit GPRs. */
211 FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3),
212 FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7),
213 FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11),
214 FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15),
215 /* ACRs */
216 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
217 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
218 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
219 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
220 /* FPRs (mapped to upper halves of 128-bit VR slots). */
221 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
222 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
223 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
224 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
225 /* orig_r2, last_break, system_call */
226 -1, -1, -1,
227 /* TDB */
228 -1, -1, -1, -1,
229 -1, -1, -1, -1,
230 -1, -1, -1, -1,
231 -1, -1, -1, -1,
232 -1, -1, -1, -1,
233 /* Lower halves of 128-bit VRs. */
234 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
235 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
236 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
237 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
238 /* And the next 16 VRs. */
239 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
240 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
241 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
242 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
243};
244
245#endif
246
247/* Initialized by get_ipa_tdesc according to the tdesc in use. */
248
249static const int *s390_regmap;
250static int s390_regnum;
251
252/* Fill in REGCACHE with registers saved by the jump pad in BUF. */
253
254void
255supply_fast_tracepoint_registers (struct regcache *regcache,
256 const unsigned char *buf)
257{
258 int i;
259 for (i = 0; i < s390_regnum; i++)
260 if (s390_regmap[i] != -1)
261 supply_register (regcache, i, ((char *) buf) + s390_regmap[i]);
262}
263
264IP_AGENT_EXPORT_FUNC ULONGEST
265gdb_agent_get_raw_reg (const unsigned char *raw_regs, int regnum)
266{
267 int offset;
268 if (regnum >= s390_regnum)
269 return 0;
270 offset = s390_regmap[regnum];
271 if (offset == -1)
272 return 0;
273
274 /* The regnums are variable, better to figure out size by FT offset. */
275
276 /* 64-bit ones. */
277 if (offset < FT_VR(16)
278#ifdef __s390x__
279 || (offset >= FT_GPR(0) && offset < FT_ACR(0))
280 || offset == FT_PSWM
281 || offset == FT_PSWA
282#endif
283 )
284 return *(uint64_t *) (raw_regs + offset);
285
286 if (offset >= FT_ACR(0 && offset < FT_PSWM)
287 || offset == FT_FPC
288#ifndef __s390x__
289 || (offset >= FT_GPR(0) && offset < FT_ACR(0))
290 || offset == FT_PSWM_U
291 || offset == FT_PSWA_L
292#endif
293 )
294 return *(uint32_t *) (raw_regs + offset);
295
296 /* This leaves 128-bit VX. No way to return them. */
297 return 0;
298}
299
300/* Return target_desc to use for IPA, given the tdesc index passed by
301 gdbserver. For s390, it also sets s390_regmap and s390_regnum. */
302
303const struct target_desc *
304get_ipa_tdesc (int idx)
305{
306#define SET_REGMAP(regmap, skip_last) \
307 do { \
308 s390_regmap = regmap; \
309 s390_regnum = (sizeof regmap / sizeof regmap[0]) - skip_last; \
310 } while(0)
311 switch (idx)
312 {
313#ifdef __s390x__
314 case S390_TDESC_64:
315 /* Subtract number of VX regs. */
316 SET_REGMAP(s390x_ft_collect_regmap, 32);
317 return tdesc_s390x_linux64;
318 case S390_TDESC_64V1:
319 SET_REGMAP(s390x_ft_collect_regmap, 32);
320 return tdesc_s390x_linux64v1;
321 case S390_TDESC_64V2:
322 SET_REGMAP(s390x_ft_collect_regmap, 32);
323 return tdesc_s390x_linux64v2;
324 case S390_TDESC_TE:
325 SET_REGMAP(s390x_te_ft_collect_regmap, 32);
326 return tdesc_s390x_te_linux64;
327 case S390_TDESC_VX:
328 SET_REGMAP(s390x_ft_collect_regmap, 0);
329 return tdesc_s390x_vx_linux64;
330 case S390_TDESC_TEVX:
331 SET_REGMAP(s390x_te_ft_collect_regmap, 0);
332 return tdesc_s390x_tevx_linux64;
333#else
334 case S390_TDESC_32:
335 SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
336 return tdesc_s390_linux32;
337 case S390_TDESC_32V1:
338 SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
339 return tdesc_s390_linux32v1;
340 case S390_TDESC_32V2:
341 SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
342 return tdesc_s390_linux32v2;
343 case S390_TDESC_64:
344 SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
345 return tdesc_s390_linux64;
346 case S390_TDESC_64V1:
347 SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
348 return tdesc_s390_linux64v1;
349 case S390_TDESC_64V2:
350 SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
351 return tdesc_s390_linux64v2;
352 case S390_TDESC_TE:
353 SET_REGMAP(s390_te_linux64_ft_collect_regmap, 32);
354 return tdesc_s390_te_linux64;
355 case S390_TDESC_VX:
356 SET_REGMAP(s390_linux64_ft_collect_regmap, 0);
357 return tdesc_s390_vx_linux64;
358 case S390_TDESC_TEVX:
359 SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0);
360 return tdesc_s390_tevx_linux64;
361#endif
362 default:
363 internal_error (__FILE__, __LINE__,
364 "unknown ipa tdesc index: %d", idx);
365#ifdef __s390x__
366 return tdesc_s390x_linux64;
367#else
368 return tdesc_s390_linux32;
369#endif
370 }
371}
372
373void
374initialize_low_tracepoint (void)
375{
376#ifdef __s390x__
377 init_registers_s390x_linux64 ();
378 init_registers_s390x_linux64v1 ();
379 init_registers_s390x_linux64v2 ();
380 init_registers_s390x_te_linux64 ();
381 init_registers_s390x_vx_linux64 ();
382 init_registers_s390x_tevx_linux64 ();
383#else
384 init_registers_s390_linux32 ();
385 init_registers_s390_linux32v1 ();
386 init_registers_s390_linux32v2 ();
387 init_registers_s390_linux64 ();
388 init_registers_s390_linux64v1 ();
389 init_registers_s390_linux64v2 ();
390 init_registers_s390_te_linux64 ();
391 init_registers_s390_vx_linux64 ();
392 init_registers_s390_tevx_linux64 ();
393#endif
394}
This page took 0.036637 seconds and 4 git commands to generate.