ia64/xen-unstable

view xen/arch/ia64/xen/gdbstub.c @ 9405:29dfadcc5029

[IA64] Followup to xen time cleanup

Clean up to xen time handler. Tristan #if 0 some code because it seems
redundant, which however is actually problematic logic as a reason for
an intermittent timer oops issue of dom0. So delete it now.

Also remove vcpu_wake, since wakeup current has nothing meaningful and
simply waste cpu cycle.

Signed-off-by: Kevin Tian <kevin.tian@intel.com>
author awilliam@xenbuild.aw
date Mon Mar 27 15:32:08 2006 -0700 (2006-03-27)
parents 056109e43947
children d2784d93e760
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_array(struct cpu_user_regs *regs, const char* buf,
66 struct gdb_context *ctx)
67 {
68 /* XXX TODO */
69 gdb_send_reply("E02", ctx);
70 }
72 /* Like copy_from_user, but safe to call with interrupts disabled.
73 Trust me, and don't look behind the curtain. */
74 unsigned
75 gdb_arch_copy_from_user(void *dest, const void *src, unsigned len)
76 {
77 int val;
78 __asm__ __volatile__(
79 "cmp4.eq p6, p0 = r0, %1\n"
80 "(p6) br.cond.dptk 2f\n"
81 "[1:]\n"
82 ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
83 "[99:] ld1 %0 = [%3], 1\n"
84 ";;\n"
85 ".xdata4 \"__ex_table\", 99f-., 2f-.;\n"
86 "[99:] st1 [%2] = %0, 1\n"
87 "adds %1 = -1, %1\n"
88 ";;\n"
89 "cmp4.eq p0, p6 = r0, %1\n"
90 "(p6) br.cond.dptk 1b\n"
91 "[2:]\n"
92 : "=r"(val), "=r"(len), "=r"(dest), "=r"(src)
93 : "1"(len), "2"(dest), "3"(src)
94 : "memory", "p6");
95 return len;
96 }
98 unsigned int
99 gdb_arch_copy_to_user(void *dest, const void *src, unsigned len)
100 {
101 /* XXX */
102 return len;
103 }
105 #define NUM_REGS 590
106 #define REGISTER_BYTES (NUM_REGS*8+128*8)
107 #define REGISTER_BYTE(N) (((N) * 8) \
108 + ((N) <= IA64_FR0_REGNUM ? \
109 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
110 #define REGISTER_SIZE(N) \
111 (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
112 #define IA64_GR0_REGNUM 0
113 #define IA64_FR0_REGNUM 128
114 #define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127)
115 #define IA64_PR0_REGNUM 256
116 #define IA64_BR0_REGNUM 320
117 #define IA64_VFP_REGNUM 328
118 #define IA64_PR_REGNUM 330
119 #define IA64_IP_REGNUM 331
120 #define IA64_PSR_REGNUM 332
121 #define IA64_CFM_REGNUM 333
122 #define IA64_AR0_REGNUM 334
123 #define IA64_NAT0_REGNUM 462
124 #define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM+31)
125 #define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM+32)
126 #define IA64_RSC_REGNUM (IA64_AR0_REGNUM+16)
127 #define IA64_BSP_REGNUM (IA64_AR0_REGNUM+17)
128 #define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM+18)
129 #define IA64_RNAT_REGNUM (IA64_AR0_REGNUM+19)
130 #define IA64_FCR_REGNUM (IA64_AR0_REGNUM+21)
131 #define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM+24)
132 #define IA64_CSD_REGNUM (IA64_AR0_REGNUM+25)
133 #define IA64_SSD_REGNUM (IA64_AR0_REGNUM+26)
134 #define IA64_CFLG_REGNUM (IA64_AR0_REGNUM+27)
135 #define IA64_FSR_REGNUM (IA64_AR0_REGNUM+28)
136 #define IA64_FIR_REGNUM (IA64_AR0_REGNUM+29)
137 #define IA64_FDR_REGNUM (IA64_AR0_REGNUM+30)
138 #define IA64_CCV_REGNUM (IA64_AR0_REGNUM+32)
139 #define IA64_UNAT_REGNUM (IA64_AR0_REGNUM+36)
140 #define IA64_FPSR_REGNUM (IA64_AR0_REGNUM+40)
141 #define IA64_ITC_REGNUM (IA64_AR0_REGNUM+44)
142 #define IA64_PFS_REGNUM (IA64_AR0_REGNUM+64)
143 #define IA64_LC_REGNUM (IA64_AR0_REGNUM+65)
144 #define IA64_EC_REGNUM (IA64_AR0_REGNUM+66)
146 #ifndef USE_UNWIND
147 struct regs_to_cpu_user_resgs_index {
148 unsigned int reg;
149 unsigned int ptregoff;
150 };
152 #define ptoff(V) ((unsigned int)&((struct cpu_user_regs*)0x0)->V)
154 // gr
155 static const struct regs_to_cpu_user_resgs_index
156 gr_reg_to_cpu_user_regs_index[] = {
157 {IA64_GR0_REGNUM + 8, ptoff(r8)},
158 {IA64_GR0_REGNUM + 9, ptoff(r9)},
159 {IA64_GR0_REGNUM + 10, ptoff(r10)},
160 {IA64_GR0_REGNUM + 11, ptoff(r11)},
161 {IA64_GR0_REGNUM + 1, ptoff(r1)},
162 {IA64_GR0_REGNUM + 12, ptoff(r12)},
163 {IA64_GR0_REGNUM + 13, ptoff(r13)},
164 {IA64_GR0_REGNUM + 15, ptoff(r15)},
166 {IA64_GR0_REGNUM + 14, ptoff(r14)},
167 {IA64_GR0_REGNUM + 2, ptoff(r2)},
168 {IA64_GR0_REGNUM + 3, ptoff(r3)},
169 {IA64_GR0_REGNUM + 16, ptoff(r16)},
170 {IA64_GR0_REGNUM + 17, ptoff(r17)},
171 {IA64_GR0_REGNUM + 18, ptoff(r18)},
172 {IA64_GR0_REGNUM + 19, ptoff(r19)},
173 {IA64_GR0_REGNUM + 20, ptoff(r20)},
174 {IA64_GR0_REGNUM + 21, ptoff(r21)},
175 {IA64_GR0_REGNUM + 22, ptoff(r22)},
176 {IA64_GR0_REGNUM + 23, ptoff(r23)},
177 {IA64_GR0_REGNUM + 24, ptoff(r24)},
178 {IA64_GR0_REGNUM + 25, ptoff(r25)},
179 {IA64_GR0_REGNUM + 26, ptoff(r26)},
180 {IA64_GR0_REGNUM + 27, ptoff(r27)},
181 {IA64_GR0_REGNUM + 28, ptoff(r28)},
182 {IA64_GR0_REGNUM + 29, ptoff(r29)},
183 {IA64_GR0_REGNUM + 30, ptoff(r30)},
184 {IA64_GR0_REGNUM + 31, ptoff(r31)},
186 {IA64_GR0_REGNUM + 4, ptoff(r4)},
187 {IA64_GR0_REGNUM + 5, ptoff(r5)},
188 {IA64_GR0_REGNUM + 6, ptoff(r6)},
189 {IA64_GR0_REGNUM + 7, ptoff(r7)},
190 };
191 static const int gr_reg_to_cpu_user_regs_index_max =
192 sizeof(gr_reg_to_cpu_user_regs_index) /
193 sizeof(gr_reg_to_cpu_user_regs_index[0]);
195 // br
196 static const struct regs_to_cpu_user_resgs_index
197 br_reg_to_cpu_user_regs_index[] = {
198 {IA64_BR0_REGNUM + 0, ptoff(b0)},
199 {IA64_BR0_REGNUM + 6, ptoff(b6)},
200 {IA64_BR0_REGNUM + 7, ptoff(b7)},
201 };
202 static const int br_reg_to_cpu_user_regs_index_max =
203 sizeof(br_reg_to_cpu_user_regs_index) /
204 sizeof(br_reg_to_cpu_user_regs_index[0]);
206 // f
207 static const struct regs_to_cpu_user_resgs_index
208 fr_reg_to_cpu_user_regs_index[] = {
209 {IA64_FR0_REGNUM + 6, ptoff(f6)},
210 {IA64_FR0_REGNUM + 7, ptoff(f7)},
211 {IA64_FR0_REGNUM + 8, ptoff(f8)},
212 {IA64_FR0_REGNUM + 9, ptoff(f9)},
213 {IA64_FR0_REGNUM + 10, ptoff(f10)},
214 {IA64_FR0_REGNUM + 11, ptoff(f11)},
215 };
216 static const int fr_reg_to_cpu_user_regs_index_max =
217 sizeof(fr_reg_to_cpu_user_regs_index) /
218 sizeof(fr_reg_to_cpu_user_regs_index[0]);
221 void
222 gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
223 struct gdb_context *ctx)
224 {
225 unsigned long reg = IA64_IP_REGNUM;
226 char buf[9];
227 int i;
229 dbg_printk("Register read regnum = 0x%lx\n", regnum);
230 if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) {
231 for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) {
232 if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) {
233 reg = *(unsigned long*)(((char*)regs) + gr_reg_to_cpu_user_regs_index[i].ptregoff);
234 break;
235 }
236 }
237 if (i == gr_reg_to_cpu_user_regs_index_max) {
238 goto out_err;
239 }
240 } else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) {
241 for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) {
242 if (br_reg_to_cpu_user_regs_index[i].reg == regnum) {
243 reg = *(unsigned long*)(((char*)regs) + br_reg_to_cpu_user_regs_index[i].ptregoff);
244 break;
245 }
246 }
247 if (i == br_reg_to_cpu_user_regs_index_max) {
248 goto out_err;
249 }
250 } else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 11) {
251 for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) {
252 if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) {
253 reg = *(unsigned long*)(((char*)regs) + fr_reg_to_cpu_user_regs_index[i].ptregoff);
254 break;
255 }
256 }
257 if (i == fr_reg_to_cpu_user_regs_index_max) {
258 goto out_err;
259 }
260 } else if (regnum == IA64_CSD_REGNUM) {
261 reg = regs->ar_csd;
262 } else if (regnum == IA64_SSD_REGNUM) {
263 reg = regs->ar_ssd;
264 } else if (regnum == IA64_PSR_REGNUM) {
265 reg = regs->cr_ipsr;
266 } else if (regnum == IA64_IP_REGNUM) {
267 reg = regs->cr_iip;
268 } else if (regnum == IA64_CFM_REGNUM) {
269 reg = regs->cr_ifs;
270 } else if (regnum == IA64_UNAT_REGNUM) {
271 reg = regs->ar_unat;
272 } else if (regnum == IA64_PFS_REGNUM) {
273 reg = regs->ar_pfs;
274 } else if (regnum == IA64_RSC_REGNUM) {
275 reg = regs->ar_rsc;
276 } else if (regnum == IA64_RNAT_REGNUM) {
277 reg = regs->ar_rnat;
278 } else if (regnum == IA64_BSPSTORE_REGNUM) {
279 reg = regs->ar_bspstore;
280 } else if (regnum == IA64_PR_REGNUM) {
281 reg = regs->pr;
282 } else if (regnum == IA64_FPSR_REGNUM) {
283 reg = regs->ar_fpsr;
284 } else if (regnum == IA64_CCV_REGNUM) {
285 reg = regs->ar_ccv;
286 } else {
287 // emul_unat, rfi_pfs
288 goto out_err;
289 }
291 dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg);
292 sprintf(buf, "%.08lx", swab64(reg));
293 out:
294 return gdb_send_reply(buf, ctx);
296 out_err:
297 dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
298 sprintf(buf, "%s", "x");
299 goto out;
300 }
301 #else
303 #define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V)
304 struct reg_to_ptreg_index {
305 unsigned int reg;
306 unsigned int ptregoff;
307 };
309 static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
310 {IA64_GR0_REGNUM + 1, ptoff(r1)},
311 {IA64_GR0_REGNUM + 2, ptoff(r2)},
312 {IA64_GR0_REGNUM + 3, ptoff(r3)},
313 {IA64_GR0_REGNUM + 8, ptoff(r8)},
314 {IA64_GR0_REGNUM + 9, ptoff(r9)},
315 {IA64_GR0_REGNUM + 10, ptoff(r10)},
316 {IA64_GR0_REGNUM + 11, ptoff(r11)},
317 {IA64_GR0_REGNUM + 12, ptoff(r12)},
318 {IA64_GR0_REGNUM + 13, ptoff(r13)},
319 {IA64_GR0_REGNUM + 14, ptoff(r14)},
320 {IA64_GR0_REGNUM + 15, ptoff(r15)},
321 {IA64_GR0_REGNUM + 16, ptoff(r16)},
322 {IA64_GR0_REGNUM + 17, ptoff(r17)},
323 {IA64_GR0_REGNUM + 18, ptoff(r18)},
324 {IA64_GR0_REGNUM + 19, ptoff(r19)},
325 {IA64_GR0_REGNUM + 20, ptoff(r20)},
326 {IA64_GR0_REGNUM + 21, ptoff(r21)},
327 {IA64_GR0_REGNUM + 22, ptoff(r22)},
328 {IA64_GR0_REGNUM + 23, ptoff(r23)},
329 {IA64_GR0_REGNUM + 24, ptoff(r24)},
330 {IA64_GR0_REGNUM + 25, ptoff(r25)},
331 {IA64_GR0_REGNUM + 26, ptoff(r26)},
332 {IA64_GR0_REGNUM + 27, ptoff(r27)},
333 {IA64_GR0_REGNUM + 28, ptoff(r28)},
334 {IA64_GR0_REGNUM + 29, ptoff(r29)},
335 {IA64_GR0_REGNUM + 30, ptoff(r30)},
336 {IA64_GR0_REGNUM + 31, ptoff(r31)},
337 };
339 static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
340 {IA64_BR0_REGNUM, ptoff(b0)},
341 {IA64_BR0_REGNUM + 6, ptoff(b6)},
342 {IA64_BR0_REGNUM + 7, ptoff(b7)},
343 };
345 static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
346 {IA64_PFS_REGNUM, ptoff(ar_pfs)},
347 {IA64_UNAT_REGNUM, ptoff(ar_unat)},
348 {IA64_RNAT_REGNUM, ptoff(ar_rnat)},
349 {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
350 {IA64_RSC_REGNUM, ptoff(ar_rsc)},
351 {IA64_CSD_REGNUM, ptoff(ar_csd)},
352 {IA64_SSD_REGNUM, ptoff(ar_ssd)},
353 {IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
354 {IA64_CCV_REGNUM, ptoff(ar_ccv)},
355 };
357 #ifndef XEN
358 extern atomic_t cpu_doing_single_step;
359 #endif
361 static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
362 unsigned long *reg, int rw)
363 {
364 char nat;
366 if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
367 (regnum >= (IA64_GR0_REGNUM + 4) &&
368 regnum <= (IA64_GR0_REGNUM + 7)))
369 return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
370 reg, &nat, rw);
371 else
372 return 0;
373 }
374 static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
375 struct unw_frame_info *info, unsigned long *reg, int rw)
376 {
377 int i, result = 1;
378 char nat;
380 if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
381 regnum <= (IA64_GR0_REGNUM + 3)) ||
382 (regnum >= (IA64_GR0_REGNUM + 8) &&
383 regnum <= (IA64_GR0_REGNUM + 15)) ||
384 (regnum >= (IA64_GR0_REGNUM + 16) &&
385 regnum <= (IA64_GR0_REGNUM + 31))))
386 return 0;
387 else if (rw && ptregs) {
388 for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
389 if (gr_reg_to_ptreg_index[i].reg == regnum) {
390 *((unsigned long *)(((void *)ptregs) +
391 gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
392 break;
393 }
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 *reg = *((unsigned long *)
398 (((void *)ptregs) +
399 gr_reg_to_ptreg_index[i].ptregoff));
400 break;
401 }
402 } else
403 result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
404 reg, &nat, rw);
405 return result;
406 }
408 static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
409 struct unw_frame_info *info, unsigned long *reg, int rw)
410 {
411 int i, result = 1;
413 if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
414 return 0;
416 switch (regnum) {
417 case IA64_BR0_REGNUM:
418 case IA64_BR0_REGNUM + 6:
419 case IA64_BR0_REGNUM + 7:
420 if (rw) {
421 for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
422 if (br_reg_to_ptreg_index[i].reg == regnum) {
423 *((unsigned long *)
424 (((void *)ptregs) +
425 br_reg_to_ptreg_index[i].ptregoff)) =
426 *reg;
427 break;
428 }
429 } else
430 for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
431 if (br_reg_to_ptreg_index[i].reg == regnum) {
432 *reg = *((unsigned long *)
433 (((void *)ptregs) +
434 br_reg_to_ptreg_index[i].
435 ptregoff));
436 break;
437 }
438 break;
439 case IA64_BR0_REGNUM + 1:
440 case IA64_BR0_REGNUM + 2:
441 case IA64_BR0_REGNUM + 3:
442 case IA64_BR0_REGNUM + 4:
443 case IA64_BR0_REGNUM + 5:
444 result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
445 reg, rw);
446 break;
447 }
449 return result;
450 }
452 static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
453 struct unw_frame_info *info, unsigned long *reg,
454 struct ia64_fpreg *freg, int rw)
455 {
456 int result = 1;
458 if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
459 return 0;
461 switch (regnum) {
462 case IA64_FR0_REGNUM + 6:
463 case IA64_FR0_REGNUM + 7:
464 case IA64_FR0_REGNUM + 8:
465 case IA64_FR0_REGNUM + 9:
466 case IA64_FR0_REGNUM + 10:
467 case IA64_FR0_REGNUM + 11:
468 case IA64_FR0_REGNUM + 12:
469 if (rw) {
470 #ifndef XEN
471 char *ptr = inbuffer;
473 freg->u.bits[0] = *reg;
474 kgdb_hex2long(&ptr, &freg->u.bits[1]);
475 *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
476 *freg;
477 #else
478 printk("%s: %d: writing to fpreg is not supported.\n",
479 __func__, __LINE__);
480 #endif
481 break;
482 } else if (!ptregs)
483 result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
484 freg, rw);
485 else
486 #ifndef XEN
487 *freg =
488 *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
489 #else
490 //XXX struct ia64_fpreg and struct pt_fpreg are same.
491 *freg = *((struct ia64_fpreg*)(&ptregs->f6 +
492 (regnum - (IA64_FR0_REGNUM + 6))));
493 #endif
494 break;
495 default:
496 if (!rw)
497 result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
498 freg, rw);
499 else
500 result = 0;
501 break;
502 }
504 return result;
505 }
507 static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
508 struct unw_frame_info *info, unsigned long *reg, int rw)
509 {
510 int result = 0, i;
512 if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
513 return 0;
515 if (rw && ptregs) {
516 for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
517 if (ar_reg_to_ptreg_index[i].reg == regnum) {
518 *((unsigned long *) (((void *)ptregs) +
519 ar_reg_to_ptreg_index[i].ptregoff)) =
520 *reg;
521 result = 1;
522 break;
523 }
524 } else if (ptregs) {
525 for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
526 if (ar_reg_to_ptreg_index[i].reg == regnum) {
527 *reg = *((unsigned long *) (((void *)ptregs) +
528 ar_reg_to_ptreg_index[i].ptregoff));
529 result = 1;
530 break;
531 }
532 }
534 if (result)
535 return result;
537 result = 1;
539 switch (regnum) {
540 case IA64_CSD_REGNUM:
541 result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
542 break;
543 case IA64_SSD_REGNUM:
544 result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
545 break;
546 case IA64_UNAT_REGNUM:
547 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
548 break;
549 case IA64_RNAT_REGNUM:
550 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
551 break;
552 case IA64_BSPSTORE_REGNUM:
553 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
554 break;
555 case IA64_PFS_REGNUM:
556 result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
557 break;
558 case IA64_LC_REGNUM:
559 result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
560 break;
561 case IA64_EC_REGNUM:
562 result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
563 break;
564 case IA64_FPSR_REGNUM:
565 result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
566 break;
567 case IA64_RSC_REGNUM:
568 result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
569 break;
570 case IA64_CCV_REGNUM:
571 result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
572 break;
573 default:
574 result = 0;
575 }
577 return result;
578 }
580 #ifndef XEN
581 void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
582 struct pt_regs *ptregs)
583 #else
584 static int
585 kgdb_get_reg(int regnum, struct unw_frame_info *info,
586 struct cpu_user_regs* ptregs,
587 unsigned long* __reg, struct ia64_fpreg* __freg)
588 #endif
589 {
590 unsigned long reg, size = 0, *mem = &reg;
591 struct ia64_fpreg freg;
593 if (kgdb_gr_reg(regnum, info, &reg, 0) ||
594 kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
595 kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
596 kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
597 size = sizeof(reg);
598 else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {
599 size = sizeof(freg);
600 mem = (unsigned long *)&freg;
601 } else if (regnum == IA64_IP_REGNUM) {
602 if (!ptregs) {
603 unw_get_ip(info, &reg);
604 size = sizeof(reg);
605 } else {
606 reg = ptregs->cr_iip;
607 size = sizeof(reg);
608 }
609 } else if (regnum == IA64_CFM_REGNUM) {
610 if (!ptregs)
611 unw_get_cfm(info, &reg);
612 else
613 reg = ptregs->cr_ifs;
614 size = sizeof(reg);
615 } else if (regnum == IA64_PSR_REGNUM) {
616 #ifndef XEN
617 if (!ptregs && kgdb_usethread)
618 ptregs = (struct pt_regs *)
619 ((unsigned long)kgdb_usethread +
620 IA64_STK_OFFSET) - 1;
621 #endif
622 if (ptregs)
623 reg = ptregs->cr_ipsr;
624 size = sizeof(reg);
625 } else if (regnum == IA64_PR_REGNUM) {
626 if (ptregs)
627 reg = ptregs->pr;
628 else
629 unw_access_pr(info, &reg, 0);
630 size = sizeof(reg);
631 } else if (regnum == IA64_BSP_REGNUM) {
632 unw_get_bsp(info, &reg);
633 size = sizeof(reg);
634 }
636 #ifndef XEN
637 if (size) {
638 kgdb_mem2hex((char *) mem, outbuffer, size);
639 outbuffer[size*2] = 0;
640 }
641 else
642 strcpy(outbuffer, "E0");
644 return;
645 #else
646 if (size) {
647 if (size == sizeof(reg)) {
648 *__reg = reg;
649 } else {
650 BUG_ON(size != sizeof(freg));
651 *__freg = freg;
652 }
653 return 0;
654 }
656 return -1;
657 #endif
658 }
660 #ifndef XEN
661 static int inline kgdb_get_blocked_state(struct task_struct *p,
662 struct unw_frame_info *unw)
663 #else
664 static int
665 kgdb_get_blocked_state(struct vcpu *p,
666 struct cpu_user_regs *regs,
667 struct unw_frame_info *unw)
668 #endif
669 {
670 unsigned long ip;
671 int count = 0;
673 #ifndef XEN
674 unw_init_from_blocked_task(unw, p);
675 #endif
676 ip = 0UL;
677 do {
678 if (unw_unwind(unw) < 0)
679 return -1;
680 unw_get_ip(unw, &ip);
681 #ifndef XEN
682 if (!in_sched_functions(ip))
683 break;
684 #else
685 dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip);
686 if (ip == regs->cr_iip)
687 break;
688 #endif
689 } while (count++ < 16);
691 if (!ip)
692 return -1;
693 else
694 return 0;
695 }
697 struct gdb_callback_arg
698 {
699 struct cpu_user_regs* regs;
700 unsigned long regnum;
701 unsigned long* reg;
702 struct pt_fpreg* freg;
704 int error;
705 // 1: not supported
706 // 0: success
707 // -1: failure
708 };
710 static void
711 gdb_get_reg_callback(struct unw_frame_info* info, void* __arg)
712 {
713 struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg;
715 if (kgdb_get_blocked_state(current, arg->regs, info) < 0) {
716 dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__);
717 arg->error = -1;
718 return;
719 }
720 //XXX struct ia64_fpreg and struct pt_fpreg are same.
721 if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg,
722 (struct ia64_fpreg*)arg->freg) < 0) {
723 dbg_printk("%s: kgdb_get_reg failed\n", __func__);
724 arg->error = 1;
725 return;
726 }
727 arg->error = 0;
728 return;
729 }
731 void
732 gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs,
733 struct gdb_context *ctx)
734 {
735 struct gdb_callback_arg arg;
736 unsigned long reg;
737 struct pt_fpreg freg;
738 char buf[16 * 2 + 1];
740 if (regnum >= NUM_REGS) {
741 dbg_printk("%s: regnum %ld\n", __func__, regnum);
742 goto out_err;
743 }
745 arg.regs = regs;
746 arg.regnum = regnum;
747 arg.reg = &reg;
748 arg.freg = &freg;
749 arg.error = 0;
750 unw_init_running(&gdb_get_reg_callback, (void*)&arg);
751 if (arg.error < 0) {
752 dbg_printk("%s: gdb_get_reg_callback failed\n", __func__);
753 goto out_err;
754 }
756 if (arg.error > 0) {
757 // notify gdb that this register is not supported.
758 // see fetch_register_using_p() in gdb/remote.c.
759 sprintf(buf, "%s", "x");
760 } else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) {
761 sprintf(buf, "%.016lx", swab64(freg.u.bits[0]));
762 sprintf(buf + 16, "%.016lx", swab64(freg.u.bits[1]));
763 } else {
764 sprintf(buf, "%.016lx", swab64(reg));
765 }
766 out:
767 return gdb_send_reply(buf, ctx);
769 out_err:
770 dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum);
771 sprintf(buf, "%s", "E0");
772 goto out;
773 }
774 #endif
776 void
777 gdb_arch_resume(struct cpu_user_regs *regs,
778 unsigned long addr, unsigned long type,
779 struct gdb_context *ctx)
780 {
781 /* XXX */
782 if (type == GDB_STEP) {
783 gdb_send_reply("S01", ctx);
784 }
785 }
787 void
788 gdb_arch_print_state(struct cpu_user_regs *regs)
789 {
790 /* XXX */
791 }
793 void
794 gdb_arch_enter(struct cpu_user_regs *regs)
795 {
796 /* nothing */
797 }
799 void
800 gdb_arch_exit(struct cpu_user_regs *regs)
801 {
802 /* nothing */
803 }
805 /*
806 * Local variables:
807 * mode: C
808 * c-set-style: "BSD"
809 * c-basic-offset: 4
810 * tab-width: 4
811 * End:
812 */