ia64/xen-unstable

changeset 8635:34f2b388beb0

ia64 specific part of gdbstub.

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 = &reg;
   3.593 +	struct ia64_fpreg freg;
   3.594 +
   3.595 +	if (kgdb_gr_reg(regnum, info, &reg, 0) ||
   3.596 +		kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
   3.597 +		kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
   3.598 +		kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
   3.599 +			size = sizeof(reg);
   3.600 +	else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &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, &reg);
   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, &reg);
   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, &reg, 0);
   3.632 +		size = sizeof(reg);
   3.633 +	} else if (regnum == IA64_BSP_REGNUM) {
   3.634 +		unw_get_bsp(info, &reg);
   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 = &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__ */