X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8ad349bb6ed4a0be06e34c92be0d98b92e078db4..5d5c5d0d5b79ade9a973d55186ffda2638ba2b6e:/osfmk/i386/db_interface.c?ds=sidebyside diff --git a/osfmk/i386/db_interface.c b/osfmk/i386/db_interface.c index 1bb40a1dc..1ba20e51b 100644 --- a/osfmk/i386/db_interface.c +++ b/osfmk/i386/db_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ * @@ -78,6 +78,8 @@ #include #include #include +#include +#include #include #include @@ -94,9 +96,11 @@ #include #include +#include + int db_active = 0; -struct i386_saved_state *i386_last_saved_statep; -struct i386_saved_state i386_nested_saved_state; +x86_saved_state32_t *i386_last_saved_statep; +x86_saved_state32_t i386_nested_saved_state; unsigned i386_last_kdb_sp; extern thread_t db_default_act; @@ -119,7 +123,7 @@ struct int_regs { int esi; int ebp; int ebx; - struct i386_interrupt_state *is; + x86_saved_state32_t *is; }; extern char * trap_type[]; @@ -168,10 +172,29 @@ extern jmp_buf_t *db_recover; * in a ktss, we hard-wire that in, rather than indexing the gdt * with tss_sel to derive a pointer to the desired tss. */ + +/* + * Code used to synchronize kdb among all cpus, one active at a time, switch + * from one to another using cpu #cpu + */ + +decl_simple_lock_data(, kdb_lock) /* kdb lock */ + +#define db_simple_lock_init(l, e) hw_lock_init(&((l)->interlock)) +#define db_simple_lock_try(l) hw_lock_try(&((l)->interlock)) +#define db_simple_unlock(l) hw_lock_unlock(&((l)->interlock)) + +int kdb_cpu = -1; /* current cpu running kdb */ +int kdb_debug = 1; +volatile unsigned int cpus_holding_bkpts; /* counter for number of cpus + * holding breakpoints + */ +extern boolean_t db_breakpoints_inserted; + void db_tss_to_frame( int tss_sel, - struct i386_saved_state *regs) + x86_saved_state32_t *regs) { extern struct i386_tss ktss; int mycpu = cpu_number(); @@ -182,7 +205,7 @@ db_tss_to_frame( /* * ddb will overwrite whatever's in esp, so put esp0 elsewhere, too. */ - regs->esp = tss->esp0; + regs->cr2 = tss->esp0; regs->efl = tss->eflags; regs->eip = tss->eip; regs->trapno = tss->ss0; /* XXX */ @@ -209,7 +232,7 @@ db_tss_to_frame( */ boolean_t db_trap_from_asm( - struct i386_saved_state *regs) + x86_saved_state32_t *regs) { int code; int type; @@ -223,12 +246,18 @@ int kdb_trap( int type, int code, - struct i386_saved_state *regs) + x86_saved_state32_t *regs) { extern char etext; boolean_t trap_from_user; - spl_t s = splhigh(); + spl_t s; + int previous_console_device; + s = splhigh(); + + previous_console_device = switch_to_serial_console(); + + db_printf("kdb_trap(): type %d, code %d, regs->eip 0x%x\n", type, code, regs->eip); switch (type) { case T_DEBUG: /* single_step */ { @@ -282,8 +311,8 @@ kdb_trap( if (!IS_USER_TRAP(regs, &etext)) { bzero((char *)&ddb_regs, sizeof (ddb_regs)); - *(struct i386_saved_state_from_kernel *)&ddb_regs = - *(struct i386_saved_state_from_kernel *)regs; + *(struct x86_saved_state32_from_kernel *)&ddb_regs = + *(struct x86_saved_state32_from_kernel *)regs; trap_from_user = FALSE; } else { @@ -308,6 +337,7 @@ kdb_trap( regs->ecx = ddb_regs.ecx; regs->edx = ddb_regs.edx; regs->ebx = ddb_regs.ebx; + if (trap_from_user) { /* * user mode - saved esp and ss valid @@ -315,6 +345,7 @@ kdb_trap( 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; @@ -332,16 +363,13 @@ kdb_trap( trap_from_user)) == BKPT_INST)) regs->eip += BKPT_SIZE; - + + switch_to_old_console(previous_console_device); kdb_exit: kdb_leave(); current_cpu_datap()->cpu_kdb_saved_state = 0; -#if MACH_MP_DEBUG - current_cpu_datap()->cpu_masked_state_cnt = 0; -#endif /* MACH_MP_DEBUG */ - enable_preemption(); splx(s); @@ -371,8 +399,8 @@ kdb_kentry( { extern char etext; boolean_t trap_from_user; - struct i386_interrupt_state *is = int_regs->is; - struct i386_saved_state regs; + x86_saved_state32_t *is = int_regs->is; + x86_saved_state32_t regs; spl_t s; s = splhigh(); @@ -473,18 +501,28 @@ db_user_to_kernel_address( int flag) { register pt_entry_t *ptp; + vm_offset_t src; + + /* + * must not pre-empted while using the pte pointer passed + * back since it's been mapped through a per-cpu window + */ + mp_disable_preemption(); - ptp = pmap_pte(task->map->pmap, addr); + ptp = pmap_pte(task->map->pmap, (vm_map_offset_t)addr); if (ptp == PT_ENTRY_NULL || (*ptp & INTEL_PTE_VALID) == 0) { if (flag) { db_printf("\nno memory is assigned to address %08x\n", addr); db_error(0); /* NOTREACHED */ } + mp_enable_preemption(); return(-1); } - src = (vm_offset_t)pte_to_pa(*ptp); + + mp_enable_preemption(); + *(int *) DMAP1 = INTEL_PTE_VALID | INTEL_PTE_RW | (src & PG_FRAME) | INTEL_PTE_REF | INTEL_PTE_MOD; #if defined(I386_CPU) @@ -576,7 +614,7 @@ db_write_bytes( if (addr >= VM_MIN_KERNEL_ADDRESS && addr <= (vm_offset_t)&etext) { - ptep0 = pmap_pte(kernel_pmap, addr); + ptep0 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr); oldmap0 = *ptep0; *ptep0 |= INTEL_PTE_WRITE; @@ -584,7 +622,7 @@ db_write_bytes( if (i386_trunc_page(addr) != addr1) { /* data crosses a page boundary */ - ptep1 = pmap_pte(kernel_pmap, addr1); + ptep1 = pmap_pte(kernel_pmap, (vm_map_offset_t)addr1); oldmap1 = *ptep1; *ptep1 |= INTEL_PTE_WRITE; } @@ -762,24 +800,6 @@ db_task_name( db_printf(" "); } -/* - * Code used to synchronize kdb among all cpus, one active at a time, switch - * from on to another using kdb_on! #cpu or cpu #cpu - */ - -decl_simple_lock_data(, kdb_lock) /* kdb lock */ - -#define db_simple_lock_init(l, e) hw_lock_init(&((l)->interlock)) -#define db_simple_lock_try(l) hw_lock_try(&((l)->interlock)) -#define db_simple_unlock(l) hw_lock_unlock(&((l)->interlock)) - -int kdb_cpu = -1; /* current cpu running kdb */ -int kdb_debug = 0; -volatile unsigned int cpus_holding_bkpts; /* counter for number of cpus holding - breakpoints (ie: cpus that did not - insert back breakpoints) */ -extern boolean_t db_breakpoints_inserted; - void db_machdep_init(void) { @@ -787,16 +807,14 @@ db_machdep_init(void) db_simple_lock_init(&kdb_lock, 0); for (c = 0; c < real_ncpus; ++c) { - db_stacks[c] = (vm_offset_t) (db_stack_store + - (INTSTACK_SIZE * (c + 1)) - sizeof (natural_t)); if (c == master_cpu) { - dbtss.esp0 = (int)(db_task_stack_store + + master_dbtss.esp0 = (int)(db_task_stack_store + (INTSTACK_SIZE * (c + 1)) - sizeof (natural_t)); - dbtss.esp = dbtss.esp0; - dbtss.eip = (int)&db_task_start; + master_dbtss.esp = master_dbtss.esp0; + master_dbtss.eip = (int)&db_task_start; /* * The TSS for the debugging task on each slave CPU - * is set up in mp_desc_init(). + * is set up in cpu_desc_init(). */ } } @@ -813,12 +831,12 @@ db_machdep_init(void) int kdb_enter(int pc) { - int mycpu; + int my_cpu; int retval; disable_preemption(); - mycpu = cpu_number(); + my_cpu = cpu_number(); if (current_cpu_datap()->cpu_db_pass_thru) { retval = 0; @@ -826,16 +844,17 @@ kdb_enter(int pc) } current_cpu_datap()->cpu_kdb_active++; + lock_kdb(); - if (kdb_debug) - db_printf("kdb_enter: cpu %d, is_slave %d, kdb_cpu %d, run mode %d pc %x (%x) holds %d\n", - my_cpu, current_cpu_datap()->cpu_kdb_is_slave, kdb_cpu, - db_run_mode, pc, *(int *)pc, cpus_holding_bkpts); + db_printf("kdb_enter(): cpu_number %d, kdb_cpu %d\n", my_cpu, kdb_cpu); + if (db_breakpoints_inserted) cpus_holding_bkpts++; + if (kdb_cpu == -1 && !current_cpu_datap()->cpu_kdb_is_slave) { kdb_cpu = my_cpu; + db_printf("Signaling other processors..\n"); remote_kdb(); /* stop other cpus */ retval = 1; } else if (kdb_cpu == my_cpu) @@ -876,6 +895,8 @@ kdb_leave(void) unlock_kdb(); current_cpu_datap()->cpu_kdb_active--; + mp_kdb_exit(); + enable_preemption(); if (wait) { @@ -888,14 +909,12 @@ lock_kdb(void) { int my_cpu; register i; - extern void kdb_console(void); disable_preemption(); my_cpu = cpu_number(); for(;;) { - kdb_console(); if (kdb_cpu != -1 && kdb_cpu != my_cpu) { continue; } @@ -990,21 +1009,17 @@ kdb_on( } } +/* + * system reboot + */ + +extern void kdp_reboot(void); + void db_reboot( db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) { - boolean_t reboot = TRUE; - char *cp, c; - - cp = modif; - while ((c = *cp++) != 0) { - if (c == 'r') /* reboot */ - reboot = TRUE; - if (c == 'h') /* halt */ - reboot = FALSE; - } - halt_all_cpus(reboot); + kdp_reboot(); }