logo       

[PATCH] ia64 fixes and clean up: msg#00102

linux.kernel.debugging.kgdb.bugs

Subject: [PATCH] ia64 fixes and clean up


This patch fixes various register fetch/put methods and does a general
code clean up and restructuring for fetch/put. The patch is based
on work I did last fall; anticipating the arrival of a libunwind replacing
the current unwind code. The code was tested on a two processor rx2600.

Signed-off-by: Bob Picco <bob.picco@xxxxxx>

arch/ia64/kernel/kgdb.c | 578 ++++++++++++++++++++++++++----------------------
1 file changed, 315 insertions(+), 263 deletions(-)

Index: linux-2.6.15-kgdb/arch/ia64/kernel/kgdb.c
===================================================================
--- linux-2.6.15-kgdb.orig/arch/ia64/kernel/kgdb.c 2006-01-11
13:45:23.000000000 -0500
+++ linux-2.6.15-kgdb/arch/ia64/kernel/kgdb.c 2006-01-11 14:21:56.000000000
-0500
@@ -14,6 +14,8 @@

/*
* Copyright (C) 2000-2001 VERITAS Software Corporation.
+ * (c) Copyright 2005 Hewlett-Packard Development Company, L.P.
+ * Bob Picco <bob.picco@xxxxxx>
*/
/*
* Contributor: Lake Stevens Instrument Division$
@@ -40,9 +42,11 @@

#define NUM_REGS 590
#define REGISTER_BYTES (NUM_REGS*8+128*8)
-#define REGISTER_BYTE(N) (((N) * 8) \
- + ((N) <= IA64_FR0_REGNUM ? 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) -
IA64_FR0_REGNUM)))
-#define REGISTER_SIZE(N) (((N) >= IA64_FR0_REGNUM && (N) <=
IA64_FR127_REGNUM) ? 16 : 8)
+#define REGISTER_BYTE(N) (((N) * 8) \
+ + ((N) <= IA64_FR0_REGNUM ? \
+ 0 : 8 * (((N) > IA64_FR127_REGNUM) ? 128 : (N) - IA64_FR0_REGNUM)))
+#define REGISTER_SIZE(N) \
+ (((N) >= IA64_FR0_REGNUM && (N) <= IA64_FR127_REGNUM) ? 16 : 8)
#define IA64_GR0_REGNUM 0
#define IA64_FR0_REGNUM 128
#define IA64_FR127_REGNUM (IA64_FR0_REGNUM+127)
@@ -77,136 +81,308 @@
#define IA64_LC_REGNUM (IA64_AR0_REGNUM+65)
#define IA64_EC_REGNUM (IA64_AR0_REGNUM+66)

-#define REGISTER_INDEX(N) (REGISTER_BYTE(N) / sizeof (unsigned
long))
+#define REGISTER_INDEX(N) (REGISTER_BYTE(N) / sizeof (unsigned long))

-#define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V)
+#define ptoff(V) ((unsigned int) &((struct pt_regs *)0x0)->V)
struct reg_to_ptreg_index {
unsigned int reg;
unsigned int ptregoff;
};
-struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
+
+static struct reg_to_ptreg_index gr_reg_to_ptreg_index[] = {
+ {IA64_GR0_REGNUM + 1, ptoff(r1)},
+ {IA64_GR0_REGNUM + 2, ptoff(r2)},
+ {IA64_GR0_REGNUM + 3, ptoff(r3)},
{IA64_GR0_REGNUM + 8, ptoff(r8)},
{IA64_GR0_REGNUM + 9, ptoff(r9)},
{IA64_GR0_REGNUM + 10, ptoff(r10)},
{IA64_GR0_REGNUM + 11, ptoff(r11)},
- {IA64_GR0_REGNUM + 1, ptoff(r1)},
{IA64_GR0_REGNUM + 12, ptoff(r12)},
{IA64_GR0_REGNUM + 13, ptoff(r13)},
{IA64_GR0_REGNUM + 14, ptoff(r14)},
{IA64_GR0_REGNUM + 15, ptoff(r15)},
+ {IA64_GR0_REGNUM + 16, ptoff(r16)},
+ {IA64_GR0_REGNUM + 17, ptoff(r17)},
+ {IA64_GR0_REGNUM + 18, ptoff(r18)},
+ {IA64_GR0_REGNUM + 19, ptoff(r19)},
+ {IA64_GR0_REGNUM + 20, ptoff(r20)},
+ {IA64_GR0_REGNUM + 21, ptoff(r21)},
+ {IA64_GR0_REGNUM + 22, ptoff(r22)},
+ {IA64_GR0_REGNUM + 23, ptoff(r23)},
+ {IA64_GR0_REGNUM + 24, ptoff(r24)},
+ {IA64_GR0_REGNUM + 25, ptoff(r25)},
+ {IA64_GR0_REGNUM + 26, ptoff(r26)},
+ {IA64_GR0_REGNUM + 27, ptoff(r27)},
+ {IA64_GR0_REGNUM + 28, ptoff(r28)},
+ {IA64_GR0_REGNUM + 29, ptoff(r29)},
+ {IA64_GR0_REGNUM + 30, ptoff(r30)},
+ {IA64_GR0_REGNUM + 31, ptoff(r31)},
};

-struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
+static struct reg_to_ptreg_index br_reg_to_ptreg_index[] = {
{IA64_BR0_REGNUM, ptoff(b0)},
{IA64_BR0_REGNUM + 6, ptoff(b6)},
{IA64_BR0_REGNUM + 7, ptoff(b7)},
};

+static struct reg_to_ptreg_index ar_reg_to_ptreg_index[] = {
+ {IA64_PFS_REGNUM, ptoff(ar_pfs)},
+ {IA64_UNAT_REGNUM, ptoff(ar_unat)},
+ {IA64_RNAT_REGNUM, ptoff(ar_rnat)},
+ {IA64_BSPSTORE_REGNUM, ptoff(ar_bspstore)},
+ {IA64_RSC_REGNUM, ptoff(ar_rsc)},
+ {IA64_CSD_REGNUM, ptoff(ar_csd)},
+ {IA64_SSD_REGNUM, ptoff(ar_ssd)},
+ {IA64_FPSR_REGNUM, ptoff(ar_fpsr)},
+ {IA64_CCV_REGNUM, ptoff(ar_ccv)},
+};
+
extern atomic_t cpu_doing_single_step;

-void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
- struct pt_regs *ptregs)
+static int kgdb_gr_reg(int regnum, struct unw_frame_info *info,
+ unsigned long *reg, int rw)
{
- unsigned long reg, size = 0, *mem = &reg;
char nat;
- struct ia64_fpreg freg;
- int i;

if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
- (regnum >= (IA64_GR0_REGNUM + 4) && regnum <= (IA64_GR0_REGNUM + 7))
- || (regnum >= (IA64_GR0_REGNUM + 16)
- && regnum <= (IA64_GR0_REGNUM + 31))) {
- unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg, &nat, 0);
- size = sizeof(reg);
+ (regnum >= (IA64_GR0_REGNUM + 4) &&
+ regnum <= (IA64_GR0_REGNUM + 7)))
+ return !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+ reg, &nat, rw);
+ else
+ return 0;
+}
+
+static int kgdb_gr_ptreg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int i, result = 1;
+ char nat;
+
+ if (!((regnum >= (IA64_GR0_REGNUM + 2) &&
+ regnum <= (IA64_GR0_REGNUM + 3)) ||
+ (regnum >= (IA64_GR0_REGNUM + 8) &&
+ regnum <= (IA64_GR0_REGNUM + 15)) ||
+ (regnum >= (IA64_GR0_REGNUM + 16) &&
+ regnum <= (IA64_GR0_REGNUM + 31))))
+ return 0;
+ else if (rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+ if (gr_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *)(((void *)ptregs) +
+ gr_reg_to_ptreg_index[i].ptregoff)) = *reg;
+ break;
+ }
+ } else if (!rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(gr_reg_to_ptreg_index); i++)
+ if (gr_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *)
+ (((void *)ptregs) +
+ gr_reg_to_ptreg_index[i].ptregoff));
+ break;
+ }
} else
- if ((regnum >= (IA64_GR0_REGNUM + 2)
- && regnum <= (IA64_GR0_REGNUM + 3))
- || (regnum >= (IA64_GR0_REGNUM + 8)
- && regnum <= (IA64_GR0_REGNUM + 15))) {
- if (ptregs) {
- for (i = 0; i < (sizeof(gr_reg_to_ptreg_index) /
- sizeof(gr_reg_to_ptreg_index[0])); i++)
- if (gr_reg_to_ptreg_index[0].reg == regnum) {
- reg = *((unsigned long *)
- (((void *)ptregs) +
- gr_reg_to_ptreg_index[i].ptregoff));
+ result = !unw_access_gr(info, regnum - IA64_GR0_REGNUM,
+ reg, &nat, rw);
+ return result;
+}
+
+static int kgdb_br_reg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int i, result = 1;
+
+ if (!(regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7)))
+ return 0;
+
+ switch (regnum) {
+ case IA64_BR0_REGNUM:
+ case IA64_BR0_REGNUM + 6:
+ case IA64_BR0_REGNUM + 7:
+ if (rw) {
+ for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+ if (br_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *)
+ (((void *)ptregs) +
+ br_reg_to_ptreg_index[i].ptregoff)) =
+ *reg;
break;
}
} else
- unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg,
- &nat, 0);
- size = sizeof(reg);
- } else if (regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))
- switch (regnum) {
- case IA64_BR0_REGNUM:
- case IA64_BR0_REGNUM + 6:
- case IA64_BR0_REGNUM + 7:
- if (ptregs) {
- for (i = 0; i < (sizeof(br_reg_to_ptreg_index) /
- sizeof(br_reg_to_ptreg_index
- [0])); i++)
- if (br_reg_to_ptreg_index[i].reg ==
- regnum) {
- reg = *((unsigned long *)
- (((void *)ptregs) +
- br_reg_to_ptreg_index
- [i].ptregoff));
- break;
- }
- } else
- unw_access_br(info, regnum - IA64_BR0_REGNUM,
- &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_BR0_REGNUM + 1:
- case IA64_BR0_REGNUM + 2:
- case IA64_BR0_REGNUM + 3:
- case IA64_BR0_REGNUM + 4:
- case IA64_BR0_REGNUM + 5:
- unw_access_br(info, regnum - IA64_BR0_REGNUM, &reg, 0);
- size = sizeof(reg);
+ for (i = 0; i < ARRAY_SIZE(br_reg_to_ptreg_index); i++)
+ if (br_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *)
+ (((void *)ptregs) +
+ br_reg_to_ptreg_index[i].
+ ptregoff));
+ break;
+ }
+ break;
+ case IA64_BR0_REGNUM + 1:
+ case IA64_BR0_REGNUM + 2:
+ case IA64_BR0_REGNUM + 3:
+ case IA64_BR0_REGNUM + 4:
+ case IA64_BR0_REGNUM + 5:
+ result = !unw_access_br(info, regnum - IA64_BR0_REGNUM,
+ reg, rw);
+ break;
+ }
+
+ return result;
+}
+
+static int kgdb_fr_reg(int regnum, char *inbuffer, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg,
+ struct ia64_fpreg *freg, int rw)
+{
+ int result = 1;
+
+ if (!(regnum >= IA64_FR0_REGNUM && regnum <= (IA64_FR0_REGNUM + 127)))
+ return 0;
+
+ switch (regnum) {
+ case IA64_FR0_REGNUM + 6:
+ case IA64_FR0_REGNUM + 7:
+ case IA64_FR0_REGNUM + 8:
+ case IA64_FR0_REGNUM + 9:
+ case IA64_FR0_REGNUM + 10:
+ case IA64_FR0_REGNUM + 11:
+ case IA64_FR0_REGNUM + 12:
+ if (rw) {
+ char *ptr = inbuffer;
+
+ freg->u.bits[0] = *reg;
+ kgdb_hex2long(&ptr, &freg->u.bits[1]);
+ *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
+ *freg;
break;
- } else if (regnum >= IA64_FR0_REGNUM
- && regnum <= (IA64_FR0_REGNUM + 127))
- switch (regnum) {
- case IA64_FR0_REGNUM + 6:
- case IA64_FR0_REGNUM + 7:
- case IA64_FR0_REGNUM + 8:
- case IA64_FR0_REGNUM + 9:
- case IA64_FR0_REGNUM + 10:
- case IA64_FR0_REGNUM + 11:
- case IA64_FR0_REGNUM + 12:
- if (!ptregs)
- unw_access_fr(info, regnum - IA64_FR0_REGNUM,
- &freg, 0);
- else {
- freg =
- *(&ptregs->f6 +
- (regnum - (IA64_FR0_REGNUM + 6)));
+ } else if (!ptregs)
+ result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+ freg, rw);
+ else
+ *freg =
+ *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)));
+ break;
+ default:
+ if (!rw)
+ result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM,
+ freg, rw);
+ else
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+static int kgdb_ar_reg(int regnum, struct pt_regs * ptregs,
+ struct unw_frame_info *info, unsigned long *reg, int rw)
+{
+ int result = 0, i;
+
+ if (!(regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM))
+ return 0;
+
+ if (rw && ptregs) {
+ for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+ if (ar_reg_to_ptreg_index[i].reg == regnum) {
+ *((unsigned long *) (((void *)ptregs) +
+ ar_reg_to_ptreg_index[i].ptregoff)) =
+ *reg;
+ result = 1;
+ break;
}
- size = sizeof(freg);
- mem = (unsigned long *)&freg;
- break;
- default:
- unw_access_fr(info, regnum - IA64_FR0_REGNUM, &freg, 0);
- break;
+ } else if (ptregs) {
+ for (i = 0; i < ARRAY_SIZE(ar_reg_to_ptreg_index); i++)
+ if (ar_reg_to_ptreg_index[i].reg == regnum) {
+ *reg = *((unsigned long *) (((void *)ptregs) +
+ ar_reg_to_ptreg_index[i].ptregoff));
+ result = 1;
+ break;
+ }
+ }
+
+ if (result)
+ return result;
+
+ result = 1;
+
+ switch (regnum) {
+ case IA64_CSD_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_CSD, reg, rw);
+ break;
+ case IA64_SSD_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_SSD, reg, rw);
+ break;
+ case IA64_UNAT_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_RNAT_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_BSPSTORE_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_PFS_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RNAT, reg, rw);
+ break;
+ case IA64_LC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_LC, reg, rw);
+ break;
+ case IA64_EC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_EC, reg, rw);
+ break;
+ case IA64_FPSR_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_FPSR, reg, rw);
+ break;
+ case IA64_RSC_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_RSC, reg, rw);
+ break;
+ case IA64_CCV_REGNUM:
+ result = !unw_access_ar(info, UNW_AR_CCV, reg, rw);
+ break;
+ default:
+ result = 0;
+ }
+
+ return result;
+}
+
+void kgdb_get_reg(char *outbuffer, int regnum, struct unw_frame_info *info,
+ struct pt_regs *ptregs)
+{
+ unsigned long reg, size = 0, *mem = &reg;
+ struct ia64_fpreg freg;
+
+ if (kgdb_gr_reg(regnum, info, &reg, 0) ||
+ kgdb_gr_ptreg(regnum, ptregs, info, &reg, 0) ||
+ kgdb_br_reg(regnum, ptregs, info, &reg, 0) ||
+ kgdb_ar_reg(regnum, ptregs, info, &reg, 0))
+ size = sizeof(reg);
+ else if (kgdb_fr_reg(regnum, NULL, ptregs, info, &reg, &freg, 0)) {
+ size = sizeof(freg);
+ mem = (unsigned long *)&freg;
} else if (regnum == IA64_IP_REGNUM) {
- if (!ptregs)
+ if (!ptregs) {
unw_get_ip(info, &reg);
- else
+ size = sizeof(reg);
+ } else {
reg = ptregs->cr_iip;
- size = sizeof(reg);
+ size = sizeof(reg);
+ }
} else if (regnum == IA64_CFM_REGNUM) {
- if (!ptregs)
+ if (!ptregs) {
unw_get_cfm(info, &reg);
- else
+ size = sizeof(reg);
+ } else {
reg = ptregs->cr_ifs;
- size = sizeof(reg);
+ size = sizeof(reg);
+ }
} else if (regnum == IA64_PSR_REGNUM) {
if (!ptregs && kgdb_usethread)
ptregs = (struct pt_regs *)
- ((unsigned long)kgdb_usethread + IA64_STK_OFFSET) -
- 1;
+ ((unsigned long)kgdb_usethread +
+ IA64_STK_OFFSET) - 1;
if (ptregs)
reg = ptregs->cr_ipsr;
size = sizeof(reg);
@@ -219,151 +395,33 @@ void kgdb_get_reg(char *outbuffer, int r
} else if (regnum == IA64_BSP_REGNUM) {
unw_get_bsp(info, &reg);
size = sizeof(reg);
- } else if (regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)
- switch (regnum) {
- case IA64_CSD_REGNUM:
- if (ptregs)
- reg = ptregs->ar_csd;
- else
- unw_access_ar(info, UNW_AR_CSD, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_SSD_REGNUM:
- if (ptregs)
- reg = ptregs->ar_ssd;
- else
- unw_access_ar(info, UNW_AR_SSD, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_UNAT_REGNUM:
- if (ptregs)
- reg = ptregs->ar_unat;
- else
- unw_access_ar(info, UNW_AR_UNAT, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_RNAT_REGNUM:
- unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_BSPSTORE_REGNUM:
- unw_access_ar(info, UNW_AR_BSPSTORE, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_PFS_REGNUM:
- unw_access_ar(info, UNW_AR_PFS, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_LC_REGNUM:
- unw_access_ar(info, UNW_AR_LC, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_EC_REGNUM:
- unw_access_ar(info, UNW_AR_EC, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_FPSR_REGNUM:
- if (ptregs)
- reg = ptregs->ar_fpsr;
- else
- unw_access_ar(info, UNW_AR_FPSR, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_RSC_REGNUM:
- if (ptregs)
- reg = ptregs->ar_rsc;
- else
- unw_access_ar(info, UNW_AR_RNAT, &reg, 0);
- size = sizeof(reg);
- break;
- case IA64_CCV_REGNUM:
- unw_access_ar(info, UNW_AR_CCV, &reg, 0);
- size = sizeof(reg);
- break;
- }
+ }

if (size) {
- kgdb_mem2hex((char *)mem, outbuffer, size);
- outbuffer[size * 2] = 0;
- } else
+ kgdb_mem2hex((char *) mem, outbuffer, size);
+ outbuffer[size*2] = 0;
+ }
+ else
strcpy(outbuffer, "E0");
-
return;
}

void kgdb_put_reg(char *inbuffer, char *outbuffer, int regnum,
- struct unw_frame_info *info, struct pt_regs *ptregs)
+ struct unw_frame_info *info, struct pt_regs *ptregs)
{
unsigned long reg;
- char nat = 0;
struct ia64_fpreg freg;
- int i;
- char *ptr;
+ char *ptr = inbuffer;

- ptr = inbuffer;
kgdb_hex2long(&ptr, &reg);
strcpy(outbuffer, "OK");

- if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||
- (regnum >= (IA64_GR0_REGNUM + 4) && regnum <= (IA64_GR0_REGNUM + 7))
- || (regnum >= (IA64_GR0_REGNUM + 16)
- && regnum <= (IA64_GR0_REGNUM + 31))) {
- unw_access_gr(info, regnum - IA64_GR0_REGNUM, &reg, &nat, 1);
- } else
- if ((regnum >= (IA64_GR0_REGNUM + 2)
- && regnum <= (IA64_GR0_REGNUM + 3))
- || (regnum >= (IA64_GR0_REGNUM + 8)
- && regnum <= (IA64_GR0_REGNUM + 15))) {
- for (i = 0;
- i <
- (sizeof(gr_reg_to_ptreg_index) /
- sizeof(gr_reg_to_ptreg_index[0])); i++)
- if (gr_reg_to_ptreg_index[0].reg == regnum) {
- *((unsigned long *)
- (((void *)ptregs) +
- gr_reg_to_ptreg_index[i].ptregoff)) = reg;
- break;
- }
- } else if (regnum >= IA64_BR0_REGNUM && regnum <= (IA64_BR0_REGNUM + 7))
- switch (regnum) {
- case IA64_BR0_REGNUM:
- case IA64_BR0_REGNUM + 6:
- case IA64_BR0_REGNUM + 7:
- for (i = 0; i < (sizeof(br_reg_to_ptreg_index) /
- sizeof(br_reg_to_ptreg_index[0])); i++)
- if (br_reg_to_ptreg_index[i].reg == regnum) {
- *((unsigned long *)
- (((void *)ptregs) +
- br_reg_to_ptreg_index[i].ptregoff)) =
- reg;
- break;
- }
- break;
- case IA64_BR0_REGNUM + 1:
- case IA64_BR0_REGNUM + 2:
- case IA64_BR0_REGNUM + 3:
- case IA64_BR0_REGNUM + 4:
- case IA64_BR0_REGNUM + 5:
- unw_access_br(info, regnum - IA64_BR0_REGNUM, &reg, 1);
- break;
- } else if (regnum >= IA64_FR0_REGNUM
- && regnum <= (IA64_FR0_REGNUM + 127))
- switch (regnum) {
- case IA64_FR0_REGNUM + 6:
- case IA64_FR0_REGNUM + 7:
- case IA64_FR0_REGNUM + 8:
- case IA64_FR0_REGNUM + 9:
- case IA64_FR0_REGNUM + 10:
- case IA64_FR0_REGNUM + 11:
- case IA64_FR0_REGNUM + 12:
- freg.u.bits[0] = reg;
- kgdb_hex2long(&ptr, &freg.u.bits[1]);
- *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) =
- freg;
- break;
- default:
- break;
- } else if (regnum == IA64_IP_REGNUM)
+ if (kgdb_gr_reg(regnum, info, &reg, 1) ||
+ kgdb_gr_ptreg(regnum, ptregs, info, &reg, 1) ||
+ kgdb_br_reg(regnum, ptregs, info, &reg, 1) ||
+ kgdb_fr_reg(regnum, inbuffer, ptregs, info, &reg, &freg, 1) ||
+ kgdb_ar_reg(regnum, ptregs, info, &reg, 1)) ;
+ else if (regnum == IA64_IP_REGNUM)
ptregs->cr_iip = reg;
else if (regnum == IA64_CFM_REGNUM)
ptregs->cr_ifs = reg;
@@ -371,40 +429,7 @@ void kgdb_put_reg(char *inbuffer, char *
ptregs->cr_ipsr = reg;
else if (regnum == IA64_PR_REGNUM)
ptregs->pr = reg;
- else if (regnum >= IA64_AR0_REGNUM && regnum <= IA64_EC_REGNUM)
- switch (regnum) {
- case IA64_CSD_REGNUM:
- ptregs->ar_csd = reg;
- break;
- case IA64_SSD_REGNUM:
- ptregs->ar_ssd = reg;
- case IA64_UNAT_REGNUM:
- ptregs->ar_unat = reg;
- case IA64_RNAT_REGNUM:
- unw_access_ar(info, UNW_AR_RNAT, &reg, 1);
- break;
- case IA64_BSPSTORE_REGNUM:
- unw_access_ar(info, UNW_AR_BSPSTORE, &reg, 1);
- break;
- case IA64_PFS_REGNUM:
- unw_access_ar(info, UNW_AR_PFS, &reg, 1);
- break;
- case IA64_LC_REGNUM:
- unw_access_ar(info, UNW_AR_LC, &reg, 1);
- break;
- case IA64_EC_REGNUM:
- unw_access_ar(info, UNW_AR_EC, &reg, 1);
- break;
- case IA64_FPSR_REGNUM:
- ptregs->ar_fpsr = reg;
- break;
- case IA64_RSC_REGNUM:
- ptregs->ar_rsc = reg;
- break;
- case IA64_CCV_REGNUM:
- unw_access_ar(info, UNW_AR_CCV, &reg, 1);
- break;
- } else
+ else
strcpy(outbuffer, "E01");

return;
@@ -765,7 +790,6 @@ static void inline kgdb_wait(struct pt_r
if (hw_breakpoint_status & IA64_PSR_DB)
ia64_setreg(_IA64_REG_PSR_L, hw_breakpoint_status);

- touch_softlockup_watchdog();
return;
}

@@ -955,6 +979,35 @@ int kgdb_arch_handle_exception(int e_vec
return info.ret;
}

+/*
+ * This is done because I evidently made an incorrect 'p' encoding
+ * when my patch for gdb was committed. It was later corrected. This
+ * check supports both my wrong encoding of the register number and
+ * the correct encoding. Eventually this should be eliminated and
+ * kgdb_hex2long should be demarshalling the regnum.
+ */
+static inline int check_packet(unsigned int regnum, char *packet)
+{
+ static int check_done, swap;
+ unsigned long reglong;
+
+ if (likely(check_done)) {
+ if (swap) {
+ kgdb_hex2long(&packet, &reglong);
+ regnum = (int) reglong;
+ }
+
+ } else {
+ if (regnum > NUM_REGS) {
+ kgdb_hex2long(&packet, &reglong);
+ regnum = (int) reglong;
+ swap = 1;
+ }
+ check_done = 1;
+ }
+ return regnum;
+}
+
static void do_kgdb_handle_exception(struct unw_frame_info *unw_info,
void *data)
{
@@ -982,10 +1035,11 @@ static void do_kgdb_handle_exception(str
switch (remcom_in_buffer[0]) {
case 'p':
{
- int regnum;
+ unsigned int regnum;

kgdb_hex2mem(&remcom_in_buffer[1], (char *)&regnum,
sizeof(regnum));
+ regnum = check_packet(regnum, &remcom_in_buffer[1]);
if (regnum >= NUM_REGS) {
remcom_out_buffer[0] = 'E';
remcom_out_buffer[1] = 0;
@@ -996,7 +1050,7 @@ static void do_kgdb_handle_exception(str
}
case 'P':
{
- int regno;
+ unsigned int regno;
long v;
char *ptr;

@@ -1004,7 +1058,7 @@ static void do_kgdb_handle_exception(str
if ((!kgdb_usethread || kgdb_usethread == current) &&
kgdb_hex2long(&ptr, &v) &&
*ptr++ == '=' && (v >= 0)) {
- regno = (int)v;
+ regno = (unsigned int)v;
regno = (regno >= NUM_REGS ? 0 : regno);
kgdb_put_reg(ptr, remcom_out_buffer, regno,
unw_info, linux_regs);
@@ -1053,8 +1107,6 @@ static void do_kgdb_handle_exception(str
linux_regs->cr_ipsr &= ~IA64_PSR_DB;
}

- if (atomic_read(&init_mm.mm_count) > 1)
- touch_softlockup_watchdog();
info->ret = 0;
break;
default:


-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise