diff options
| -rw-r--r-- | arch/mips/kernel/kgdb.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c index 1f4bd222ba76..eb6c0d582626 100644 --- a/arch/mips/kernel/kgdb.c +++ b/arch/mips/kernel/kgdb.c | |||
| @@ -244,9 +244,6 @@ static int compute_signal(int tt) | |||
| 244 | void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | 244 | void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) |
| 245 | { | 245 | { |
| 246 | int reg; | 246 | int reg; |
| 247 | struct thread_info *ti = task_thread_info(p); | ||
| 248 | unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32; | ||
| 249 | struct pt_regs *regs = (struct pt_regs *)ksp - 1; | ||
| 250 | #if (KGDB_GDB_REG_SIZE == 32) | 247 | #if (KGDB_GDB_REG_SIZE == 32) |
| 251 | u32 *ptr = (u32 *)gdb_regs; | 248 | u32 *ptr = (u32 *)gdb_regs; |
| 252 | #else | 249 | #else |
| @@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) | |||
| 254 | #endif | 251 | #endif |
| 255 | 252 | ||
| 256 | for (reg = 0; reg < 16; reg++) | 253 | for (reg = 0; reg < 16; reg++) |
| 257 | *(ptr++) = regs->regs[reg]; | 254 | *(ptr++) = 0; |
| 258 | 255 | ||
| 259 | /* S0 - S7 */ | 256 | /* S0 - S7 */ |
| 260 | for (reg = 16; reg < 24; reg++) | 257 | *(ptr++) = p->thread.reg16; |
| 261 | *(ptr++) = regs->regs[reg]; | 258 | *(ptr++) = p->thread.reg17; |
| 259 | *(ptr++) = p->thread.reg18; | ||
| 260 | *(ptr++) = p->thread.reg19; | ||
| 261 | *(ptr++) = p->thread.reg20; | ||
| 262 | *(ptr++) = p->thread.reg21; | ||
| 263 | *(ptr++) = p->thread.reg22; | ||
| 264 | *(ptr++) = p->thread.reg23; | ||
| 262 | 265 | ||
| 263 | for (reg = 24; reg < 28; reg++) | 266 | for (reg = 24; reg < 28; reg++) |
| 264 | *(ptr++) = 0; | 267 | *(ptr++) = 0; |
| 265 | 268 | ||
| 266 | /* GP, SP, FP, RA */ | 269 | /* GP, SP, FP, RA */ |
| 267 | for (reg = 28; reg < 32; reg++) | 270 | *(ptr++) = (long)p; |
| 268 | *(ptr++) = regs->regs[reg]; | 271 | *(ptr++) = p->thread.reg29; |
| 269 | 272 | *(ptr++) = p->thread.reg30; | |
| 270 | *(ptr++) = regs->cp0_status; | 273 | *(ptr++) = p->thread.reg31; |
| 271 | *(ptr++) = regs->lo; | 274 | |
| 272 | *(ptr++) = regs->hi; | 275 | *(ptr++) = p->thread.cp0_status; |
| 273 | *(ptr++) = regs->cp0_badvaddr; | 276 | |
| 274 | *(ptr++) = regs->cp0_cause; | 277 | /* lo, hi */ |
| 275 | *(ptr++) = regs->cp0_epc; | 278 | *(ptr++) = 0; |
| 279 | *(ptr++) = 0; | ||
| 280 | |||
| 281 | /* | ||
| 282 | * BadVAddr, Cause | ||
| 283 | * Ideally these would come from the last exception frame up the stack | ||
| 284 | * but that requires unwinding, otherwise we can't know much for sure. | ||
| 285 | */ | ||
| 286 | *(ptr++) = 0; | ||
| 287 | *(ptr++) = 0; | ||
| 288 | |||
| 289 | /* | ||
| 290 | * PC | ||
| 291 | * use return address (RA), i.e. the moment after return from resume() | ||
| 292 | */ | ||
| 293 | *(ptr++) = p->thread.reg31; | ||
| 276 | } | 294 | } |
| 277 | 295 | ||
| 278 | void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) | 296 | void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) |
