📄 ia64-lite.patch
字号:
+ if ((regnum >= IA64_GR0_REGNUM && regnum <= (IA64_GR0_REGNUM + 1)) ||+ (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+ 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+ 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 (!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;+ }+ } 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 = ®+ struct ia64_fpreg freg;++ if (kgdb_gr_reg(regnum, info, ®, 0) ||+ kgdb_gr_ptreg(regnum, ptregs, info, ®, 0) ||+ kgdb_br_reg(regnum, ptregs, info, ®, 0) ||+ kgdb_ar_reg(regnum, ptregs, info, ®, 0))+ size = sizeof(reg);+ else if (kgdb_fr_reg(regnum, NULL, ptregs, info, ®, &freg, 0)) {+ size = sizeof(freg);+ mem = (unsigned long *)&freg;+ } else if (regnum == IA64_IP_REGNUM) {+ if (!ptregs) {+ unw_get_ip(info, ®);+ size = sizeof(reg);+ } 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);+ }++ 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;+ struct ia64_fpreg freg;+ char *ptr = inbuffer;++ kgdb_hex2long(&ptr, ®);+ strcpy(outbuffer, "OK");++ if (kgdb_gr_reg(regnum, info, ®, 1) ||+ kgdb_gr_ptreg(regnum, ptregs, info, ®, 1) ||+ kgdb_br_reg(regnum, ptregs, info, ®, 1) ||+ kgdb_fr_reg(regnum, inbuffer, ptregs, info, ®, &freg, 1) ||+ kgdb_ar_reg(regnum, ptregs, info, ®, 1)) ;+ 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+ strcpy(outbuffer, "E01");+ return;+}++void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)+{+}++void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)+{+}++void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)+{++}++#define MAX_HW_BREAKPOINT (20)+long hw_break_total_dbr, hw_break_total_ibr;+#define HW_BREAKPOINT (hw_break_total_dbr + hw_break_total_ibr)+#define WATCH_INSTRUCTION 0x0+#define WATCH_WRITE 0x1+#define WATCH_READ 0x2+#define WATCH_ACCESS 0x3++#define HWCAP_DBR ((1 << WATCH_WRITE) | (1 << WATCH_READ))+#define HWCAP_IBR (1 << WATCH_INSTRUCTION)+struct hw_breakpoint {+ unsigned enabled;+ unsigned long capable;+ unsigned long type;+ unsigned long mask;+ unsigned long addr;+} *breakinfo;++static struct hw_breakpoint hwbreaks[MAX_HW_BREAKPOINT];++enum instruction_type { A, I, M, F, B, L, X, u };++static enum instruction_type bundle_encoding[32][3] = {+ {M, I, I}, /* 00 */+ {M, I, I}, /* 01 */+ {M, I, I}, /* 02 */+ {M, I, I}, /* 03 */+ {M, L, X}, /* 04 */+ {M, L, X}, /* 05 */+ {u, u, u}, /* 06 */+ {u, u, u}, /* 07 */+ {M, M, I}, /* 08 */+ {M, M, I}, /* 09 */+ {M, M, I}, /* 0A */+ {M, M, I}, /* 0B */+ {M, F, I}, /* 0C */+ {M, F, I}, /* 0D */+ {M, M, F}, /* 0E */+ {M, M, F}, /* 0F */+ {M, I, B}, /* 10 */+ {M, I, B}, /* 11 */+ {M, B, B}, /* 12 */+ {M, B, B}, /* 13 */+ {u, u, u}, /* 14 */+ {u, u, u}, /* 15 */+ {B, B, B}, /* 16 */+ {B, B, B}, /* 17 */+ {M, M, B}, /* 18 */+ {M, M, B}, /* 19 */+ {u, u, u}, /* 1A */+ {u, u, u}, /* 1B */+ {M, F, B}, /* 1C */+ {M, F, B}, /* 1D */+ {u, u, u}, /* 1E */+ {u, u, u}, /* 1F */+};++int kgdb_validate_break_address(unsigned long addr)+{+ int error;+ char tmp_variable[BREAK_INSTR_SIZE];+ error = kgdb_get_mem((char *)(addr & BREAK_INSTR_ALIGN), tmp_variable,+ BREAK_INSTR_SIZE);+ return error;+}++int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)+{+ extern unsigned long _start[];+ unsigned long slot = addr & BREAK_INSTR_ALIGN, bundle_addr;+ unsigned long template;+ struct bundle {+ struct {+ unsigned long long template:5;+ unsigned long long slot0:41;+ unsigned long long slot1_p0:64 - 46;+ } quad0;+ struct {+ unsigned long long slot1_p1:41 - (64 - 46);+ unsigned long long slot2:41;+ } quad1;+ } bundle;+ int ret;++ bundle_addr = addr & ~0xFULL;++ if (bundle_addr == (unsigned long)_start)+ return 0;++ ret = kgdb_get_mem((char *)bundle_addr, (char *)&bundle,+ BREAK_INSTR_SIZE);+ if (ret < 0)+ return ret;++ if (slot > 2)+ slot = 0;++ memcpy(saved_instr, &bundle, BREAK_INSTR_SIZE);+ template = bundle.quad0.template;++ if (slot == 1 && bundle_encoding[template][1] == L)+ slot = 2;++ switch (slot) {+ case 0:+ bundle.quad0.slot0 = BREAKNUM;+ break;+ case 1:+ bundle.quad0.slot1_p0 = BREAKNUM;+ bundle.quad1.slot1_p1 = (BREAKNUM >> (64 - 46));+ break;+ case 2:+ bundle.quad1.slot2 = BREAKNUM;+ break;+ }++ return kgdb_set_mem((char *)bundle_addr, (char *)&bundle,+ BREAK_INSTR_SIZE);+}++int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)+{+ extern unsigned long _start[];+ + addr = addr & BREAK_INSTR_ALIGN;+ if (addr == (unsigned long)_start)+ return 0;+ return kgdb_set_mem((char *)addr, (char *)bundle, BREAK_INSTR_SIZE);+}++static int hw_breakpoint_init;++void do_init_hw_break(void)+{+ s64 status;+ int i;++ hw_breakpoint_init = 1;++#ifdef CONFIG_IA64_HP_SIM+ hw_break_total_ibr = 8;+ hw_break_total_dbr = 8;+ status = 0;+#else+ status = ia64_pal_debug_info(&hw_break_total_ibr, &hw_break_total_dbr);+#endif++ if (status) {+ printk(KERN_INFO "do_init_hw_break: pal call failed %d\n",+ (int)status);+ return;+ }++ if (HW_BREAKPOINT > MAX_HW_BREAKPOINT) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -