Changeset 07bd114e in mainline for arch/mips32/src/debugger.c
- Timestamp:
- 2005-12-17T00:08:13Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2cf87e50
- Parents:
- c43fa55
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
arch/mips32/src/debugger.c
rc43fa55 r07bd114e 73 73 }; 74 74 75 static cmd_arg_t adde_argv[] = { 76 { .type = ARG_TYPE_INT }, 77 { .type = ARG_TYPE_INT } 78 }; 79 static cmd_info_t addbkpte_info = { 80 .name = "addbkpte", 81 .description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).", 82 .func = cmd_add_breakpoint, 83 .argc = 2, 84 .argv = adde_argv 85 }; 86 87 static struct { 88 __u32 andmask; 89 __u32 value; 90 }jmpinstr[] = { 91 {0xf3ff0000, 0x41000000}, /* BCzF */ 92 {0xf3ff0000, 0x41020000}, /* BCzFL */ 93 {0xf3ff0000, 0x41010000}, /* BCzT */ 94 {0xf3ff0000, 0x41030000}, /* BCzTL */ 95 {0xfc000000, 0x10000000}, /* BEQ */ 96 {0xfc000000, 0x50000000}, /* BEQL */ 97 {0xfc1f0000, 0x04010000}, /* BEQL */ 98 {0xfc1f0000, 0x04110000}, /* BGEZAL */ 99 {0xfc1f0000, 0x04130000}, /* BGEZALL */ 100 {0xfc1f0000, 0x04030000}, /* BGEZL */ 101 {0xfc1f0000, 0x1c000000}, /* BGTZ */ 102 {0xfc1f0000, 0x5c000000}, /* BGTZL */ 103 {0xfc1f0000, 0x18000000}, /* BLEZ */ 104 {0xfc1f0000, 0x58000000}, /* BLEZL */ 105 {0xfc1f0000, 0x04000000}, /* BLTZ */ 106 {0xfc1f0000, 0x04100000}, /* BLTZAL */ 107 {0xfc1f0000, 0x04120000}, /* BLTZALL */ 108 {0xfc1f0000, 0x04020000}, /* BLTZL */ 109 {0xfc000000, 0x14000000}, /* BNE */ 110 {0xfc000000, 0x54000000}, /* BNEL */ 111 {0xfc000000, 0x08000000}, /* J */ 112 {0xfc000000, 0x0c000000}, /* JAL */ 113 {0xfc1f07ff, 0x00000009}, /* JALR */ 114 {0,0} /* EndOfTable */ 115 }; 116 117 /** Test, if the given instruction is a jump or branch instruction 118 * 119 * @param instr Instruction code 120 * @return true - it is jump instruction, false otherwise 121 */ 122 static bool is_jump(__native instr) 123 { 124 int i; 125 126 for (i=0;jmpinstr[i].andmask;i++) { 127 if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value) 128 return true; 129 } 130 131 return false; 132 } 133 75 134 /** Add new breakpoint to table */ 76 135 int cmd_add_breakpoint(cmd_arg_t *argv) … … 117 176 cur->instruction = ((__native *)cur->address)[0]; 118 177 cur->nextinstruction = ((__native *)cur->address)[1]; 119 cur->executing = false; 178 if (argv == &add_argv) { 179 cur->flags = 0; 180 } else { /* We are add extended */ 181 cur->flags = BKPOINT_FUNCCALL; 182 cur->bkfunc = (void (*)(void *, struct exception_regdump *)) argv[1].intval; 183 } 184 if (is_jump(cur->instruction)) 185 cur->flags |= BKPOINT_ONESHOT; 186 cur->counter = 0; 120 187 121 188 /* Set breakpoint */ … … 127 194 return 1; 128 195 } 196 197 129 198 130 199 /** Remove breakpoint from table */ … … 148 217 return 0; 149 218 } 150 219 if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) { 220 printf("Cannot remove one-shot breakpoint in-progress\n"); 221 spinlock_unlock(&bkpoint_lock); 222 interrupts_restore(ipl); 223 return 0; 224 } 151 225 ((__u32 *)cur->address)[0] = cur->instruction; 152 226 ((__u32 *)cur->address)[1] = cur->nextinstruction; … … 171 245 printf("%d. 0x%p in %s\n",i, 172 246 breakpoints[i].address, symbol); 247 printf(" Count(%d) ", breakpoints[i].counter); 248 if (breakpoints[i].flags & BKPOINT_INPROG) 249 printf("INPROG "); 250 if (breakpoints[i].flags & BKPOINT_ONESHOT) 251 printf("ONESHOT "); 252 if (breakpoints[i].flags & BKPOINT_FUNCCALL) 253 printf("FUNCCALL "); 254 printf("\n"); 173 255 } 174 256 return 1; … … 194 276 if (!cmd_register(&addbkpt_info)) 195 277 panic("could not register command %s\n", addbkpt_info.name); 278 279 cmd_initialize(&addbkpte_info); 280 if (!cmd_register(&addbkpte_info)) 281 panic("could not register command %s\n", addbkpte_info.name); 196 282 } 197 283 … … 206 292 void debugger_bpoint(struct exception_regdump *pstate) 207 293 { 208 char *symbol;209 294 bpinfo_t *cur = NULL; 210 int i; 211 212 symbol = get_symtab_entry(pstate->epc); 213 295 __address fireaddr = pstate->epc; 296 int i; 214 297 215 298 /* test branch delay slot */ … … 219 302 spinlock_lock(&bkpoint_lock); 220 303 for (i=0; i<BKPOINTS_MAX; i++) { 221 if (pstate->epc == breakpoints[i].address || \222 (pstate->epc == breakpoints[i].address+sizeof(__native) &&\223 breakpoints[i].executing))304 /* Normal breakpoint */ 305 if (fireaddr == breakpoints[i].address \ 306 && !(breakpoints[i].flags & BKPOINT_REINST)) { 224 307 cur = &breakpoints[i]; 225 break; 226 308 break; 309 } 310 /* Reinst only breakpoint */ 311 if ((breakpoints[i].flags & BKPOINT_REINST) \ 312 && (fireaddr ==breakpoints[i].address+sizeof(__native))) { 313 cur = &breakpoints[i]; 314 break; 315 } 227 316 } 228 317 if (cur) { 229 if ((cur->executing && pstate->epc==cur->address) || 230 (!cur->executing && pstate->epc==cur->address+sizeof(__native))) 231 panic("Weird breakpoint state.\n"); 232 if (!cur->executing) { 233 printf("***Breakpoint %d: 0x%p in %s.\n", i, 234 pstate->epc,symbol); 235 /* Return first instruction back */ 236 ((__u32 *)cur->address)[0] = cur->instruction; 237 /* Set Breakpoint on second */ 238 ((__u32 *)cur->address)[1] = 0x0d; 239 cur->executing = true; 240 } else { 318 if (cur->flags & BKPOINT_REINST) { 241 319 /* Set breakpoint on first instruction */ 242 320 ((__u32 *)cur->address)[0] = 0x0d; 243 321 /* Return back the second */ 244 322 ((__u32 *)cur->address)[1] = cur->nextinstruction; 245 cur-> executing = false;323 cur->flags &= ~BKPOINT_REINST; 246 324 spinlock_unlock(&bkpoint_lock); 247 325 return; 248 } 326 } 327 if (cur->flags & BKPOINT_INPROG) 328 printf("Warning: breakpoint recursion\n"); 329 330 if (!(cur->flags & BKPOINT_FUNCCALL)) 331 printf("***Breakpoint %d: 0x%p in %s.\n", i, 332 fireaddr, get_symtab_entry(pstate->epc)); 333 334 /* Return first instruction back */ 335 ((__u32 *)cur->address)[0] = cur->instruction; 336 337 if (! (cur->flags & BKPOINT_ONESHOT)) { 338 /* Set Breakpoint on next instruction */ 339 ((__u32 *)cur->address)[1] = 0x0d; 340 cur->flags |= BKPOINT_REINST; 341 } 342 cur->flags |= BKPOINT_INPROG; 249 343 } else { 250 printf("***Breakpoint 0x%p in %s.\n", pstate->epc, symbol); 344 printf("***Breakpoint 0x%p in %s.\n", fireaddr, 345 get_symtab_entry(fireaddr)); 251 346 /* Move on to next instruction */ 252 347 pstate->epc += 4; 253 348 } 349 350 cur->counter++; 351 if (cur && (cur->flags & BKPOINT_FUNCCALL)) { 352 /* Allow zero bkfunc, just for counting */ 353 if (cur->bkfunc) 354 cur->bkfunc(cur, pstate); 355 } else { 356 printf("***Type 'exit' to exit kconsole.\n"); 357 /* This disables all other processors - we are not SMP, 358 * actually this gets us to cpu_halt, if scheduler() is run 359 * - we generally do not want scheduler to be run from debug, 360 * so this is a good idea 361 */ 362 atomic_set(&haltstate,1); 363 spinlock_unlock(&bkpoint_lock); 364 365 kconsole("debug"); 366 367 spinlock_lock(&bkpoint_lock); 368 atomic_set(&haltstate,0); 369 } 370 371 if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { 372 /* Remove one-shot breakpoint */ 373 if ((cur->flags & BKPOINT_ONESHOT)) 374 cur->address = NULL; 375 /* Remove in-progress flag */ 376 cur->flags &= ~BKPOINT_INPROG; 377 } 254 378 spinlock_unlock(&bkpoint_lock); 255 256 257 printf("***Type 'exit' to exit kconsole.\n"); 258 /* Umm..we should rather set some 'debugstate' here */ 259 atomic_set(&haltstate,1); 260 kconsole("debug"); 261 atomic_set(&haltstate,0); 262 } 379 }
Note:
See TracChangeset
for help on using the changeset viewer.