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; }
void kgdb_put_reg(char *inbuffer, char *outbuffer, int regnum, struct unw_frame_info *info, struct pt_regs *ptregs) { unsigned long reg; char nat = 0; struct ia64_fpreg freg; int i; char *ptr; ptr = inbuffer; kgdb_hex2long(&ptr, ®); 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, ®, &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, ®, 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) ptregs->cr_iip = reg; else if (regnum == IA64_CFM_REGNUM) ptregs->cr_ifs = reg; else if (regnum == IA64_PSR_REGNUM) 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, ®, 1); break; case IA64_BSPSTORE_REGNUM: unw_access_ar(info, UNW_AR_BSPSTORE, ®, 1); break; case IA64_PFS_REGNUM: unw_access_ar(info, UNW_AR_PFS, ®, 1); break; case IA64_LC_REGNUM: unw_access_ar(info, UNW_AR_LC, ®, 1); break; case IA64_EC_REGNUM: unw_access_ar(info, UNW_AR_EC, ®, 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, ®, 1); break; } else strcpy(outbuffer, "E01"); return; }
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; } } 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; }