2  * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  32  * Mach Operating System 
  33  * Copyright (c) 1991,1990 Carnegie Mellon University 
  34  * All Rights Reserved. 
  36  * Permission to use, copy, modify and distribute this software and its 
  37  * documentation is hereby granted, provided that both the copyright 
  38  * notice and this permission notice appear in all copies of the 
  39  * software, derivative works or modified versions, and any portions 
  40  * thereof, and that both notices appear in supporting documentation. 
  42  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
  43  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 
  44  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 
  46  * Carnegie Mellon requests users of this software to return to 
  48  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU 
  49  *  School of Computer Science 
  50  *  Carnegie Mellon University 
  51  *  Pittsburgh PA 15213-3890 
  53  * any improvements or extensions that they make and grant Carnegie Mellon 
  54  * the rights to redistribute these changes. 
  60  * Interface to new debugger. 
  62 #include <platforms.h> 
  63 #include <time_stamp.h> 
  64 #include <mach_mp_debug.h> 
  65 #include <mach_ldebug.h> 
  67 #include <kern/cpu_number.h> 
  68 #include <kern/kern_types.h> 
  69 #include <kern/misc_protos.h> 
  72 #include <i386/thread.h> 
  73 #include <i386/db_machdep.h> 
  75 #include <i386/trap.h> 
  76 #include <i386/setjmp.h> 
  77 #include <i386/pmap.h> 
  78 #include <i386/misc_protos.h> 
  80 #include <i386/machine_cpu.h> 
  82 #include <mach/vm_param.h> 
  83 #include <vm/vm_map.h> 
  84 #include <kern/thread.h> 
  85 #include <kern/task.h> 
  87 #include <ddb/db_command.h> 
  88 #include <ddb/db_task_thread.h> 
  89 #include <ddb/db_run.h> 
  90 #include <ddb/db_trap.h> 
  91 #include <ddb/db_output.h> 
  92 #include <ddb/db_access.h> 
  93 #include <ddb/db_sym.h> 
  94 #include <ddb/db_break.h> 
  95 #include <ddb/db_watch.h> 
  97 #include <i386/cpu_data.h> 
 100 x86_saved_state32_t     
*i386_last_saved_statep
; 
 101 x86_saved_state32_t     i386_nested_saved_state
; 
 102 unsigned i386_last_kdb_sp
; 
 103 db_regs_t       ddb_regs
;       /* register state */ 
 105 extern  thread_t db_default_act
; 
 106 extern pt_entry_t 
*DMAP1
; 
 107 extern caddr_t DADDR1
; 
 110 extern int masked_state_cnt
[]; 
 111 #endif  /* MACH_MP_DEBUG */ 
 114  *      Enter KDB through a keyboard trap. 
 115  *      We show the registers as of the keyboard interrupt 
 116  *      instead of those at its call to KDB. 
 125         x86_saved_state32_t 
*is
; 
 128 extern char *   trap_type
[]; 
 129 extern int      TRAP_TYPES
; 
 133 extern void     kdbprinttrap( 
 138 extern void     kdb_kentry( 
 139                         struct int_regs         
*int_regs
); 
 140 extern int      db_user_to_kernel_address( 
 145 extern void     db_write_bytes_user_space( 
 150 extern int      db_search_null( 
 156 extern int      kdb_enter(int); 
 157 extern void     kdb_leave(void); 
 158 extern void     lock_kdb(void); 
 159 extern void     unlock_kdb(void); 
 162  *  kdb_trap - field a TRACE or BPT trap 
 166 extern jmp_buf_t 
*db_recover
; 
 169  * Translate the state saved in a task state segment into an 
 170  * exception frame.  Since we "know" we always want the state 
 171  * in a ktss, we hard-wire that in, rather than indexing the gdt 
 172  * with tss_sel to derive a pointer to the desired tss. 
 176  * Code used to synchronize kdb among all cpus, one active at a time, switch 
 177  * from one to another using cpu #cpu 
 180 decl_simple_lock_data(, kdb_lock
)       /* kdb lock                     */ 
 182 #define db_simple_lock_init(l, e)       hw_lock_init(&((l)->interlock)) 
 183 #define db_simple_lock_try(l)           hw_lock_try(&((l)->interlock)) 
 184 #define db_simple_unlock(l)             hw_lock_unlock(&((l)->interlock)) 
 186 int                     kdb_cpu 
= -1;   /* current cpu running kdb      */ 
 188 volatile unsigned int   cpus_holding_bkpts
;     /* counter for number of cpus 
 189                                                  * holding breakpoints 
 191 extern boolean_t        db_breakpoints_inserted
; 
 196         x86_saved_state32_t 
*regs
) 
 198         extern struct i386_tss ktss
; 
 199         int mycpu 
= cpu_number(); 
 200         struct i386_tss 
*tss
; 
 202         tss 
= cpu_datap(mycpu
)->cpu_desc_index
.cdi_ktss
;        /* XXX */ 
 205          * ddb will overwrite whatever's in esp, so put esp0 elsewhere, too. 
 207         regs
->cr2 
= tss
->esp0
; 
 208         regs
->efl 
= tss
->eflags
; 
 209         regs
->eip 
= tss
->eip
; 
 210         regs
->trapno 
= tss
->ss0
;        /* XXX */ 
 211         regs
->err 
= tss
->esp0
;  /* XXX */ 
 212         regs
->eax 
= tss
->eax
; 
 213         regs
->ecx 
= tss
->ecx
; 
 214         regs
->edx 
= tss
->edx
; 
 215         regs
->ebx 
= tss
->ebx
; 
 216         regs
->uesp 
= tss
->esp
; 
 217         regs
->ebp 
= tss
->ebp
; 
 218         regs
->esi 
= tss
->esi
; 
 219         regs
->edi 
= tss
->edi
; 
 229  * Compose a call to the debugger from the saved state in regs.  (No 
 230  * reason not to do this in C.) 
 234         x86_saved_state32_t 
*regs
) 
 241         return (kdb_trap(type
, code
, regs
)); 
 248         x86_saved_state32_t     
*regs
) 
 251         boolean_t               trap_from_user
; 
 253         int                     previous_console_device
; 
 257         previous_console_device 
= switch_to_serial_console(); 
 259         db_printf("kdb_trap(): type %d, code %d, regs->eip 0x%x\n", type
, code
, regs
->eip
); 
 261             case T_DEBUG
:       /* single_step */ 
 263                 extern int dr_addr
[]; 
 267                 __asm__ 
volatile ("movl %%dr6, %0" : "=r" (status
)); 
 269                 if (status 
& 0xf) {     /* hmm hdw break */ 
 270                         addr 
=  status 
& 0x8 ? dr_addr
[3] : 
 271                                 status 
& 0x4 ? dr_addr
[2] : 
 272                                 status 
& 0x2 ? dr_addr
[1] : 
 275                         db_single_step_cmd(addr
, 0, 1, "p"); 
 278             case T_INT3
:        /* breakpoint */ 
 279             case T_WATCHPOINT
:  /* watchpoint */ 
 280             case -1:    /* keyboard interrupt */ 
 285                     i386_nested_saved_state 
= *regs
; 
 286                     db_printf("Caught "); 
 287                     if (type 
< 0 || type 
> TRAP_TYPES
) 
 288                         db_printf("type %d", type
); 
 290                         db_printf("%s", trap_type
[type
]); 
 291                     db_printf(" trap, code = %x, pc = %x\n", 
 297                 kdbprinttrap(type
, code
, (int *)®s
->eip
, regs
->uesp
); 
 300         disable_preemption(); 
 302         current_cpu_datap()->cpu_kdb_saved_ipl 
= s
; 
 303         current_cpu_datap()->cpu_kdb_saved_state 
= regs
; 
 305         i386_last_saved_statep 
= regs
; 
 306         i386_last_kdb_sp 
= (unsigned) &type
; 
 308         if (!kdb_enter(regs
->eip
)) 
 311         /*  Should switch to kdb's own stack here. */ 
 313         if (!IS_USER_TRAP(regs
, &etext
)) { 
 314                 bzero((char *)&ddb_regs
, sizeof (ddb_regs
)); 
 315                 *(struct x86_saved_state32_from_kernel 
*)&ddb_regs 
= 
 316                         *(struct x86_saved_state32_from_kernel 
*)regs
; 
 317                 trap_from_user 
= FALSE
; 
 321                 trap_from_user 
= TRUE
; 
 323         if (!trap_from_user
) { 
 325              * Kernel mode - esp and ss not saved 
 327             ddb_regs
.uesp 
= (int)®s
->uesp
;   /* kernel stack pointer */ 
 328             ddb_regs
.ss   
= KERNEL_DS
; 
 332         db_task_trap(type
, code
, trap_from_user
); 
 335         regs
->eip    
= ddb_regs
.eip
; 
 336         regs
->efl    
= ddb_regs
.efl
; 
 337         regs
->eax    
= ddb_regs
.eax
; 
 338         regs
->ecx    
= ddb_regs
.ecx
; 
 339         regs
->edx    
= ddb_regs
.edx
; 
 340         regs
->ebx    
= ddb_regs
.ebx
; 
 342         if (trap_from_user
) { 
 344              * user mode - saved esp and ss valid 
 346             regs
->uesp 
= ddb_regs
.uesp
;         /* user stack pointer */ 
 347             regs
->ss   
= ddb_regs
.ss 
& 0xffff;  /* user stack segment */ 
 350         regs
->ebp    
= ddb_regs
.ebp
; 
 351         regs
->esi    
= ddb_regs
.esi
; 
 352         regs
->edi    
= ddb_regs
.edi
; 
 353         regs
->es     
= ddb_regs
.es 
& 0xffff; 
 354         regs
->cs     
= ddb_regs
.cs 
& 0xffff; 
 355         regs
->ds     
= ddb_regs
.ds 
& 0xffff; 
 356         regs
->fs     
= ddb_regs
.fs 
& 0xffff; 
 357         regs
->gs     
= ddb_regs
.gs 
& 0xffff; 
 359         if ((type 
== T_INT3
) && 
 360             (db_get_task_value(regs
->eip
, 
 363                                db_target_space(current_thread(), 
 366             regs
->eip 
+= BKPT_SIZE
; 
 368         switch_to_old_console(previous_console_device
); 
 372         current_cpu_datap()->cpu_kdb_saved_state 
= 0; 
 378         /* Allow continue to upper layers of exception handling if 
 379          * trap was not a debugging trap. 
 382         if (trap_from_user 
&& type 
!= T_DEBUG 
&& type 
!= T_INT3 
 
 383                 && type 
!= T_WATCHPOINT
) 
 390  *      Enter KDB through a keyboard trap. 
 391  *      We show the registers as of the keyboard interrupt 
 392  *      instead of those at its call to KDB. 
 399         struct int_regs 
*int_regs
) 
 402         boolean_t trap_from_user
; 
 403         x86_saved_state32_t 
*is 
= int_regs
->is
; 
 404         x86_saved_state32_t regs
; 
 410         if (IS_USER_TRAP(is
, &etext
)) 
 412             regs
.uesp 
= ((int *)(is
+1))[0]; 
 413             regs
.ss   
= ((int *)(is
+1))[1]; 
 417             regs
.uesp
= (int)(is
+1); 
 425         regs
.ebx 
= int_regs
->ebx
; 
 426         regs
.ebp 
= int_regs
->ebp
; 
 427         regs
.esi 
= int_regs
->esi
; 
 428         regs
.edi 
= int_regs
->edi
; 
 431         regs
.fs  
= int_regs
->fs
; 
 432         regs
.gs  
= int_regs
->gs
; 
 434         disable_preemption(); 
 436         current_cpu_datap()->cpu_kdb_saved_state 
= ®s
; 
 438         if (!kdb_enter(regs
.eip
)) 
 441         bcopy((char *)®s
, (char *)&ddb_regs
, sizeof (ddb_regs
)); 
 442         trap_from_user 
= IS_USER_TRAP(&ddb_regs
, &etext
); 
 445         db_task_trap(-1, 0, trap_from_user
); 
 448         if (trap_from_user
) { 
 449             ((int *)(is
+1))[0] = ddb_regs
.uesp
; 
 450             ((int *)(is
+1))[1] = ddb_regs
.ss 
& 0xffff; 
 452         is
->efl 
= ddb_regs
.efl
; 
 453         is
->cs  
= ddb_regs
.cs 
& 0xffff; 
 454         is
->eip 
= ddb_regs
.eip
; 
 455         is
->eax 
= ddb_regs
.eax
; 
 456         is
->ecx 
= ddb_regs
.ecx
; 
 457         is
->edx 
= ddb_regs
.edx
; 
 458         int_regs
->ebx 
= ddb_regs
.ebx
; 
 459         int_regs
->ebp 
= ddb_regs
.ebp
; 
 460         int_regs
->esi 
= ddb_regs
.esi
; 
 461         int_regs
->edi 
= ddb_regs
.edi
; 
 462         is
->ds  
= ddb_regs
.ds 
& 0xffff; 
 463         is
->es  
= ddb_regs
.es 
& 0xffff; 
 464         int_regs
->fs 
= ddb_regs
.fs 
& 0xffff; 
 465         int_regs
->gs 
= ddb_regs
.gs 
& 0xffff; 
 469         current_cpu_datap()->cpu_kdb_saved_state 
= 0; 
 488         if (type 
< 0 || type 
> TRAP_TYPES
) 
 489             db_printf("type %d", type
); 
 491             db_printf("%s", trap_type
[type
]); 
 492         db_printf(" trap, code=%x eip@%x = %x esp=%x\n", 
 493                   code
, pc
, *(int *)pc
, sp
); 
 494         db_run_mode 
= STEP_CONTINUE
; 
 498 db_user_to_kernel_address( 
 504         register pt_entry_t 
*ptp
; 
 508          * must not pre-empted while using the pte pointer passed 
 509          * back since it's been mapped through a per-cpu window 
 511         mp_disable_preemption(); 
 513         ptp 
= pmap_pte(task
->map
->pmap
, (vm_map_offset_t
)addr
); 
 514         if (ptp 
== PT_ENTRY_NULL 
|| (*ptp 
& INTEL_PTE_VALID
) == 0) { 
 516                 db_printf("\nno memory is assigned to address %08x\n", addr
); 
 520             mp_enable_preemption(); 
 523         src 
= (vm_offset_t
)pte_to_pa(*ptp
); 
 524         mp_enable_preemption(); 
 526         *(int *) DMAP1 
= INTEL_PTE_VALID 
| INTEL_PTE_RW 
| (src 
& PG_FRAME
) |  
 527           INTEL_PTE_REF 
| INTEL_PTE_MOD
; 
 528 #if defined(I386_CPU) 
 529         if (cpu_class 
== CPUCLASS_386
) { 
 534                 invlpg((u_int
)DADDR1
); 
 537         *kaddr 
= (unsigned)DADDR1 
+ (addr 
& PAGE_MASK
); 
 543  * Read bytes from kernel address space for debugger. 
 558         if (task 
== kernel_task 
|| task 
== TASK_NULL
) { 
 559             while (--size 
>= 0) { 
 560                 if (addr
++ > VM_MAX_KERNEL_ADDRESS
) { 
 561                     db_printf("\nbad address %x\n", addr
); 
 570             if (db_user_to_kernel_address(task
, addr
, &kern_addr
, 1) < 0) 
 572             src 
= (char *)kern_addr
; 
 573             n 
= intel_trunc_page(addr
+INTEL_PGBYTES
) - addr
; 
 584  * Write bytes to kernel address space for debugger. 
 596         register pt_entry_t 
*ptep0 
= 0; 
 597         pt_entry_t      oldmap0 
= 0; 
 599         register pt_entry_t 
*ptep1 
= 0; 
 600         pt_entry_t      oldmap1 
= 0; 
 603         if (task 
&& task 
!= kernel_task
) { 
 604             db_write_bytes_user_space(addr
, size
, data
, task
); 
 609         if (addr 
>= VM_MIN_KERNEL_LOADED_ADDRESS
) { 
 610                 db_write_bytes_user_space(addr
, size
, data
, kernel_task
); 
 614         if (addr 
>= VM_MIN_KERNEL_ADDRESS 
&& 
 615             addr 
<= (vm_offset_t
)&etext
) 
 617             ptep0 
= pmap_pte(kernel_pmap
, (vm_map_offset_t
)addr
); 
 619             *ptep0 
|= INTEL_PTE_WRITE
; 
 621             addr1 
= i386_trunc_page(addr 
+ size 
- 1); 
 622             if (i386_trunc_page(addr
) != addr1
) { 
 623                 /* data crosses a page boundary */ 
 625                 ptep1 
= pmap_pte(kernel_pmap
, (vm_map_offset_t
)addr1
); 
 627                 *ptep1 
|= INTEL_PTE_WRITE
; 
 634         while (--size 
>= 0) { 
 635             if (addr
++ > VM_MAX_KERNEL_ADDRESS
) { 
 636                 db_printf("\nbad address %x\n", addr
); 
 653 db_write_bytes_user_space( 
 664             if (db_user_to_kernel_address(task
, addr
, &kern_addr
, 1) < 0) 
 666             dst 
= (char *)kern_addr
; 
 667             n 
= intel_trunc_page(addr
+INTEL_PGBYTES
) - addr
; 
 686         if (task 
== kernel_task 
|| task 
== TASK_NULL
) { 
 687             if (kernel_task 
== TASK_NULL
) 
 690         } else if (task 
== TASK_NULL
) { 
 691             if (current_thread() == THREAD_NULL
) 
 693             task 
= current_thread()->task
; 
 696             if (db_user_to_kernel_address(task
, addr
, &kern_addr
, 0) < 0) 
 698             n 
= intel_trunc_page(addr
+INTEL_PGBYTES
) - addr
; 
 714         unsigned        kern_addr1
, kern_addr2
; 
 716         if ((addr1 
& (INTEL_PGBYTES
-1)) != (addr2 
& (INTEL_PGBYTES
-1))) 
 718         if (task1 
== TASK_NULL
) { 
 719             if (current_thread() == THREAD_NULL
) 
 721             task1 
= current_thread()->task
; 
 723         if (db_user_to_kernel_address(task1
, addr1
, &kern_addr1
, 0) < 0 || 
 724                 db_user_to_kernel_address(task2
, addr2
, &kern_addr2
, 0) < 0) 
 726         return(kern_addr1 
== kern_addr2
); 
 729 #define DB_USER_STACK_ADDR              (VM_MIN_KERNEL_ADDRESS) 
 730 #define DB_NAME_SEARCH_LIMIT            (DB_USER_STACK_ADDR-(INTEL_PGBYTES*3)) 
 740         register unsigned vaddr
; 
 741         register unsigned *kaddr
; 
 743         kaddr 
= (unsigned *)*skaddr
; 
 744         for (vaddr 
= *svaddr
; vaddr 
> evaddr
; vaddr 
-= sizeof(unsigned)) { 
 745             if (vaddr 
% INTEL_PGBYTES 
== 0) { 
 746                 vaddr 
-= sizeof(unsigned); 
 747                 if (db_user_to_kernel_address(task
, vaddr
, skaddr
, 0) < 0) 
 749                 kaddr 
= (unsigned *)*skaddr
; 
 751                 vaddr 
-= sizeof(unsigned); 
 754             if ((*kaddr 
== 0) ^ (flag  
== 0)) { 
 756                 *skaddr 
= (unsigned)kaddr
; 
 769         unsigned vaddr
, kaddr
; 
 771         vaddr 
= DB_USER_STACK_ADDR
; 
 775          * skip nulls at the end 
 777         if (db_search_null(task
, &vaddr
, DB_NAME_SEARCH_LIMIT
, &kaddr
, 0) < 0) { 
 778             db_printf(DB_NULL_TASK_NAME
); 
 782          * search start of args 
 784         if (db_search_null(task
, &vaddr
, DB_NAME_SEARCH_LIMIT
, &kaddr
, 1) < 0) { 
 785             db_printf(DB_NULL_TASK_NAME
); 
 789         n 
= DB_TASK_NAME_LEN
-1; 
 790         p 
= (char *)kaddr 
+ sizeof(unsigned); 
 791         for (vaddr 
+= sizeof(int); vaddr 
< DB_USER_STACK_ADDR 
&& n 
> 0;  
 793             if (vaddr 
% INTEL_PGBYTES 
== 0) { 
 794                 (void)db_user_to_kernel_address(task
, vaddr
, &kaddr
, 0); 
 797             db_printf("%c", (*p 
< ' ' || *p 
> '~')? ' ': *p
); 
 799         while (n
-- >= 0)        /* compare with >= 0 for one more space */ 
 804 db_machdep_init(void) 
 808         db_simple_lock_init(&kdb_lock
, 0); 
 809         for (c 
= 0; c 
< real_ncpus
; ++c
) { 
 810                 if (c 
== master_cpu
) { 
 811                         master_dbtss
.esp0 
= (int)(db_task_stack_store 
+ 
 812                                 (INTSTACK_SIZE 
* (c 
+ 1)) - sizeof (natural_t
)); 
 813                         master_dbtss
.esp 
= master_dbtss
.esp0
; 
 814                         master_dbtss
.eip 
= (int)&db_task_start
; 
 816                          * The TSS for the debugging task on each slave CPU 
 817                          * is set up in cpu_desc_init(). 
 824  * Called when entering kdb: 
 825  * Takes kdb lock. If if we were called remotely (slave state) we just 
 826  * wait for kdb_cpu to be equal to cpu_number(). Otherwise enter kdb if 
 827  * not active on another cpu. 
 828  * If db_pass_thru[cpu_number()] > 0, then kdb can't stop now. 
 837         disable_preemption(); 
 839         my_cpu 
= cpu_number(); 
 841         if (current_cpu_datap()->cpu_db_pass_thru
) { 
 846         current_cpu_datap()->cpu_kdb_active
++; 
 850         db_printf("kdb_enter(): cpu_number %d, kdb_cpu %d\n", my_cpu
, kdb_cpu
); 
 852         if (db_breakpoints_inserted
) 
 853                 cpus_holding_bkpts
++; 
 855         if (kdb_cpu 
== -1 && !current_cpu_datap()->cpu_kdb_is_slave
) { 
 857                 db_printf("Signaling other processors..\n"); 
 858                 remote_kdb();   /* stop other cpus */ 
 860         } else if (kdb_cpu 
== my_cpu
)  
 875         boolean_t       wait 
= FALSE
; 
 877         disable_preemption(); 
 879         my_cpu 
= cpu_number(); 
 881         if (db_run_mode 
== STEP_CONTINUE
) { 
 885         if (db_breakpoints_inserted
) 
 886                 cpus_holding_bkpts
--; 
 887         if (current_cpu_datap()->cpu_kdb_is_slave
) 
 888                 current_cpu_datap()->cpu_kdb_is_slave
--; 
 890                 db_printf("kdb_leave: cpu %d, kdb_cpu %d, run_mode %d pc %x (%x) holds %d\n", 
 891                           my_cpu
, kdb_cpu
, db_run_mode
, 
 892                           ddb_regs
.eip
, *(int *)ddb_regs
.eip
, 
 896         current_cpu_datap()->cpu_kdb_active
--; 
 903                 while(cpus_holding_bkpts
); 
 913         disable_preemption(); 
 915         my_cpu 
= cpu_number(); 
 918                 if (kdb_cpu 
!= -1 && kdb_cpu 
!= my_cpu
) { 
 921                 if (db_simple_lock_try(&kdb_lock
)) { 
 922                         if (kdb_cpu 
== -1 || kdb_cpu 
== my_cpu
) 
 924                         db_simple_unlock(&kdb_lock
); 
 932 extern unsigned old_time_stamp
; 
 933 #endif  /* TIME_STAMP */ 
 938         db_simple_unlock(&kdb_lock
); 
 941 #endif  /* TIME_STAMP */ 
 946 #define KDB_SAVE(type, name) extern type name; type name##_save = name 
 947 #define KDB_RESTORE(name) name = name##_save 
 949 #define KDB_SAVE(type, name) extern type name; type name/**/_save = name 
 950 #define KDB_RESTORE(name) name = name/**/_save 
 951 #endif  /* __STDC__ */ 
 953 #define KDB_SAVE_CTXT() \ 
 954         KDB_SAVE(int, db_run_mode); \ 
 955         KDB_SAVE(boolean_t, db_sstep_print); \ 
 956         KDB_SAVE(int, db_loop_count); \ 
 957         KDB_SAVE(int, db_call_depth); \ 
 958         KDB_SAVE(int, db_inst_count); \ 
 959         KDB_SAVE(int, db_last_inst_count); \ 
 960         KDB_SAVE(int, db_load_count); \ 
 961         KDB_SAVE(int, db_store_count); \ 
 962         KDB_SAVE(boolean_t, db_cmd_loop_done); \ 
 963         KDB_SAVE(jmp_buf_t *, db_recover); \ 
 964         KDB_SAVE(db_addr_t, db_dot); \ 
 965         KDB_SAVE(db_addr_t, db_last_addr); \ 
 966         KDB_SAVE(db_addr_t, db_prev); \ 
 967         KDB_SAVE(db_addr_t, db_next); \ 
 968         KDB_SAVE(db_regs_t, ddb_regs);  
 970 #define KDB_RESTORE_CTXT() \ 
 971         KDB_RESTORE(db_run_mode); \ 
 972         KDB_RESTORE(db_sstep_print); \ 
 973         KDB_RESTORE(db_loop_count); \ 
 974         KDB_RESTORE(db_call_depth); \ 
 975         KDB_RESTORE(db_inst_count); \ 
 976         KDB_RESTORE(db_last_inst_count); \ 
 977         KDB_RESTORE(db_load_count); \ 
 978         KDB_RESTORE(db_store_count); \ 
 979         KDB_RESTORE(db_cmd_loop_done); \ 
 980         KDB_RESTORE(db_recover); \ 
 981         KDB_RESTORE(db_dot); \ 
 982         KDB_RESTORE(db_last_addr); \ 
 983         KDB_RESTORE(db_prev); \ 
 984         KDB_RESTORE(db_next); \ 
 985         KDB_RESTORE(ddb_regs);  
 988  * switch to another cpu 
 996         if (cpu 
< 0 || cpu 
>= real_ncpus 
|| !cpu_datap(cpu
)->cpu_kdb_active
) 
 998         db_set_breakpoints(); 
 999         db_set_watchpoints(); 
1003         db_clear_breakpoints(); 
1004         db_clear_watchpoints(); 
1006         if (kdb_cpu 
== -1)  {/* someone continued */ 
1007                 kdb_cpu 
= cpu_number(); 
1008                 db_continue_cmd(0, 0, 0, ""); 
1016 extern void kdp_machine_reboot(void); 
1020         boolean_t       have_addr
, 
1024         kdp_machine_reboot();