direct-io.hg
changeset 8635:34f2b388beb0
ia64 specific part of gdbstub.
Signed-off-by: Isaku Yamahtata <yamahata@valinux.co.jp>
Signed-off-by: Isaku Yamahtata <yamahata@valinux.co.jp>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Mon Jan 23 15:47:00 2006 +0100 (2006-01-23) |
parents | d270db8a9092 |
children | 3a62d8978788 |
files | xen/arch/ia64/Makefile xen/arch/ia64/vmx/vmx_process.c xen/arch/ia64/xen/gdbstub.c xen/arch/ia64/xen/hyperprivop.S xen/arch/ia64/xen/ivt.S xen/arch/ia64/xen/process.c xen/arch/ia64/xen/xenmisc.c xen/include/asm-ia64/debugger.h |
line diff
1.1 --- a/xen/arch/ia64/Makefile Mon Jan 23 15:17:14 2006 +0100 1.2 +++ b/xen/arch/ia64/Makefile Mon Jan 23 15:47:00 2006 +0100 1.3 @@ -23,6 +23,10 @@ OBJS += bitop.o clear_page.o flush.o cop 1.4 __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ 1.5 __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o 1.6 1.7 +ifeq ($(crash_debug),y) 1.8 +OBJS += gdbstub.o 1.9 +endif 1.10 + 1.11 # xen stack unwinder 1.12 # unwind_decoder.c is included in unwind.c 1.13 OBJS += unwind.o
2.1 --- a/xen/arch/ia64/vmx/vmx_process.c Mon Jan 23 15:17:14 2006 +0100 2.2 +++ b/xen/arch/ia64/vmx/vmx_process.c Mon Jan 23 15:47:00 2006 +0100 2.3 @@ -41,6 +41,7 @@ 2.4 #include <asm/regionreg.h> 2.5 #include <asm/privop.h> 2.6 #include <asm/ia64_int.h> 2.7 +#include <asm/debugger.h> 2.8 //#include <asm/hpsim_ssc.h> 2.9 #include <asm/dom_fw.h> 2.10 #include <asm/vmx_vcpu.h> 2.11 @@ -108,6 +109,14 @@ vmx_ia64_handle_break (unsigned long ifa 2.12 else do_ssc(vcpu_get_gr_nat(current,36), regs); 2.13 } 2.14 #endif 2.15 +#ifdef CRASH_DEBUG 2.16 + if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs) && 2.17 + IS_VMM_ADDRESS(regs->cr_iip)) { 2.18 + if (iim == 0) 2.19 + show_registers(regs); 2.20 + debugger_trap_fatal(0 /* don't care */, regs); 2.21 + } else 2.22 +#endif 2.23 if (iim == d->arch.breakimm) { 2.24 struct ia64_pal_retval y; 2.25 struct sal_ret_values x;
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/xen/arch/ia64/xen/gdbstub.c Mon Jan 23 15:47:00 2006 +0100 3.3 @@ -0,0 +1,811 @@ 3.4 +/* 3.5 + * ia64-specific cdb routines 3.6 + * cdb xen/ia64 by Isaku Yamahta <yamahata at valinux co jp> 3.7 + * VA Linux Systems Japan K.K. 3.8 + * some routines are stolen from kgdb/ia64. 3.9 + */ 3.10 +/* 3.11 + * 3.12 + * This program is free software; you can redistribute it and/or modify it 3.13 + * under the terms of the GNU General Public License as published by the 3.14 + * Free Software Foundation; either version 2, or (at your option) any 3.15 + * later version. 3.16 + * 3.17 + * This program is distributed in the hope that it will be useful, but 3.18 + * WITHOUT ANY WARRANTY; without even the implied warranty of 3.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3.20 + * General Public License for more details. 3.21 + * 3.22 + */ 3.23 + 3.24 +/* 3.25 + * Copyright (C) 2000-2001 VERITAS Software Corporation. 3.26 + */ 3.27 +/* 3.28 + * Contributor: Lake Stevens Instrument Division$ 3.29 + * Written by: Glenn Engel $ 3.30 + * Updated by: Amit Kale<akale@veritas.com> 3.31 + * Modified for 386 by Jim Kingdon, Cygnus Support. 3.32 + * Origianl kgdb, compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com> 3.33 + * 3.34 + */ 3.35 + 3.36 + 3.37 +#include <xen/lib.h> 3.38 +#include <asm/byteorder.h> 3.39 +#include <asm/debugger.h> 3.40 +#include <asm/uaccess.h> 3.41 + 3.42 +#define USE_UNWIND 3.43 + 3.44 +#ifdef USE_UNWIND 3.45 +#include <asm/unwind.h> 3.46 +#endif 3.47 + 3.48 +/* Printk isn't particularly safe just after we've trapped to the 3.49 + debugger. so avoid it. */ 3.50 +#define dbg_printk(...) 3.51 +//#define dbg_printk(...) printk(__VA_ARGS__) 3.52 + 3.53 +u16 3.54 +gdb_arch_signal_num(struct cpu_user_regs *regs, unsigned long cookie) 3.55 +{ 3.56 + /* XXX */ 3.57 + return 1; 3.58 +} 3.59 + 3.60 +void 3.61 +gdb_arch_read_reg_array(struct cpu_user_regs *regs, struct gdb_context *ctx) 3.62 +{ 3.63 + gdb_send_reply("", ctx); 3.64 +} 3.65 + 3.66 +void 3.67 +gdb_arch_write_reg_array(struct cpu_user_regs *regs, const char* buf, 3.68 + struct gdb_context *ctx) 3.69 +{ 3.70 + /* XXX TODO */ 3.71 + gdb_send_reply("E02", ctx); 3.72 +} 3.73 + 3.74 +/* Like copy_from_user, but safe to call with interrupts disabled. 3.75 + Trust me, and don't look behind the curtain. */ 3.76 +unsigned 3.77 +gdb_arch_copy_from_user(void *dest, const void *src, unsigned len) 3.78 +{ 3.79 + int val; 3.80 + __asm__ __volatile__( 3.81 + "cmp4.eq p6, p0 = r0, %1\n" 3.82 + "(p6) br.cond.dptk 2f\n" 3.83 + "[1:]\n" 3.84 + ".xdata4 \"__ex_table\", 99f-., 2f-.;\n" 3.85 + "[99:] ld1 %0 = [%3], 1\n" 3.86 + ";;\n" 3.87 + ".xdata4 \"__ex_table\", 99f-., 2f-.;\n" 3.88 + "[99:] st1 [%2] = %0, 1\n" 3.89 + "adds %1 = -1, %1\n" 3.90 + ";;\n" 3.91 + "cmp4.eq p0, p6 = r0, %1\n" 3.92 + "(p6) br.cond.dptk 1b\n" 3.93 + "[2:]\n" 3.94 + : "=r"(val), "=r"(len), "=r"(dest), "=r"(src) 3.95 + : "1"(len), "2"(dest), "3"(src) 3.96 + : "memory", "p6"); 3.97 + return len; 3.98 +} 3.99 + 3.100 +unsigned int 3.101 +gdb_arch_copy_to_user(void *dest, const void *src, unsigned len) 3.102 +{ 3.103 + /* XXX */ 3.104 + return len; 3.105 +} 3.106 + 3.107 +#define NUM_REGS 590 3.108 +#define REGISTER_BYTES (NUM_REGS*8+128*8) 3.109 +#define REGISTER_BYTE(N) (((N) * 8) \ 3.110 + + ((N) <= IA64_FR0_REGNUM ? \ 3.111 + 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM))) 3.112 +#define REGISTER_SIZE(N) \ 3.113 + (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8) 3.114 +#define IA64_GR0_REGNUM 0 3.115 +#define IA64_FR0_REGNUM 128 3.116 +#define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127) 3.117 +#define IA64_PR0_REGNUM 256 3.118 +#define IA64_BR0_REGNUM 320 3.119 +#define IA64_VFP_REGNUM 328 3.120 +#define IA64_PR_REGNUM 330 3.121 +#define IA64_IP_REGNUM 331 3.122 +#define IA64_PSR_REGNUM 332 3.123 +#define IA64_CFM_REGNUM 333 3.124 +#define IA64_AR0_REGNUM 334 3.125 +#define IA64_NAT0_REGNUM 462 3.126 +#define IA64_NAT31_REGNUM (IA64_NAT0_REGNUM+31) 3.127 +#define IA64_NAT32_REGNUM (IA64_NAT0_REGNUM+32) 3.128 +#define IA64_RSC_REGNUM (IA64_AR0_REGNUM+16) 3.129 +#define IA64_BSP_REGNUM (IA64_AR0_REGNUM+17) 3.130 +#define IA64_BSPSTORE_REGNUM (IA64_AR0_REGNUM+18) 3.131 +#define IA64_RNAT_REGNUM (IA64_AR0_REGNUM+19) 3.132 +#define IA64_FCR_REGNUM (IA64_AR0_REGNUM+21) 3.133 +#define IA64_EFLAG_REGNUM (IA64_AR0_REGNUM+24) 3.134 +#define IA64_CSD_REGNUM (IA64_AR0_REGNUM+25) 3.135 +#define IA64_SSD_REGNUM (IA64_AR0_REGNUM+26) 3.136 +#define IA64_CFLG_REGNUM (IA64_AR0_REGNUM+27) 3.137 +#define IA64_FSR_REGNUM (IA64_AR0_REGNUM+28) 3.138 +#define IA64_FIR_REGNUM (IA64_AR0_REGNUM+29) 3.139 +#define IA64_FDR_REGNUM (IA64_AR0_REGNUM+30) 3.140 +#define IA64_CCV_REGNUM (IA64_AR0_REGNUM+32) 3.141 +#define IA64_UNAT_REGNUM (IA64_AR0_REGNUM+36) 3.142 +#define IA64_FPSR_REGNUM (IA64_AR0_REGNUM+40) 3.143 +#define IA64_ITC_REGNUM (IA64_AR0_REGNUM+44) 3.144 +#define IA64_PFS_REGNUM (IA64_AR0_REGNUM+64) 3.145 +#define IA64_LC_REGNUM (IA64_AR0_REGNUM+65) 3.146 +#define IA64_EC_REGNUM (IA64_AR0_REGNUM+66) 3.147 + 3.148 +#ifndef USE_UNWIND 3.149 +struct regs_to_cpu_user_resgs_index { 3.150 + unsigned int reg; 3.151 + unsigned int ptregoff; 3.152 +}; 3.153 + 3.154 +#define ptoff(V) ((unsigned int)&((struct cpu_user_regs*)0x0)->V) 3.155 + 3.156 +// gr 3.157 +static const struct regs_to_cpu_user_resgs_index 3.158 +gr_reg_to_cpu_user_regs_index[] = { 3.159 + {IA64_GR0_REGNUM + 8, ptoff(r8)}, 3.160 + {IA64_GR0_REGNUM + 9, ptoff(r9)}, 3.161 + {IA64_GR0_REGNUM + 10, ptoff(r10)}, 3.162 + {IA64_GR0_REGNUM + 11, ptoff(r11)}, 3.163 + {IA64_GR0_REGNUM + 1, ptoff(r1)}, 3.164 + {IA64_GR0_REGNUM + 12, ptoff(r12)}, 3.165 + {IA64_GR0_REGNUM + 13, ptoff(r13)}, 3.166 + {IA64_GR0_REGNUM + 15, ptoff(r15)}, 3.167 + 3.168 + {IA64_GR0_REGNUM + 14, ptoff(r14)}, 3.169 + {IA64_GR0_REGNUM + 2, ptoff(r2)}, 3.170 + {IA64_GR0_REGNUM + 3, ptoff(r3)}, 3.171 + {IA64_GR0_REGNUM + 16, ptoff(r16)}, 3.172 + {IA64_GR0_REGNUM + 17, ptoff(r17)}, 3.173 + {IA64_GR0_REGNUM + 18, ptoff(r18)}, 3.174 + {IA64_GR0_REGNUM + 19, ptoff(r19)}, 3.175 + {IA64_GR0_REGNUM + 20, ptoff(r20)}, 3.176 + {IA64_GR0_REGNUM + 21, ptoff(r21)}, 3.177 + {IA64_GR0_REGNUM + 22, ptoff(r22)}, 3.178 + {IA64_GR0_REGNUM + 23, ptoff(r23)}, 3.179 + {IA64_GR0_REGNUM + 24, ptoff(r24)}, 3.180 + {IA64_GR0_REGNUM + 25, ptoff(r25)}, 3.181 + {IA64_GR0_REGNUM + 26, ptoff(r26)}, 3.182 + {IA64_GR0_REGNUM + 27, ptoff(r27)}, 3.183 + {IA64_GR0_REGNUM + 28, ptoff(r28)}, 3.184 + {IA64_GR0_REGNUM + 29, ptoff(r29)}, 3.185 + {IA64_GR0_REGNUM + 30, ptoff(r30)}, 3.186 + {IA64_GR0_REGNUM + 31, ptoff(r31)}, 3.187 + 3.188 + {IA64_GR0_REGNUM + 4, ptoff(r4)}, 3.189 + {IA64_GR0_REGNUM + 5, ptoff(r5)}, 3.190 + {IA64_GR0_REGNUM + 6, ptoff(r6)}, 3.191 + {IA64_GR0_REGNUM + 7, ptoff(r7)}, 3.192 +}; 3.193 +static const int gr_reg_to_cpu_user_regs_index_max = 3.194 + sizeof(gr_reg_to_cpu_user_regs_index) / 3.195 + sizeof(gr_reg_to_cpu_user_regs_index[0]); 3.196 + 3.197 +// br 3.198 +static const struct regs_to_cpu_user_resgs_index 3.199 +br_reg_to_cpu_user_regs_index[] = { 3.200 + {IA64_BR0_REGNUM + 0, ptoff(b0)}, 3.201 + {IA64_BR0_REGNUM + 6, ptoff(b6)}, 3.202 + {IA64_BR0_REGNUM + 7, ptoff(b7)}, 3.203 +}; 3.204 +static const int br_reg_to_cpu_user_regs_index_max = 3.205 + sizeof(br_reg_to_cpu_user_regs_index) / 3.206 + sizeof(br_reg_to_cpu_user_regs_index[0]); 3.207 + 3.208 +// f 3.209 +static const struct regs_to_cpu_user_resgs_index 3.210 +fr_reg_to_cpu_user_regs_index[] = { 3.211 + {IA64_FR0_REGNUM + 6, ptoff(f6)}, 3.212 + {IA64_FR0_REGNUM + 7, ptoff(f7)}, 3.213 + {IA64_FR0_REGNUM + 8, ptoff(f8)}, 3.214 + {IA64_FR0_REGNUM + 9, ptoff(f9)}, 3.215 + {IA64_FR0_REGNUM + 10, ptoff(f10)}, 3.216 + {IA64_FR0_REGNUM + 11, ptoff(f11)}, 3.217 +}; 3.218 +static const int fr_reg_to_cpu_user_regs_index_max = 3.219 + sizeof(fr_reg_to_cpu_user_regs_index) / 3.220 + sizeof(fr_reg_to_cpu_user_regs_index[0]); 3.221 + 3.222 + 3.223 +void 3.224 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs, 3.225 + struct gdb_context *ctx) 3.226 +{ 3.227 + unsigned long reg = IA64_IP_REGNUM; 3.228 + char buf[9]; 3.229 + int i; 3.230 + 3.231 + dbg_printk("Register read regnum = 0x%lx\n", regnum); 3.232 + if (IA64_GR0_REGNUM <= regnum && regnum <= IA64_GR0_REGNUM + 31) { 3.233 + for (i = 0; i < gr_reg_to_cpu_user_regs_index_max; i++) { 3.234 + if (gr_reg_to_cpu_user_regs_index[i].reg == regnum) { 3.235 + reg = *(unsigned long*)(((char*)regs) + gr_reg_to_cpu_user_regs_index[i].ptregoff); 3.236 + break; 3.237 + } 3.238 + } 3.239 + if (i == gr_reg_to_cpu_user_regs_index_max) { 3.240 + goto out_err; 3.241 + } 3.242 + } else if (IA64_BR0_REGNUM <= regnum && regnum <= IA64_BR0_REGNUM + 7) { 3.243 + for (i = 0; i < br_reg_to_cpu_user_regs_index_max; i++) { 3.244 + if (br_reg_to_cpu_user_regs_index[i].reg == regnum) { 3.245 + reg = *(unsigned long*)(((char*)regs) + br_reg_to_cpu_user_regs_index[i].ptregoff); 3.246 + break; 3.247 + } 3.248 + } 3.249 + if (i == br_reg_to_cpu_user_regs_index_max) { 3.250 + goto out_err; 3.251 + } 3.252 + } else if (IA64_FR0_REGNUM + 6 <= regnum && regnum <= IA64_FR0_REGNUM + 11) { 3.253 + for (i = 0; i < fr_reg_to_cpu_user_regs_index_max; i++) { 3.254 + if (fr_reg_to_cpu_user_regs_index[i].reg == regnum) { 3.255 + reg = *(unsigned long*)(((char*)regs) + fr_reg_to_cpu_user_regs_index[i].ptregoff); 3.256 + break; 3.257 + } 3.258 + } 3.259 + if (i == fr_reg_to_cpu_user_regs_index_max) { 3.260 + goto out_err; 3.261 + } 3.262 + } else if (regnum == IA64_CSD_REGNUM) { 3.263 + reg = regs->ar_csd; 3.264 + } else if (regnum == IA64_SSD_REGNUM) { 3.265 + reg = regs->ar_ssd; 3.266 + } else if (regnum == IA64_PSR_REGNUM) { 3.267 + reg = regs->cr_ipsr; 3.268 + } else if (regnum == IA64_IP_REGNUM) { 3.269 + reg = regs->cr_iip; 3.270 + } else if (regnum == IA64_CFM_REGNUM) { 3.271 + reg = regs->cr_ifs; 3.272 + } else if (regnum == IA64_UNAT_REGNUM) { 3.273 + reg = regs->ar_unat; 3.274 + } else if (regnum == IA64_PFS_REGNUM) { 3.275 + reg = regs->ar_pfs; 3.276 + } else if (regnum == IA64_RSC_REGNUM) { 3.277 + reg = regs->ar_rsc; 3.278 + } else if (regnum == IA64_RNAT_REGNUM) { 3.279 + reg = regs->ar_rnat; 3.280 + } else if (regnum == IA64_BSPSTORE_REGNUM) { 3.281 + reg = regs->ar_bspstore; 3.282 + } else if (regnum == IA64_PR_REGNUM) { 3.283 + reg = regs->pr; 3.284 + } else if (regnum == IA64_FPSR_REGNUM) { 3.285 + reg = regs->ar_fpsr; 3.286 + } else if (regnum == IA64_CCV_REGNUM) { 3.287 + reg = regs->ar_ccv; 3.288 + } else { 3.289 + // emul_unat, rfi_pfs 3.290 + goto out_err; 3.291 + } 3.292 + 3.293 + dbg_printk("Register read regnum = 0x%lx, val = 0x%lx\n", regnum, reg); 3.294 + sprintf(buf, "%.08lx", swab64(reg)); 3.295 +out: 3.296 + return gdb_send_reply(buf, ctx); 3.297 + 3.298 +out_err: 3.299 + dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum); 3.300 + sprintf(buf, "%s", "x"); 3.301 + goto out; 3.302 +} 3.303 +#else 3.304 + 3.305 +#define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V) 3.306 +struct reg_to_ptreg_index { 3.307 + unsigned int reg; 3.308 + unsigned int ptregoff; 3.309 +}; 3.310 + 3.311 +static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = { 3.312 + {IA64_GR0_REGNUM + 1, ptoff(r1)}, 3.313 + {IA64_GR0_REGNUM + 2, ptoff(r2)}, 3.314 + {IA64_GR0_REGNUM + 3, ptoff(r3)}, 3.315 + {IA64_GR0_REGNUM + 8, ptoff(r8)}, 3.316 + {IA64_GR0_REGNUM + 9, ptoff(r9)}, 3.317 + {IA64_GR0_REGNUM + 10, ptoff(r10)}, 3.318 + {IA64_GR0_REGNUM + 11, ptoff(r11)}, 3.319 + {IA64_GR0_REGNUM + 12, ptoff(r12)}, 3.320 + {IA64_GR0_REGNUM + 13, ptoff(r13)}, 3.321 + {IA64_GR0_REGNUM + 14, ptoff(r14)}, 3.322 + {IA64_GR0_REGNUM + 15, ptoff(r15)}, 3.323 + {IA64_GR0_REGNUM + 16, ptoff(r16)}, 3.324 + {IA64_GR0_REGNUM + 17, ptoff(r17)}, 3.325 + {IA64_GR0_REGNUM + 18, ptoff(r18)}, 3.326 + {IA64_GR0_REGNUM + 19, ptoff(r19)}, 3.327 + {IA64_GR0_REGNUM + 20, ptoff(r20)}, 3.328 + {IA64_GR0_REGNUM + 21, ptoff(r21)}, 3.329 + {IA64_GR0_REGNUM + 22, ptoff(r22)}, 3.330 + {IA64_GR0_REGNUM + 23, ptoff(r23)}, 3.331 + {IA64_GR0_REGNUM + 24, ptoff(r24)}, 3.332 + {IA64_GR0_REGNUM + 25, ptoff(r25)}, 3.333 + {IA64_GR0_REGNUM + 26, ptoff(r26)}, 3.334 + {IA64_GR0_REGNUM + 27, ptoff(r27)}, 3.335 + {IA64_GR0_REGNUM + 28, ptoff(r28)}, 3.336 + {IA64_GR0_REGNUM + 29, ptoff(r29)}, 3.337 + {IA64_GR0_REGNUM + 30, ptoff(r30)}, 3.338 + {IA64_GR0_REGNUM + 31, ptoff(r31)}, 3.339 +}; 3.340 + 3.341 +static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = { 3.342 + {IA64_BR0_REGNUM, ptoff(b0)}, 3.343 + {IA64_BR0_REGNUM + 6, ptoff(b6)}, 3.344 + {IA64_BR0_REGNUM + 7, ptoff(b7)}, 3.345 +}; 3.346 + 3.347 +static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = { 3.348 + {IA64_PFS_REGNUM, ptoff(ar_pfs)}, 3.349 + {IA64_UNAT_REGNUM, ptoff(ar_unat)}, 3.350 + {IA64_RNAT_REGNUM, ptoff(ar_rnat)}, 3.351 + {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)}, 3.352 + {IA64_RSC_REGNUM, ptoff(ar_rsc)}, 3.353 + {IA64_CSD_REGNUM, ptoff(ar_csd)}, 3.354 + {IA64_SSD_REGNUM, ptoff(ar_ssd)}, 3.355 + {IA64_FPSR_REGNUM, ptoff(ar_fpsr)}, 3.356 + {IA64_CCV_REGNUM, ptoff(ar_ccv)}, 3.357 +}; 3.358 + 3.359 +#ifndef XEN 3.360 +extern atomic_t cpu_doing_single_step; 3.361 +#endif 3.362 + 3.363 +static int kgdb_gr_reg(int regnum, struct unw_frame_info *info, 3.364 + unsigned long *reg, int rw) 3.365 +{ 3.366 + char nat; 3.367 + 3.368 + if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) || 3.369 + (regnum >= (IA64_GR0_REGNUM + 4) && 3.370 + regnum <= (IA64_GR0_REGNUM + 7))) 3.371 + return !unw_access_gr(info, regnum - IA64_GR0_REGNUM, 3.372 + reg, &nat, rw); 3.373 + else 3.374 + return 0; 3.375 +} 3.376 +static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs, 3.377 + struct unw_frame_info *info, unsigned long *reg, int rw) 3.378 +{ 3.379 + int i, result = 1; 3.380 + char nat; 3.381 + 3.382 + if (!((regnum >= (IA64_GR0_REGNUM + 2) && 3.383 + regnum <= (IA64_GR0_REGNUM + 3)) || 3.384 + (regnum >= (IA64_GR0_REGNUM + 8) && 3.385 + regnum <= (IA64_GR0_REGNUM + 15)) || 3.386 + (regnum >= (IA64_GR0_REGNUM + 16) && 3.387 + regnum <= (IA64_GR0_REGNUM + 31)))) 3.388 + return 0; 3.389 + else if (rw && ptregs) { 3.390 + for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++) 3.391 + if (gr_reg_to_ptreg_index[i].reg == regnum) { 3.392 + *((unsigned long *)(((void *)ptregs) + 3.393 + gr_reg_to_ptreg_index[i].ptregoff)) = *reg; 3.394 + break; 3.395 + } 3.396 + } else if (!rw && ptregs) { 3.397 + for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++) 3.398 + if (gr_reg_to_ptreg_index[i].reg == regnum) { 3.399 + *reg = *((unsigned long *) 3.400 + (((void *)ptregs) + 3.401 + gr_reg_to_ptreg_index[i].ptregoff)); 3.402 + break; 3.403 + } 3.404 + } else 3.405 + result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM, 3.406 + reg, &nat, rw); 3.407 + return result; 3.408 +} 3.409 + 3.410 +static int kgdb_br_reg(int regnum, struct pt_regs * ptregs, 3.411 + struct unw_frame_info *info, unsigned long *reg, int rw) 3.412 +{ 3.413 + int i, result = 1; 3.414 + 3.415 + if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))) 3.416 + return 0; 3.417 + 3.418 + switch (regnum) { 3.419 + case IA64_BR0_REGNUM: 3.420 + case IA64_BR0_REGNUM + 6: 3.421 + case IA64_BR0_REGNUM + 7: 3.422 + if (rw) { 3.423 + for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++) 3.424 + if (br_reg_to_ptreg_index[i].reg == regnum) { 3.425 + *((unsigned long *) 3.426 + (((void *)ptregs) + 3.427 + br_reg_to_ptreg_index[i].ptregoff)) = 3.428 + *reg; 3.429 + break; 3.430 + } 3.431 + } else 3.432 + for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++) 3.433 + if (br_reg_to_ptreg_index[i].reg == regnum) { 3.434 + *reg = *((unsigned long *) 3.435 + (((void *)ptregs) + 3.436 + br_reg_to_ptreg_index[i]. 3.437 + ptregoff)); 3.438 + break; 3.439 + } 3.440 + break; 3.441 + case IA64_BR0_REGNUM + 1: 3.442 + case IA64_BR0_REGNUM + 2: 3.443 + case IA64_BR0_REGNUM + 3: 3.444 + case IA64_BR0_REGNUM + 4: 3.445 + case IA64_BR0_REGNUM + 5: 3.446 + result = !unw_access_br(info, regnum - IA64_BR0_REGNUM, 3.447 + reg, rw); 3.448 + break; 3.449 + } 3.450 + 3.451 + return result; 3.452 +} 3.453 + 3.454 +static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs, 3.455 + struct unw_frame_info *info, unsigned long *reg, 3.456 + struct ia64_fpreg *freg, int rw) 3.457 +{ 3.458 + int result = 1; 3.459 + 3.460 + if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127))) 3.461 + return 0; 3.462 + 3.463 + switch (regnum) { 3.464 + case IA64_FR0_REGNUM + 6: 3.465 + case IA64_FR0_REGNUM + 7: 3.466 + case IA64_FR0_REGNUM + 8: 3.467 + case IA64_FR0_REGNUM + 9: 3.468 + case IA64_FR0_REGNUM + 10: 3.469 + case IA64_FR0_REGNUM + 11: 3.470 + case IA64_FR0_REGNUM + 12: 3.471 + if (rw) { 3.472 +#ifndef XEN 3.473 + char *ptr = inbuffer; 3.474 + 3.475 + freg->u.bits[0] = *reg; 3.476 + kgdb_hex2long(&ptr, &freg->u.bits[1]); 3.477 + *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) = 3.478 + *freg; 3.479 +#else 3.480 + printk("%s: %d: writing to fpreg is not supported.\n", 3.481 + __func__, __LINE__); 3.482 +#endif 3.483 + break; 3.484 + } else if (!ptregs) 3.485 + result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM, 3.486 + freg, rw); 3.487 + else 3.488 +#ifndef XEN 3.489 + *freg = 3.490 + *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))); 3.491 +#else 3.492 + //XXX struct ia64_fpreg and struct pt_fpreg are same. 3.493 + *freg = *((struct ia64_fpreg*)(&ptregs->f6 + 3.494 + (regnum - (IA64_FR0_REGNUM + 6)))); 3.495 +#endif 3.496 + break; 3.497 + default: 3.498 + if (!rw) 3.499 + result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM, 3.500 + freg, rw); 3.501 + else 3.502 + result = 0; 3.503 + break; 3.504 + } 3.505 + 3.506 + return result; 3.507 +} 3.508 + 3.509 +static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs, 3.510 + struct unw_frame_info *info, unsigned long *reg, int rw) 3.511 +{ 3.512 + int result = 0, i; 3.513 + 3.514 + if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)) 3.515 + return 0; 3.516 + 3.517 + if (rw && ptregs) { 3.518 + for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++) 3.519 + if (ar_reg_to_ptreg_index[i].reg == regnum) { 3.520 + *((unsigned long *) (((void *)ptregs) + 3.521 + ar_reg_to_ptreg_index[i].ptregoff)) = 3.522 + *reg; 3.523 + result = 1; 3.524 + break; 3.525 + } 3.526 + } else if (ptregs) { 3.527 + for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++) 3.528 + if (ar_reg_to_ptreg_index[i].reg == regnum) { 3.529 + *reg = *((unsigned long *) (((void *)ptregs) + 3.530 + ar_reg_to_ptreg_index[i].ptregoff)); 3.531 + result = 1; 3.532 + break; 3.533 + } 3.534 + } 3.535 + 3.536 + if (result) 3.537 + return result; 3.538 + 3.539 + result = 1; 3.540 + 3.541 + switch (regnum) { 3.542 + case IA64_CSD_REGNUM: 3.543 + result = !unw_access_ar(info, UNW_AR_CSD, reg, rw); 3.544 + break; 3.545 + case IA64_SSD_REGNUM: 3.546 + result = !unw_access_ar(info, UNW_AR_SSD, reg, rw); 3.547 + break; 3.548 + case IA64_UNAT_REGNUM: 3.549 + result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw); 3.550 + break; 3.551 + case IA64_RNAT_REGNUM: 3.552 + result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw); 3.553 + break; 3.554 + case IA64_BSPSTORE_REGNUM: 3.555 + result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw); 3.556 + break; 3.557 + case IA64_PFS_REGNUM: 3.558 + result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw); 3.559 + break; 3.560 + case IA64_LC_REGNUM: 3.561 + result = !unw_access_ar(info, UNW_AR_LC, reg, rw); 3.562 + break; 3.563 + case IA64_EC_REGNUM: 3.564 + result = !unw_access_ar(info, UNW_AR_EC, reg, rw); 3.565 + break; 3.566 + case IA64_FPSR_REGNUM: 3.567 + result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw); 3.568 + break; 3.569 + case IA64_RSC_REGNUM: 3.570 + result = !unw_access_ar(info, UNW_AR_RSC, reg, rw); 3.571 + break; 3.572 + case IA64_CCV_REGNUM: 3.573 + result = !unw_access_ar(info, UNW_AR_CCV, reg, rw); 3.574 + break; 3.575 + default: 3.576 + result = 0; 3.577 + } 3.578 + 3.579 + return result; 3.580 +} 3.581 + 3.582 +#ifndef XEN 3.583 +void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info, 3.584 + struct pt_regs *ptregs) 3.585 +#else 3.586 +static int 3.587 +kgdb_get_reg(int regnum, struct unw_frame_info *info, 3.588 + struct cpu_user_regs* ptregs, 3.589 + unsigned long* __reg, struct ia64_fpreg* __freg) 3.590 +#endif 3.591 +{ 3.592 + unsigned long reg, size = 0, *mem = ® 3.593 + struct ia64_fpreg freg; 3.594 + 3.595 + if (kgdb_gr_reg(regnum, info, ®, 0) || 3.596 + kgdb_gr_ptreg(regnum, ptregs, info, ®, 0) || 3.597 + kgdb_br_reg(regnum, ptregs, info, ®, 0) || 3.598 + kgdb_ar_reg(regnum, ptregs, info, ®, 0)) 3.599 + size = sizeof(reg); 3.600 + else if (kgdb_fr_reg(regnum, NULL, ptregs, info, ®, &freg, 0)) { 3.601 + size = sizeof(freg); 3.602 + mem = (unsigned long *)&freg; 3.603 + } else if (regnum == IA64_IP_REGNUM) { 3.604 + if (!ptregs) { 3.605 + unw_get_ip(info, ®); 3.606 + size = sizeof(reg); 3.607 + } else { 3.608 + reg = ptregs->cr_iip; 3.609 + size = sizeof(reg); 3.610 + } 3.611 + } else if (regnum == IA64_CFM_REGNUM) { 3.612 + if (!ptregs) 3.613 + unw_get_cfm(info, ®); 3.614 + else 3.615 + reg = ptregs->cr_ifs; 3.616 + size = sizeof(reg); 3.617 + } else if (regnum == IA64_PSR_REGNUM) { 3.618 +#ifndef XEN 3.619 + if (!ptregs && kgdb_usethread) 3.620 + ptregs = (struct pt_regs *) 3.621 + ((unsigned long)kgdb_usethread + 3.622 + IA64_STK_OFFSET) - 1; 3.623 +#endif 3.624 + if (ptregs) 3.625 + reg = ptregs->cr_ipsr; 3.626 + size = sizeof(reg); 3.627 + } else if (regnum == IA64_PR_REGNUM) { 3.628 + if (ptregs) 3.629 + reg = ptregs->pr; 3.630 + else 3.631 + unw_access_pr(info, ®, 0); 3.632 + size = sizeof(reg); 3.633 + } else if (regnum == IA64_BSP_REGNUM) { 3.634 + unw_get_bsp(info, ®); 3.635 + size = sizeof(reg); 3.636 + } 3.637 + 3.638 +#ifndef XEN 3.639 + if (size) { 3.640 + kgdb_mem2hex((char *) mem, outbuffer, size); 3.641 + outbuffer[size*2] = 0; 3.642 + } 3.643 + else 3.644 + strcpy(outbuffer, "E0"); 3.645 + 3.646 + return; 3.647 +#else 3.648 + if (size) { 3.649 + if (size == sizeof(reg)) { 3.650 + *__reg = reg; 3.651 + } else { 3.652 + BUG_ON(size != sizeof(freg)); 3.653 + *__freg = freg; 3.654 + } 3.655 + return 0; 3.656 + } 3.657 + 3.658 + return -1; 3.659 +#endif 3.660 +} 3.661 + 3.662 +#ifndef XEN 3.663 +static int inline kgdb_get_blocked_state(struct task_struct *p, 3.664 + struct unw_frame_info *unw) 3.665 +#else 3.666 +static int 3.667 +kgdb_get_blocked_state(struct vcpu *p, 3.668 + struct cpu_user_regs *regs, 3.669 + struct unw_frame_info *unw) 3.670 +#endif 3.671 +{ 3.672 + unsigned long ip; 3.673 + int count = 0; 3.674 + 3.675 +#ifndef XEN 3.676 + unw_init_from_blocked_task(unw, p); 3.677 +#endif 3.678 + ip = 0UL; 3.679 + do { 3.680 + if (unw_unwind(unw) < 0) 3.681 + return -1; 3.682 + unw_get_ip(unw, &ip); 3.683 +#ifndef XEN 3.684 + if (!in_sched_functions(ip)) 3.685 + break; 3.686 +#else 3.687 + dbg_printk("ip 0x%lx cr_iip 0x%lx\n", ip, regs->cr_iip); 3.688 + if (ip == regs->cr_iip) 3.689 + break; 3.690 +#endif 3.691 + } while (count++ < 16); 3.692 + 3.693 + if (!ip) 3.694 + return -1; 3.695 + else 3.696 + return 0; 3.697 +} 3.698 + 3.699 +struct gdb_callback_arg 3.700 +{ 3.701 + struct cpu_user_regs* regs; 3.702 + unsigned long regnum; 3.703 + unsigned long* reg; 3.704 + struct pt_fpreg* freg; 3.705 + 3.706 + int error; 3.707 + // 1: not supported 3.708 + // 0: success 3.709 + // -1: failure 3.710 +}; 3.711 + 3.712 +static void 3.713 +gdb_get_reg_callback(struct unw_frame_info* info, void* __arg) 3.714 +{ 3.715 + struct gdb_callback_arg* arg = (struct gdb_callback_arg*)__arg; 3.716 + 3.717 + if (kgdb_get_blocked_state(current, arg->regs, info) < 0) { 3.718 + dbg_printk("%s: kgdb_get_blocked_state failed\n", __func__); 3.719 + arg->error = -1; 3.720 + return; 3.721 + } 3.722 + //XXX struct ia64_fpreg and struct pt_fpreg are same. 3.723 + if (kgdb_get_reg(arg->regnum, info, arg->regs, arg->reg, 3.724 + (struct ia64_fpreg*)arg->freg) < 0) { 3.725 + dbg_printk("%s: kgdb_get_reg failed\n", __func__); 3.726 + arg->error = 1; 3.727 + return; 3.728 + } 3.729 + arg->error = 0; 3.730 + return; 3.731 +} 3.732 + 3.733 +void 3.734 +gdb_arch_read_reg(unsigned long regnum, struct cpu_user_regs *regs, 3.735 + struct gdb_context *ctx) 3.736 +{ 3.737 + struct gdb_callback_arg arg; 3.738 + unsigned long reg; 3.739 + struct pt_fpreg freg; 3.740 + char buf[16 * 2 + 1]; 3.741 + 3.742 + if (regnum >= NUM_REGS) { 3.743 + dbg_printk("%s: regnum %ld\n", __func__, regnum); 3.744 + goto out_err; 3.745 + } 3.746 + 3.747 + arg.regs = regs; 3.748 + arg.regnum = regnum; 3.749 + arg.reg = ® 3.750 + arg.freg = &freg; 3.751 + arg.error = 0; 3.752 + unw_init_running(&gdb_get_reg_callback, (void*)&arg); 3.753 + if (arg.error < 0) { 3.754 + dbg_printk("%s: gdb_get_reg_callback failed\n", __func__); 3.755 + goto out_err; 3.756 + } 3.757 + 3.758 + if (arg.error > 0) { 3.759 + // notify gdb that this register is not supported. 3.760 + // see fetch_register_using_p() in gdb/remote.c. 3.761 + sprintf(buf, "%s", "x"); 3.762 + } else if (IA64_FR0_REGNUM <= regnum && regnum <= IA64_FR0_REGNUM + 127) { 3.763 + sprintf(buf, "%.016lx", swab64(freg.u.bits[0])); 3.764 + sprintf(buf + 16, "%.016lx", swab64(freg.u.bits[1])); 3.765 + } else { 3.766 + sprintf(buf, "%.016lx", swab64(reg)); 3.767 + } 3.768 +out: 3.769 + return gdb_send_reply(buf, ctx); 3.770 + 3.771 +out_err: 3.772 + dbg_printk("Register read unsupported regnum = 0x%lx\n", regnum); 3.773 + sprintf(buf, "%s", "E0"); 3.774 + goto out; 3.775 +} 3.776 +#endif 3.777 + 3.778 +void 3.779 +gdb_arch_resume(struct cpu_user_regs *regs, 3.780 + unsigned long addr, unsigned long type, 3.781 + struct gdb_context *ctx) 3.782 +{ 3.783 + /* XXX */ 3.784 + if (type == GDB_STEP) { 3.785 + gdb_send_reply("S01", ctx); 3.786 + } 3.787 +} 3.788 + 3.789 +void 3.790 +gdb_arch_print_state(struct cpu_user_regs *regs) 3.791 +{ 3.792 + /* XXX */ 3.793 +} 3.794 + 3.795 +void 3.796 +gdb_arch_enter(struct cpu_user_regs *regs) 3.797 +{ 3.798 + /* nothing */ 3.799 +} 3.800 + 3.801 +void 3.802 +gdb_arch_exit(struct cpu_user_regs *regs) 3.803 +{ 3.804 + /* nothing */ 3.805 +} 3.806 + 3.807 +/* 3.808 + * Local variables: 3.809 + * mode: C 3.810 + * c-set-style: "BSD" 3.811 + * c-basic-offset: 4 3.812 + * tab-width: 4 3.813 + * End: 3.814 + */
4.1 --- a/xen/arch/ia64/xen/hyperprivop.S Mon Jan 23 15:17:14 2006 +0100 4.2 +++ b/xen/arch/ia64/xen/hyperprivop.S Mon Jan 23 15:47:00 2006 +0100 4.3 @@ -12,6 +12,7 @@ 4.4 #include <asm/offsets.h> 4.5 #include <asm/processor.h> 4.6 #include <asm/system.h> 4.7 +#include <asm/debugger.h> 4.8 #include <public/arch-ia64.h> 4.9 4.10 4.11 @@ -549,7 +550,12 @@ GLOBAL_ENTRY(fast_break_reflect) 4.12 (p7) br.spnt.many 1f ;; 4.13 cmp.eq p7,p0=r17,r0 4.14 (p7) br.spnt.few dispatch_break_fault ;; 4.15 -1: 4.16 +#ifdef CRASH_DEBUG 4.17 + movl r21=CDB_BREAK_NUM ;; 4.18 + cmp.eq p7,p0=r17,r21 4.19 +(p7) br.spnt.few dispatch_break_fault ;; 4.20 +#endif 4.21 +1: 4.22 #if 1 /* special handling in case running on simulator */ 4.23 movl r20=first_break;; 4.24 ld4 r23=[r20];;
5.1 --- a/xen/arch/ia64/xen/ivt.S Mon Jan 23 15:17:14 2006 +0100 5.2 +++ b/xen/arch/ia64/xen/ivt.S Mon Jan 23 15:47:00 2006 +0100 5.3 @@ -15,6 +15,7 @@ 5.4 #define sys_call_table 0 5.5 #define sys_ni_syscall 0 5.6 #include <asm/vhpt.h> 5.7 +#include <asm/debugger.h> 5.8 #endif 5.9 /* 5.10 * arch/ia64/kernel/ivt.S 5.11 @@ -841,6 +842,13 @@ ENTRY(break_fault) 5.12 ;; 5.13 cmp.eq p7,p0=r17,r0 5.14 (p7) br.spnt.few dispatch_break_fault ;; 5.15 +#ifdef CRASH_DEBUG 5.16 + // panic can occur before domain0 is created. 5.17 + // in such case referencing XSI_PSR_IC causes nested_dtlb_miss 5.18 + movl r18=CDB_BREAK_NUM ;; 5.19 + cmp.eq p7,p0=r17,r18 ;; 5.20 +(p7) br.spnt.few dispatch_break_fault ;; 5.21 +#endif 5.22 movl r18=XSI_PSR_IC 5.23 ;; 5.24 ld8 r19=[r18]
6.1 --- a/xen/arch/ia64/xen/process.c Mon Jan 23 15:17:14 2006 +0100 6.2 +++ b/xen/arch/ia64/xen/process.c Mon Jan 23 15:47:00 2006 +0100 6.3 @@ -31,6 +31,7 @@ 6.4 #include <asm/dom_fw.h> 6.5 #include "hpsim_ssc.h" 6.6 #include <xen/multicall.h> 6.7 +#include <asm/debugger.h> 6.8 6.9 extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64); 6.10 extern void die_if_kernel(char *str, struct pt_regs *regs, long err); 6.11 @@ -652,7 +653,7 @@ void 6.12 ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, unsigned long iim) 6.13 { 6.14 struct domain *d = (struct domain *) current->domain; 6.15 - struct vcpu *v = (struct domain *) current; 6.16 + struct vcpu *v = current; 6.17 extern unsigned long running_on_sim; 6.18 6.19 if (first_break) { 6.20 @@ -663,7 +664,14 @@ ia64_handle_break (unsigned long ifa, st 6.21 if (iim == 0x80001 || iim == 0x80002) { //FIXME: don't hardcode constant 6.22 if (running_on_sim) do_ssc(vcpu_get_gr(current,36), regs); 6.23 else do_ssc(vcpu_get_gr(current,36), regs); 6.24 - } 6.25 + } 6.26 +#ifdef CRASH_DEBUG 6.27 + else if ((iim == 0 || iim == CDB_BREAK_NUM) && !user_mode(regs)) { 6.28 + if (iim == 0) 6.29 + show_registers(regs); 6.30 + debugger_trap_fatal(0 /* don't care */, regs); 6.31 + } 6.32 +#endif 6.33 else if (iim == d->arch.breakimm) { 6.34 /* by default, do not continue */ 6.35 v->arch.hypercall_continuation = 0;
7.1 --- a/xen/arch/ia64/xen/xenmisc.c Mon Jan 23 15:17:14 2006 +0100 7.2 +++ b/xen/arch/ia64/xen/xenmisc.c Mon Jan 23 15:47:00 2006 +0100 7.3 @@ -18,6 +18,7 @@ 7.4 #include <xen/softirq.h> 7.5 #include <public/sched.h> 7.6 #include <asm/vhpt.h> 7.7 +#include <asm/debugger.h> 7.8 7.9 efi_memory_desc_t ia64_efi_io_md; 7.10 EXPORT_SYMBOL(ia64_efi_io_md); 7.11 @@ -356,6 +357,11 @@ loop: 7.12 va_end(args); 7.13 printf(buf); 7.14 if (regs) show_registers(regs); 7.15 + if (regs) { 7.16 + debugger_trap_fatal(0 /* don't care */, regs); 7.17 + } else { 7.18 + debugger_trap_immediate(); 7.19 + } 7.20 domain_pause_by_systemcontroller(current->domain); 7.21 v->domain->shutdown_code = SHUTDOWN_crash; 7.22 set_bit(_DOMF_shutdown, v->domain->domain_flags);
8.1 --- a/xen/include/asm-ia64/debugger.h Mon Jan 23 15:17:14 2006 +0100 8.2 +++ b/xen/include/asm-ia64/debugger.h Mon Jan 23 15:47:00 2006 +0100 8.3 @@ -24,6 +24,54 @@ 8.4 8.5 #include <xen/softirq.h> 8.6 8.7 +// this number is an arbitary number which is not used for any other purpose 8.8 +// __builtin_trap(), FORCE_CRASH() 0x0 8.9 +// ski 0x80001, 0x80002 8.10 +// kdb 0x80100, 0x80101 8.11 +// kprobe 0x80200, jprobe 0x80300 8.12 +// kgdb 0x6665 8.13 +// gdb 0x99998 (#define IA64_BREAKPOINT 0x00003333300LL) 8.14 + 8.15 +// cdb should handle 0 and CDB_BREAK_NUM. 8.16 +#define CDB_BREAK_NUM 0x80800 8.17 + 8.18 + 8.19 +#ifndef __ASSEMBLY__ 8.20 + 8.21 +#include <xen/gdbstub.h> 8.22 + 8.23 +// NOTE: on xen struct pt_regs = struct cpu_user_regs 8.24 +// see include/asm-ia64/linux-xen/asm/ptrace.h 8.25 +#ifdef CRASH_DEBUG 8.26 +// crash_debug=y 8.27 + 8.28 +/* The main trap handlers use these helper macros which include early bail. */ 8.29 +static inline int debugger_trap_entry( 8.30 + unsigned int vector, struct cpu_user_regs *regs) 8.31 +{ 8.32 + return 0; 8.33 +} 8.34 + 8.35 +extern int __trap_to_cdb(struct cpu_user_regs *r); 8.36 +static inline int debugger_trap_fatal( 8.37 + unsigned int vector, struct cpu_user_regs *regs) 8.38 +{ 8.39 + (void)__trap_to_gdb(regs, vector); 8.40 + return 0; 8.41 +} 8.42 + 8.43 +#define ____debugger_trap_immediate(b) __asm__ __volatile__ ("break.m "#b"\n") 8.44 +#define __debugger_trap_immediate(b) ____debugger_trap_immediate(b) 8.45 +#define debugger_trap_immediate() __debugger_trap_immediate(CDB_BREAK_NUM) 8.46 + 8.47 +//XXX temporal work around 8.48 +#ifndef CONFIG_SMP 8.49 +#define smp_send_stop() /* nothing */ 8.50 +#endif 8.51 + 8.52 +#elif defined DOMU_DEBUG 8.53 +// domu_debug=y 8.54 +#warning "domu_debug is not implemented yet." 8.55 /* The main trap handlers use these helper macros which include early bail. */ 8.56 static inline int debugger_trap_entry( 8.57 unsigned int vector, struct cpu_user_regs *regs) 8.58 @@ -37,6 +85,23 @@ static inline int debugger_trap_fatal( 8.59 return 0; 8.60 } 8.61 8.62 -#define debugger_trap_immediate() do {} while(0) 8.63 +#define debugger_trap_immediate() ((void)0) 8.64 +#else 8.65 +/* The main trap handlers use these helper macros which include early bail. */ 8.66 +static inline int debugger_trap_entry( 8.67 + unsigned int vector, struct cpu_user_regs *regs) 8.68 +{ 8.69 + return 0; 8.70 +} 8.71 + 8.72 +static inline int debugger_trap_fatal( 8.73 + unsigned int vector, struct cpu_user_regs *regs) 8.74 +{ 8.75 + return 0; 8.76 +} 8.77 + 8.78 +#define debugger_trap_immediate() ((void)0) 8.79 +#endif 8.80 +#endif // __ASSEMBLLY__ 8.81 8.82 #endif /* __ASM_DEBUGGER_H__ */