ia64/xen-unstable

view xen/arch/ia64/xen/gdbstub.c @ 16785:af3550f53874

[IA64] domheap: Don't pin xenheap down. Now it's unnecessary.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Jan 17 12:05:43 2008 -0700 (2008-01-17)
parents 9bf8b152df9f
children
line source
1 /*
2 * ia64-specific cdb routines
3 * cdb xen/ia64 by Isaku Yamahta <yamahata at valinux co jp>
4 * VA Linux Systems Japan K.K.
5 * some routines are stolen from kgdb/ia64.
6 */
7 /*
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 */
21 /*
22 * Copyright (C) 2000-2001 VERITAS Software Corporation.
23 */
24 /*
25 * Contributor: Lake Stevens Instrument Division$
26 * Written by: Glenn Engel $
27 * Updated by: Amit Kale<akale@veritas.com>
28 * Modified for 386 by Jim Kingdon, Cygnus Support.
29 * Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
30 *
31 */
34 #include <xen/lib.h>
35 #include <xen/mm.h>
36 #include <asm/byteorder.h>
37 #include <asm/debugger.h>
38 #include <asm/uaccess.h>
40 #define USE_UNWIND
42 #ifdef USE_UNWIND
43 #include <asm/unwind.h>
44 #endif
46 /* Printk isn't particularly safe just after we've trapped to the
47 debugger. so avoid it. */
48 #define dbg_printk(...)
49 //#define dbg_printk(...) printk(__VA_ARGS__)
51 u16
52 gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie)
53 {
54 /* XXX */
55 return 1;
56 }
58 void
59 gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx)
60 {
61 gdb_send_reply("", ctx);
62 }
64 void
65 gdb_arch_write_reg(unsigned long regnum, unsigned long val,
66 struct cpu_user_regs *regs, struct gdb_context *ctx)
67 {
68 gdb_send_reply("", ctx);
69 }
71 void
72 gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf,
73 struct gdb_context *ctx)
74 {
75 /* XXX TODO */
76 gdb_send_reply("E02", ctx);
77 }
79 /* Like copy_from_user, but safe to call with interrupts disabled.
80 Trust me, and don't look behind the curtain. */
81 unsigned
82 gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
83 {
84 int val;
85 __asm__ __volatile__(
86 "cmp4.eq p6, p0 = r0, %1\n"
87 "(p6) br.cond.dptk 2f\n"
88 "[1:]\n"
89 ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
90 "[99:] ld1 %0 = [%3], 1\n"
91 ";;\n"
92 ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
93 "[99:] st1 [%2] = %0, 1\n"
94 "adds %1 = -1, %1\n"
95 ";;\n"
96 "cmp4.eq p0, p6 = r0, %1\n"
97 "(p6) br.cond.dptk 1b\n"
98 "[2:]\n"
99 : "=r"(val), "=r"(len), "=r"(dest), "=r"(src)
100 : "1"(len), "2"(dest), "3"(src)
101 : "memory", "p6");
102 return len;
103 }
105 unsigned int
106 gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
107 {
108 /* XXX */
109 return len;
110 }
112 #define NUM_REGS 590
113 #define REGISTER_BYTES (NUM_REGS*8+128*8)
114 #define REGISTER_BYTE(N) (((N) * 8) \
115 + ((N) <= IA64_FR0_REGNUM ? \
116 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
117 #define REGISTER_SIZE(N) \
118 (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
119 #define IA64_GR0_REGNUM 0
120 #define IA64_FR0_REGNUM 128
121 #define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127)
122 #define IA64_PR0_REGNUM 256
123 #define IA64_BR0_REGNUM 320
124 #define IA64_VFP_REGNUM 328
125 #define IA64_PR_REGNUM 330
126 #define IA64_IP_REGNUM 331
127 #define IA64_PSR_REGNUM 332
128 #define IA64_CFM_REGNUM 333
129 #define IA64_AR0_REGNUM 334
130 #define IA64_NAT0_REGNUM 462
131 #define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM+31)
132 #define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM+32)
133 #define IA64_RSC_REGNUM (IA64_AR0_REGNUM+16)
134 #define IA64_BSP_REGNUM (IA64_AR0_REGNUM+17)
135 #define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM+18)
136 #define IA64_RNAT_REGNUM (IA64_AR0_REGNUM+19)
137 #define IA64_FCR_REGNUM (IA64_AR0_REGNUM+21)
138 #define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM+24)
139 #define IA64_CSD_REGNUM (IA64_AR0_REGNUM+25)
140 #define IA64_SSD_REGNUM (IA64_AR0_REGNUM+26)
141 #define IA64_CFLG_REGNUM (IA64_AR0_REGNUM+27)
142 #define IA64_FSR_REGNUM (IA64_AR0_REGNUM+28)
143 #define IA64_FIR_REGNUM (IA64_AR0_REGNUM+29)
144 #define IA64_FDR_REGNUM (IA64_AR0_REGNUM+30)
145 #define IA64_CCV_REGNUM (IA64_AR0_REGNUM+32)
146 #define IA64_UNAT_REGNUM (IA64_AR0_REGNUM+36)
147 #define IA64_FPSR_REGNUM (IA64_AR0_REGNUM+40)
148 #define IA64_ITC_REGNUM (IA64_AR0_REGNUM+44)
149 #define IA64_PFS_REGNUM (IA64_AR0_REGNUM+64)
150 #define IA64_LC_REGNUM (IA64_AR0_REGNUM+65)
151 #define IA64_EC_REGNUM (IA64_AR0_REGNUM+66)
153 #ifndef USE_UNWIND
154 struct regs_to_cpu_user_resgs_index {
155 unsigned int reg;
156 unsigned int ptregoff;
157 };
159 #define ptoff(V) ((unsigned int)&((struct cpu_user_regs*)0x0)->V)
161 // gr
162 static const struct regs_to_cpu_user_resgs_index
163 gr_reg_to_cpu_user_regs_index[] = {
164 {IA64_GR0_REGNUM + 8, ptoff(r8)},
165 {IA64_GR0_REGNUM + 9, ptoff(r9)},
166 {IA64_GR0_REGNUM + 10, ptoff(r10)},
167 {IA64_GR0_REGNUM + 11, ptoff(r11)},
168 {IA64_GR0_REGNUM + 1, ptoff(r1)},
169 {IA64_GR0_REGNUM + 12, ptoff(r12)},
170 {IA64_GR0_REGNUM + 13, ptoff(r13)},
171 {IA64_GR0_REGNUM + 15, ptoff(r15)},
173 {IA64_GR0_REGNUM + 14, ptoff(r14)},
174 {IA64_GR0_REGNUM + 2, ptoff(r2)},
175 {IA64_GR0_REGNUM + 3, ptoff(r3)},
176 {IA64_GR0_REGNUM + 16, ptoff(r16)},
177 {IA64_GR0_REGNUM + 17, ptoff(r17)},
178 {IA64_GR0_REGNUM + 18, ptoff(r18)},
179 {IA64_GR0_REGNUM + 19, ptoff(r19)},
180 {IA64_GR0_REGNUM + 20, ptoff(r20)},
181 {IA64_GR0_REGNUM + 21, ptoff(r21)},
182 {IA64_GR0_REGNUM + 22, ptoff(r22)},
183 {IA64_GR0_REGNUM + 23, ptoff(r23)},
184 {IA64_GR0_REGNUM + 24, ptoff(r24)},
185 {IA64_GR0_REGNUM + 25, ptoff(r25)},
186 {IA64_GR0_REGNUM + 26, ptoff(r26)},
187 {IA64_GR0_REGNUM + 27, ptoff(r27)},
188 {IA64_GR0_REGNUM + 28, ptoff(r28)},
189 {IA64_GR0_REGNUM + 29, ptoff(r29)},
190 {IA64_GR0_REGNUM + 30, ptoff(r30)},
191 {IA64_GR0_REGNUM + 31, ptoff(r31)},
193 {IA64_GR0_REGNUM + 4, ptoff(r4)},
194 {IA64_GR0_REGNUM + 5, ptoff(r5)},
195 {IA64_GR0_REGNUM + 6, ptoff(r6)},
196 {IA64_GR0_REGNUM + 7, ptoff(r7)},
197 };
198 static const int gr_reg_to_cpu_user_regs_index_max =
199 sizeof(gr_reg_to_cpu_user_regs_index) /
200 sizeof(gr_reg_to_cpu_user_regs_index[0]);
202 // br
203 static const struct regs_to_cpu_user_resgs_index
204 br_reg_to_cpu_user_regs_index[] = {
205 {IA64_BR0_REGNUM + 0, ptoff(b0)},
206 {IA64_BR0_REGNUM + 6, ptoff(b6)},
207 {IA64_BR0_REGNUM + 7, ptoff(b7)},
208 };
209 static const int br_reg_to_cpu_user_regs_index_max =
210 sizeof(br_reg_to_cpu_user_regs_index) /
211 sizeof(br_reg_to_cpu_user_regs_index[0]);
213 // f
214 static const struct regs_to_cpu_user_resgs_index
215 fr_reg_to_cpu_user_regs_index[] = {
216 {IA64_FR0_REGNUM + 6, ptoff(f6)},
217 {IA64_FR0_REGNUM + 7, ptoff(f7)},
218 {IA64_FR0_REGNUM + 8, ptoff(f8)},
219 {IA64_FR0_REGNUM + 9, ptoff(f9)},
220 {IA64_FR0_REGNUM + 10, ptoff(f10)},
221 {IA64_FR0_REGNUM + 11, ptoff(f11)},
222 };
223 static const int fr_reg_to_cpu_user_regs_index_max =
224 sizeof(fr_reg_to_cpu_user_regs_index) /
225 sizeof(fr_reg_to_cpu_user_regs_index[0]);
228 void
229 gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
230 struct gdb_context *ctx)
231 {
232 unsigned long reg = IA64_IP_REGNUM;
233 char buf[9];
234 int i;
236 dbg_printk("Register read regnum = 0x%lx\n", regnum);
237 if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
238 for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
239 if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
240 reg = *(unsigned long*)(((char*)regs) + gr_reg_to_cpu_user_regs_index[i].ptregoff);
241 break;
242 }
243 }
244 if (i == gr_reg_to_cpu_user_regs_index_max) {
245 goto out_err;
246 }
247 } else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
248 for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
249 if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
250 reg = *(unsigned long*)(((char*)regs) + br_reg_to_cpu_user_regs_index[i].ptregoff);
251 break;
252 }
253 }
254 if (i == br_reg_to_cpu_user_regs_index_max) {
255 goto out_err;
256 }
257 } else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 11) {
258 for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
259 if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
260 reg = *(unsigned long*)(((char*)regs) + fr_reg_to_cpu_user_regs_index[i].ptregoff);
261 break;
262 }
263 }
264 if (i == fr_reg_to_cpu_user_regs_index_max) {
265 goto out_err;
266 }
267 } else if (regnum == IA64_CSD_REGNUM) {
268 reg = regs->ar_csd;
269 } else if (regnum == IA64_SSD_REGNUM) {
270 reg = regs->ar_ssd;
271 } else if (regnum == IA64_PSR_REGNUM) {
272 reg = regs->cr_ipsr;
273 } else if (regnum == IA64_IP_REGNUM) {
274 reg = regs->cr_iip;
275 } else if (regnum == IA64_CFM_REGNUM) {
276 reg = regs->cr_ifs;
277 } else if (regnum == IA64_UNAT_REGNUM) {
278 reg = regs->ar_unat;
279 } else if (regnum == IA64_PFS_REGNUM) {
280 reg = regs->ar_pfs;
281 } else if (regnum == IA64_RSC_REGNUM) {
282 reg = regs->ar_rsc;
283 } else if (regnum == IA64_RNAT_REGNUM) {
284 reg = regs->ar_rnat;
285 } else if (regnum == IA64_BSPSTORE_REGNUM) {
286 reg = regs->ar_bspstore;
287 } else if (regnum == IA64_PR_REGNUM) {
288 reg = regs->pr;
289 } else if (regnum == IA64_FPSR_REGNUM) {
290 reg = regs->ar_fpsr;
291 } else if (regnum == IA64_CCV_REGNUM) {
292 reg = regs->ar_ccv;
293 } else {
294 // emul_unat, rfi_pfs
295 goto out_err;
296 }
298 dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg);
299 snprintf(buf, sizeof(buf), "%.08lx", swab64(reg));
300 out:
301 return gdb_send_reply(buf, ctx);
303 out_err:
304 dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
305 safe_strcpy(buf, "x");
306 goto out;
307 }
308 #else
310 #define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V)
311 struct reg_to_ptreg_index {
312 unsigned int reg;
313 unsigned int ptregoff;
314 };
316 static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
317 {IA64_GR0_REGNUM + 1, ptoff(r1)},
318 {IA64_GR0_REGNUM + 2, ptoff(r2)},
319 {IA64_GR0_REGNUM + 3, ptoff(r3)},
320 {IA64_GR0_REGNUM + 8, ptoff(r8)},
321 {IA64_GR0_REGNUM + 9, ptoff(r9)},
322 {IA64_GR0_REGNUM + 10, ptoff(r10)},
323 {IA64_GR0_REGNUM + 11, ptoff(r11)},
324 {IA64_GR0_REGNUM + 12, ptoff(r12)},
325 {IA64_GR0_REGNUM + 13, ptoff(r13)},
326 {IA64_GR0_REGNUM + 14, ptoff(r14)},
327 {IA64_GR0_REGNUM + 15, ptoff(r15)},
328 {IA64_GR0_REGNUM + 16, ptoff(r16)},
329 {IA64_GR0_REGNUM + 17, ptoff(r17)},
330 {IA64_GR0_REGNUM + 18, ptoff(r18)},
331 {IA64_GR0_REGNUM + 19, ptoff(r19)},
332 {IA64_GR0_REGNUM + 20, ptoff(r20)},
333 {IA64_GR0_REGNUM + 21, ptoff(r21)},
334 {IA64_GR0_REGNUM + 22, ptoff(r22)},
335 {IA64_GR0_REGNUM + 23, ptoff(r23)},
336 {IA64_GR0_REGNUM + 24, ptoff(r24)},
337 {IA64_GR0_REGNUM + 25, ptoff(r25)},
338 {IA64_GR0_REGNUM + 26, ptoff(r26)},
339 {IA64_GR0_REGNUM + 27, ptoff(r27)},
340 {IA64_GR0_REGNUM + 28, ptoff(r28)},
341 {IA64_GR0_REGNUM + 29, ptoff(r29)},
342 {IA64_GR0_REGNUM + 30, ptoff(r30)},
343 {IA64_GR0_REGNUM + 31, ptoff(r31)},
344 };
346 static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
347 {IA64_BR0_REGNUM, ptoff(b0)},
348 {IA64_BR0_REGNUM + 6, ptoff(b6)},
349 {IA64_BR0_REGNUM + 7, ptoff(b7)},
350 };
352 static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
353 {IA64_PFS_REGNUM, ptoff(ar_pfs)},
354 {IA64_UNAT_REGNUM, ptoff(ar_unat)},
355 {IA64_RNAT_REGNUM, ptoff(ar_rnat)},
356 {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
357 {IA64_RSC_REGNUM, ptoff(ar_rsc)},
358 {IA64_CSD_REGNUM, ptoff(ar_csd)},
359 {IA64_SSD_REGNUM, ptoff(ar_ssd)},
360 {IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
361 {IA64_CCV_REGNUM, ptoff(ar_ccv)},
362 };
364 #ifndef XEN
365 extern atomic_t cpu_doing_single_step;
366 #endif
368 static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
369 unsigned long *reg, int rw)
370 {
371 char nat;
373 if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
374 (regnum >= (IA64_GR0_REGNUM + 4) &&
375 regnum <= (IA64_GR0_REGNUM + 7)))
376 return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
377 reg, &nat, rw);
378 else
379 return 0;
380 }
381 static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
382 struct unw_frame_info *info, unsigned long *reg, int rw)
383 {
384 int i, result = 1;
385 char nat;
387 if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
388 regnum <= (IA64_GR0_REGNUM + 3)) ||
389 (regnum >= (IA64_GR0_REGNUM + 8) &&
390 regnum <= (IA64_GR0_REGNUM + 15)) ||
391 (regnum >= (IA64_GR0_REGNUM + 16) &&
392 regnum <= (IA64_GR0_REGNUM + 31))))
393 return 0;
394 else if (rw && ptregs) {
395 for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
396 if (gr_reg_to_ptreg_index[i].reg == regnum) {
397 *((unsigned long *)(((void *)ptregs) +
398 gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
399 break;
400 }
401 } else if (!rw && ptregs) {
402 for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
403 if (gr_reg_to_ptreg_index[i].reg == regnum) {
404 *reg = *((unsigned long *)
405 (((void *)ptregs) +
406 gr_reg_to_ptreg_index[i].ptregoff));
407 break;
408 }
409 } else
410 result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
411 reg, &nat, rw);
412 return result;
413 }
415 static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
416 struct unw_frame_info *info, unsigned long *reg, int rw)
417 {
418 int i, result = 1;
420 if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
421 return 0;
423 switch (regnum) {
424 case IA64_BR0_REGNUM:
425 case IA64_BR0_REGNUM + 6:
426 case IA64_BR0_REGNUM + 7:
427 if (rw) {
428 for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
429 if (br_reg_to_ptreg_index[i].reg == regnum) {
430 *((unsigned long *)
431 (((void *)ptregs) +
432 br_reg_to_ptreg_index[i].ptregoff)) =
433 *reg;
434 break;
435 }
436 } else
437 for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
438 if (br_reg_to_ptreg_index[i].reg == regnum) {
439 *reg = *((unsigned long *)
440 (((void *)ptregs) +
441 br_reg_to_ptreg_index[i].
442 ptregoff));
443 break;
444 }
445 break;
446 case IA64_BR0_REGNUM + 1:
447 case IA64_BR0_REGNUM + 2:
448 case IA64_BR0_REGNUM + 3:
449 case IA64_BR0_REGNUM + 4:
450 case IA64_BR0_REGNUM + 5:
451 result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
452 reg, rw);
453 break;
454 }
456 return result;
457 }
459 static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
460 struct unw_frame_info *info, unsigned long *reg,
461 struct ia64_fpreg *freg, int rw)
462 {
463 int result = 1;
465 if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
466 return 0;
468 switch (regnum) {
469 case IA64_FR0_REGNUM + 6:
470 case IA64_FR0_REGNUM + 7:
471 case IA64_FR0_REGNUM + 8:
472 case IA64_FR0_REGNUM + 9:
473 case IA64_FR0_REGNUM + 10:
474 case IA64_FR0_REGNUM + 11:
475 case IA64_FR0_REGNUM + 12:
476 if (rw) {
477 #ifndef XEN
478 char *ptr = inbuffer;
480 freg->u.bits[0] = *reg;
481 kgdb_hex2long(&ptr, &freg->u.bits[1]);
482 *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
483 *freg;
484 #else
485 printk("%s: %d: writing to fpreg is not supported.\n",
486 __func__, __LINE__);
487 #endif
488 break;
489 } else if (!ptregs)
490 result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
491 freg, rw);
492 else
493 #ifndef XEN
494 *freg =
495 *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
496 #else
497 //XXX struct ia64_fpreg and struct pt_fpreg are same.
498 *freg = *((struct ia64_fpreg*)(&ptregs->f6 +
499 (regnum - (IA64_FR0_REGNUM + 6))));
500 #endif
501 break;
502 default:
503 if (!rw)
504 result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
505 freg, rw);
506 else
507 result = 0;
508 break;
509 }
511 return result;
512 }
514 static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
515 struct unw_frame_info *info, unsigned long *reg, int rw)
516 {
517 int result = 0, i;
519 if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
520 return 0;
522 if (rw && ptregs) {
523 for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
524 if (ar_reg_to_ptreg_index[i].reg == regnum) {
525 *((unsigned long *) (((void *)ptregs) +
526 ar_reg_to_ptreg_index[i].ptregoff)) =
527 *reg;
528 result = 1;
529 break;
530 }
531 } else if (ptregs) {
532 for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
533 if (ar_reg_to_ptreg_index[i].reg == regnum) {
534 *reg = *((unsigned long *) (((void *)ptregs) +
535 ar_reg_to_ptreg_index[i].ptregoff));
536 result = 1;
537 break;
538 }
539 }
541 if (result)
542 return result;
544 result = 1;
546 switch (regnum) {
547 case IA64_CSD_REGNUM:
548 result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
549 break;
550 case IA64_SSD_REGNUM:
551 result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
552 break;
553 case IA64_UNAT_REGNUM:
554 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
555 break;
556 case IA64_RNAT_REGNUM:
557 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
558 break;
559 case IA64_BSPSTORE_REGNUM:
560 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
561 break;
562 case IA64_PFS_REGNUM:
563 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
564 break;
565 case IA64_LC_REGNUM:
566 result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
567 break;
568 case IA64_EC_REGNUM:
569 result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
570 break;
571 case IA64_FPSR_REGNUM:
572 result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
573 break;
574 case IA64_RSC_REGNUM:
575 result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
576 break;
577 case IA64_CCV_REGNUM:
578 result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
579 break;
580 default:
581 result = 0;
582 }
584 return result;
585 }
587 #ifndef XEN
588 void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
589 struct pt_regs *ptregs)
590 #else
591 static int
592 kgdb_get_reg(int regnum, struct unw_frame_info *info,
593 struct cpu_user_regs* ptregs,
594 unsigned long* __reg, struct ia64_fpreg* __freg)
595 #endif
596 {
597 unsigned long reg, size = 0, *mem = &reg;
598 struct ia64_fpreg freg;
600 if (kgdb_gr_reg(regnum, info, &reg, 0) ||
601 kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
602 kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
603 kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
604 size = sizeof(reg);
605 else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {
606 size = sizeof(freg);
607 mem = (unsigned long *)&freg;
608 } else if (regnum == IA64_IP_REGNUM) {
609 if (!ptregs) {
610 unw_get_ip(info, &reg);
611 size = sizeof(reg);
612 } else {
613 reg = ptregs->cr_iip;
614 size = sizeof(reg);
615 }
616 } else if (regnum == IA64_CFM_REGNUM) {
617 if (!ptregs)
618 unw_get_cfm(info, &reg);
619 else
620 reg = ptregs->cr_ifs;
621 size = sizeof(reg);
622 } else if (regnum == IA64_PSR_REGNUM) {
623 #ifndef XEN
624 if (!ptregs && kgdb_usethread)
625 ptregs = (struct pt_regs *)
626 ((unsigned long)kgdb_usethread +
627 IA64_STK_OFFSET) - 1;
628 #endif
629 if (ptregs)
630 reg = ptregs->cr_ipsr;
631 size = sizeof(reg);
632 } else if (regnum == IA64_PR_REGNUM) {
633 if (ptregs)
634 reg = ptregs->pr;
635 else
636 unw_access_pr(info, &reg, 0);
637 size = sizeof(reg);
638 } else if (regnum == IA64_BSP_REGNUM) {
639 unw_get_bsp(info, &reg);
640 size = sizeof(reg);
641 }
643 #ifndef XEN
644 if (size) {
645 kgdb_mem2hex((char *) mem, outbuffer, size);
646 outbuffer[size*2] = 0;
647 }
648 else
649 strlcpy(outbuffer, "E0", sizeof("E0"));
651 return;
652 #else
653 if (size) {
654 if (size == sizeof(reg)) {
655 *__reg = reg;
656 } else {
657 BUG_ON(size != sizeof(freg));
658 *__freg = freg;
659 }
660 return 0;
661 }
663 return -1;
664 #endif
665 }
667 #ifndef XEN
668 static int inline kgdb_get_blocked_state(struct task_struct *p,
669 struct unw_frame_info *unw)
670 #else
671 static int
672 kgdb_get_blocked_state(struct vcpu *p,
673 struct cpu_user_regs *regs,
674 struct unw_frame_info *unw)
675 #endif
676 {
677 unsigned long ip;
678 int count = 0;
680 #ifndef XEN
681 unw_init_from_blocked_task(unw, p);
682 #endif
683 ip = 0UL;
684 do {
685 if (unw_unwind(unw) < 0)
686 return -1;
687 unw_get_ip(unw, &ip);
688 #ifndef XEN
689 if (!in_sched_functions(ip))
690 break;
691 #else
692 dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);
693 if (ip == regs->cr_iip)
694 break;
695 #endif
696 } while (count++ < 16);
698 if (!ip)
699 return -1;
700 else
701 return 0;
702 }
704 struct gdb_callback_arg
705 {
706 struct cpu_user_regs* regs;
707 unsigned long regnum;
708 unsigned long* reg;
709 struct pt_fpreg* freg;
711 int error;
712 // 1: not supported
713 // 0: success
714 // -1: failure
715 };
717 static void
718 gdb_get_reg_callback(struct unw_frame_info* info, void* __arg)
719 {
720 struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;
722 if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {
723 dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);
724 arg->error = -1;
725 return;
726 }
727 //XXX struct ia64_fpreg and struct pt_fpreg are same.
728 if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg,
729 (struct ia64_fpreg*)arg->freg) < 0) {
730 dbg_printk("%s: kgdb_get_reg failed\n", __func__);
731 arg->error = 1;
732 return;
733 }
734 arg->error = 0;
735 return;
736 }
738 void
739 gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
740 struct gdb_context *ctx)
741 {
742 struct gdb_callback_arg arg;
743 unsigned long reg;
744 struct pt_fpreg freg;
745 char buf[16 * 2 + 1];
747 if (regnum >= NUM_REGS) {
748 dbg_printk("%s: regnum %ld\n", __func__, regnum);
749 goto out_err;
750 }
752 arg.regs = regs;
753 arg.regnum = regnum;
754 arg.reg = &reg;
755 arg.freg = &freg;
756 arg.error = 0;
757 unw_init_running(&gdb_get_reg_callback, (void*)&arg);
758 if (arg.error < 0) {
759 dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
760 goto out_err;
761 }
763 if (arg.error > 0) {
764 // notify gdb that this register is not supported.
765 // see fetch_register_using_p() in gdb/remote.c.
766 safe_strcpy(buf, "x");
767 } else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) {
768 snprintf(buf, sizeof(buf), "%.016lx", swab64(freg.u.bits[0]));
769 snprintf(buf + 16, sizeof(buf) - 16, "%.016lx", swab64(freg.u.bits[1]));
770 } else {
771 snprintf(buf, sizeof(buf), "%.016lx", swab64(reg));
772 }
773 out:
774 return gdb_send_reply(buf, ctx);
776 out_err:
777 dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
778 safe_strcpy(buf, "E0");
779 goto out;
780 }
781 #endif
783 void
784 gdb_arch_resume(struct cpu_user_regs *regs,
785 unsigned long addr, unsigned long type,
786 struct gdb_context *ctx)
787 {
788 /* XXX */
789 if (type == GDB_STEP) {
790 gdb_send_reply("S01", ctx);
791 }
792 }
794 void
795 gdb_arch_print_state(struct cpu_user_regs *regs)
796 {
797 /* XXX */
798 }
800 void
801 gdb_arch_enter(struct cpu_user_regs *regs)
802 {
803 /* nothing */
804 }
806 void
807 gdb_arch_exit(struct cpu_user_regs *regs)
808 {
809 /* nothing */
810 }
812 /*
813 * Local variables:
814 * mode: C
815 * c-set-style: "BSD"
816 * c-basic-offset: 4
817 * tab-width: 4
818 * End:
819 */