boolean_t kdb_trap( int type, int code, struct i386_saved_state *regs) { spl_t s; s = splhigh(); saved_ipl[cpu_number()] = s; switch (type) { case T_DEBUG: /* single_step */ { int addr; int status = get_dr6(); if (status & 0xf) { /* hmm hdw break */ addr = status & 0x8 ? get_dr3() : status & 0x4 ? get_dr2() : status & 0x2 ? get_dr1() : get_dr0(); regs->efl |= EFL_RF; db_single_step_cmd(addr, 0, 1, "p"); } } case T_INT3: /* breakpoint */ case T_WATCHPOINT: /* watchpoint */ case -1: /* keyboard interrupt */ break; default: if (db_recover) { i386_nested_saved_state = *regs; db_printf("Caught %s (%d), code = %x, pc = %x\n", trap_name(type), type, code, regs->eip); db_error(""); /*NOTREACHED*/ } kdbprinttrap(type, code); } #if NCPUS > 1 if (db_enter()) #endif /* NCPUS > 1 */ { i386_last_saved_statep = regs; i386_last_kdb_sp = (unsigned) &type; /* XXX Should switch to ddb`s own stack here. */ ddb_regs = *regs; if ((regs->cs & 0x3) == KERNEL_RING) { /* * Kernel mode - esp and ss not saved */ ddb_regs.uesp = (int)®s->uesp; /* kernel stack pointer */ ddb_regs.ss = KERNEL_DS; } cnpollc(TRUE); db_task_trap(type, code, (regs->cs & 0x3) != 0); cnpollc(FALSE); regs->eip = ddb_regs.eip; regs->efl = ddb_regs.efl; regs->eax = ddb_regs.eax; regs->ecx = ddb_regs.ecx; regs->edx = ddb_regs.edx; regs->ebx = ddb_regs.ebx; if ((regs->cs & 0x3) != KERNEL_RING) { /* * user mode - saved esp and ss valid */ regs->uesp = ddb_regs.uesp; /* user stack pointer */ regs->ss = ddb_regs.ss & 0xffff; /* user stack segment */ } regs->ebp = ddb_regs.ebp; regs->esi = ddb_regs.esi; regs->edi = ddb_regs.edi; regs->es = ddb_regs.es & 0xffff; regs->cs = ddb_regs.cs & 0xffff; regs->ds = ddb_regs.ds & 0xffff; regs->fs = ddb_regs.fs & 0xffff; regs->gs = ddb_regs.gs & 0xffff; if ((type == T_INT3) && (db_get_task_value(regs->eip, BKPT_SIZE, FALSE, TASK_NULL) == BKPT_INST)) regs->eip += BKPT_SIZE; } #if NCPUS > 1 db_leave(); #endif /* NCPUS > 1 */ splx(s); return 1; }
void kdb_kentry( struct int_regs *int_regs) { struct i386_interrupt_state *is = int_regs->is; spl_t s = splhigh(); #if NCPUS > 1 if (db_enter()) #endif /* NCPUS > 1 */ { if ((is->cs & 0x3) != KERNEL_RING) { ddb_regs.uesp = ((int *)(is+1))[0]; ddb_regs.ss = ((int *)(is+1))[1]; } else { ddb_regs.ss = KERNEL_DS; ddb_regs.uesp= (int)(is+1); } ddb_regs.efl = is->efl; ddb_regs.cs = is->cs; ddb_regs.eip = is->eip; ddb_regs.eax = is->eax; ddb_regs.ecx = is->ecx; ddb_regs.edx = is->edx; ddb_regs.ebx = int_regs->ebx; ddb_regs.ebp = int_regs->ebp; ddb_regs.esi = int_regs->esi; ddb_regs.edi = int_regs->edi; ddb_regs.ds = is->ds; ddb_regs.es = is->es; ddb_regs.fs = is->fs; ddb_regs.gs = is->gs; cnpollc(TRUE); db_task_trap(-1, 0, (ddb_regs.cs & 0x3) != 0); cnpollc(FALSE); if ((ddb_regs.cs & 0x3) != KERNEL_RING) { ((int *)(is+1))[0] = ddb_regs.uesp; ((int *)(is+1))[1] = ddb_regs.ss & 0xffff; } is->efl = ddb_regs.efl; is->cs = ddb_regs.cs & 0xffff; is->eip = ddb_regs.eip; is->eax = ddb_regs.eax; is->ecx = ddb_regs.ecx; is->edx = ddb_regs.edx; int_regs->ebx = ddb_regs.ebx; int_regs->ebp = ddb_regs.ebp; int_regs->esi = ddb_regs.esi; int_regs->edi = ddb_regs.edi; is->ds = ddb_regs.ds & 0xffff; is->es = ddb_regs.es & 0xffff; is->fs = ddb_regs.fs & 0xffff; is->gs = ddb_regs.gs & 0xffff; } #if NCPUS > 1 db_leave(); #endif /* NCPUS > 1 */ (void) splx(s); }
/* * kdb_trap - field a TRACE or BPT trap */ void kdb_trap( int type, struct savearea *regs) { boolean_t trap_from_user; int previous_console_device; int code=0; previous_console_device=switch_to_serial_console(); switch (type) { case T_TRACE: /* single_step */ case T_PROGRAM: /* breakpoint */ #if 0 case T_WATCHPOINT: /* watchpoint */ #endif case -1: /* keyboard interrupt */ break; default: if (db_recover) { ppc_nested_saved_state = *regs; db_printf("Caught "); if (type > TRAP_TYPES) db_printf("type %d", type); else db_printf("%s", trap_type[type]); db_printf(" trap, pc = %x\n", regs->save_srr0); db_error(""); /*NOTREACHED*/ } kdbprinttrap(type, code, (int *)®s->save_srr0, regs->save_r1); } saved_state[cpu_number()] = regs; ppc_last_saved_statep = regs; ppc_last_kdb_sp = (unsigned) &type; if (!IS_USER_TRAP(regs)) { bzero((char *)&ddb_regs, sizeof (ddb_regs)); ddb_regs = *regs; trap_from_user = FALSE; } else { ddb_regs = *regs; trap_from_user = TRUE; } db_task_trap(type, code, trap_from_user); *regs = ddb_regs; if ((type == T_PROGRAM) && (db_get_task_value(regs->save_srr0, BKPT_SIZE, FALSE, db_target_space(current_act(), trap_from_user)) == BKPT_INST)) regs->save_srr0 += BKPT_SIZE; kdb_exit: saved_state[cpu_number()] = 0; switch_to_old_console(previous_console_device); }