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) { #ifndef XEN char *ptr = inbuffer; freg->u.bits[0] = *reg; kgdb_hex2long(&ptr, &freg->u.bits[1]); *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))) = *freg; #else printk("%s: %d: writing to fpreg is not supported.\n", __func__, __LINE__); #endif break; } else if (!ptregs) result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM, freg, rw); else #ifndef XEN *freg = *(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6))); #else //XXX struct ia64_fpreg and struct pt_fpreg are same. *freg = *((struct ia64_fpreg*)(&ptregs->f6 + (regnum - (IA64_FR0_REGNUM + 6)))); #endif break; default: if (!rw) result = !unw_access_fr(info, regnum - IA64_FR0_REGNUM, freg, rw); else result = 0; break; } 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 = ® 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, ®, &nat, 0); size = sizeof(reg); } 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)); break; } } else unw_access_gr(info, regnum - IA64_GR0_REGNUM, ®, &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, ®, 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, ®, 0); size = sizeof(reg); 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))); } size = sizeof(freg); mem = (unsigned long *)&freg; break; default: unw_access_fr(info, regnum - IA64_FR0_REGNUM, &freg, 0); break; } else if (regnum == IA64_IP_REGNUM) { if (!ptregs) unw_get_ip(info, ®); else reg = ptregs->cr_iip; size = sizeof(reg); } else if (regnum == IA64_CFM_REGNUM) { if (!ptregs) unw_get_cfm(info, ®); else reg = ptregs->cr_ifs; 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; if (ptregs) reg = ptregs->cr_ipsr; size = sizeof(reg); } else if (regnum == IA64_PR_REGNUM) { if (ptregs) reg = ptregs->pr; else unw_access_pr(info, ®, 0); size = sizeof(reg); } else if (regnum == IA64_BSP_REGNUM) { unw_get_bsp(info, ®); 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, ®, 0); size = sizeof(reg); break; case IA64_SSD_REGNUM: if (ptregs) reg = ptregs->ar_ssd; else unw_access_ar(info, UNW_AR_SSD, ®, 0); size = sizeof(reg); break; case IA64_UNAT_REGNUM: if (ptregs) reg = ptregs->ar_unat; else unw_access_ar(info, UNW_AR_UNAT, ®, 0); size = sizeof(reg); break; case IA64_RNAT_REGNUM: unw_access_ar(info, UNW_AR_RNAT, ®, 0); size = sizeof(reg); break; case IA64_BSPSTORE_REGNUM: unw_access_ar(info, UNW_AR_BSPSTORE, ®, 0); size = sizeof(reg); break; case IA64_PFS_REGNUM: unw_access_ar(info, UNW_AR_PFS, ®, 0); size = sizeof(reg); break; case IA64_LC_REGNUM: unw_access_ar(info, UNW_AR_LC, ®, 0); size = sizeof(reg); break; case IA64_EC_REGNUM: unw_access_ar(info, UNW_AR_EC, ®, 0); size = sizeof(reg); break; case IA64_FPSR_REGNUM: if (ptregs) reg = ptregs->ar_fpsr; else unw_access_ar(info, UNW_AR_FPSR, ®, 0); size = sizeof(reg); break; case IA64_RSC_REGNUM: if (ptregs) reg = ptregs->ar_rsc; else unw_access_ar(info, UNW_AR_RNAT, ®, 0); size = sizeof(reg); break; case IA64_CCV_REGNUM: unw_access_ar(info, UNW_AR_CCV, ®, 0); size = sizeof(reg); break; } if (size) { kgdb_mem2hex((char *)mem, outbuffer, size); outbuffer[size * 2] = 0; } else strcpy(outbuffer, "E0"); return; }