2 * Copyright (c) 2000 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@
29 #include <mach/mach_types.h>
30 #include <mach/machine.h>
31 #include <mach/exception_types.h>
32 #include <kern/cpu_data.h>
33 #include <i386/trap.h>
35 #include <kdp/kdp_internal.h>
37 #define KDP_TEST_HARNESS 0
39 #define dprintf(x) printf x
44 extern void kdreboot(void);
46 void print_saved_state(void *);
49 boolean_t
kdp_call_kdb(void);
50 void kdp_getstate(i386_thread_state_t
*);
51 void kdp_setstate(i386_thread_state_t
*);
52 void kdp_print_phys(int);
53 void kdp_i386_backtrace(void *, int);
56 struct i386_saved_state
*,
64 unsigned short *remote_port
,
65 unsigned int exception
,
70 kdp_exception_t
*rq
= (kdp_exception_t
*)pkt
;
72 rq
->hdr
.request
= KDP_EXCEPTION
;
74 rq
->hdr
.seq
= kdp
.exception_seq
;
76 rq
->hdr
.len
= sizeof (*rq
);
79 rq
->exc_info
[0].cpu
= 0;
80 rq
->exc_info
[0].exception
= exception
;
81 rq
->exc_info
[0].code
= code
;
82 rq
->exc_info
[0].subcode
= subcode
;
84 rq
->hdr
.len
+= rq
->n_exc_info
* sizeof (kdp_exc_info_t
);
86 bcopy((char *)rq
, (char *)pkt
, rq
->hdr
.len
);
88 kdp
.exception_ack_needed
= TRUE
;
90 *remote_port
= kdp
.exception_port
;
100 kdp_exception_ack_t
*rq
= (kdp_exception_ack_t
*)pkt
;
102 if (((unsigned int) len
) < sizeof (*rq
))
105 if (!rq
->hdr
.is_reply
|| rq
->hdr
.request
!= KDP_EXCEPTION
)
108 dprintf(("kdp_exception_ack seq %x %x\n", rq
->hdr
.seq
, kdp
.exception_seq
));
110 if (rq
->hdr
.seq
== kdp
.exception_seq
) {
111 kdp
.exception_ack_needed
= FALSE
;
119 i386_thread_state_t
*state
122 static i386_thread_state_t null_state
;
123 struct i386_saved_state
*saved_state
;
125 saved_state
= (struct i386_saved_state
*)kdp
.saved_state
;
128 state
->eax
= saved_state
->eax
;
129 state
->ebx
= saved_state
->ebx
;
130 state
->ecx
= saved_state
->ecx
;
131 state
->edx
= saved_state
->edx
;
132 state
->edi
= saved_state
->edi
;
133 state
->esi
= saved_state
->esi
;
134 state
->ebp
= saved_state
->ebp
;
136 if ((saved_state
->cs
& 0x3) == 0){ /* Kernel State */
137 state
->esp
= (unsigned int) &saved_state
->uesp
;
138 state
->ss
= KERNEL_DS
;
140 state
->esp
= saved_state
->uesp
;
141 state
->ss
= saved_state
->ss
;
144 state
->eflags
= saved_state
->efl
;
145 state
->eip
= saved_state
->eip
;
146 state
->cs
= saved_state
->cs
;
147 state
->ds
= saved_state
->ds
;
148 state
->es
= saved_state
->es
;
149 state
->fs
= saved_state
->fs
;
150 state
->gs
= saved_state
->gs
;
156 i386_thread_state_t
*state
159 struct i386_saved_state
*saved_state
;
161 saved_state
= (struct i386_saved_state
*)kdp
.saved_state
;
163 saved_state
->eax
= state
->eax
;
164 saved_state
->ebx
= state
->ebx
;
165 saved_state
->ecx
= state
->ecx
;
166 saved_state
->edx
= state
->edx
;
167 saved_state
->edi
= state
->edi
;
168 saved_state
->esi
= state
->esi
;
169 saved_state
->ebp
= state
->ebp
;
170 saved_state
->efl
= state
->eflags
;
172 saved_state
->frame
.eflags
&= ~( EFL_VM
| EFL_NT
| EFL_IOPL
| EFL_CLR
);
173 saved_state
->frame
.eflags
|= ( EFL_IF
| EFL_SET
);
175 saved_state
->eip
= state
->eip
;
176 saved_state
->fs
= state
->fs
;
177 saved_state
->gs
= state
->gs
;
182 kdp_machine_read_regs(
183 __unused
unsigned int cpu
,
184 __unused
unsigned int flavor
,
189 static i386_thread_fpstate_t null_fpstate
;
193 case i386_THREAD_STATE
:
194 dprintf(("kdp_readregs THREAD_STATE\n"));
195 kdp_getstate((i386_thread_state_t
*)data
);
196 *size
= sizeof (i386_thread_state_t
);
197 return KDPERR_NO_ERROR
;
199 case i386_THREAD_FPSTATE
:
200 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
201 *(i386_thread_fpstate_t
*)data
= null_fpstate
;
202 *size
= sizeof (i386_thread_fpstate_t
);
203 return KDPERR_NO_ERROR
;
206 dprintf(("kdp_readregs bad flavor %d\n", flavor
));
208 return KDPERR_BADFLAVOR
;
213 kdp_machine_write_regs(
214 __unused
unsigned int cpu
,
222 case i386_THREAD_STATE
:
223 dprintf(("kdp_writeregs THREAD_STATE\n"));
224 kdp_setstate((i386_thread_state_t
*)data
);
225 return KDPERR_NO_ERROR
;
227 case i386_THREAD_FPSTATE
:
228 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
229 return KDPERR_NO_ERROR
;
232 dprintf(("kdp_writeregs bad flavor %d\n"));
233 return KDPERR_BADFLAVOR
;
240 kdp_machine_hostinfo(
241 kdp_hostinfo_t
*hostinfo
246 hostinfo
->cpus_mask
= 0;
248 for (i
= 0; i
< machine_info
.max_cpus
; i
++) {
249 if (cpu_data_ptr
[i
] == NULL
)
252 hostinfo
->cpus_mask
|= (1 << i
);
256 hostinfo
->cpu_type
= CPU_TYPE_I386
;
257 hostinfo
->cpu_subtype
= CPU_SUBTYPE_486
;
265 kprintf("kdp panic: %s\n", msg
);
266 __asm__
volatile("hlt");
295 kdp_us_spin(int usec
)
300 void print_saved_state(void *state
)
302 struct i386_saved_state
*saved_state
;
306 kprintf("pc = 0x%x\n", saved_state
->eip
);
307 kprintf("cr3= 0x%x\n", saved_state
->cr2
);
308 kprintf("rp = TODO FIXME\n");
309 kprintf("sp = 0x%x\n", saved_state
->esp
);
316 return; /* No op here. */
322 __asm__
volatile ("int $3"); /* Let the processor do the work */
326 typedef struct _cframe_t
{
327 struct _cframe_t
*prev
;
332 #include <i386/pmap.h>
333 extern pt_entry_t
*DMAP2
;
334 extern caddr_t DADDR2
;
337 kdp_print_phys(int src
)
342 *(int *) DMAP2
= 0x63 | (src
& 0xfffff000);
343 invlpg((u_int
) DADDR2
);
344 iptr
= (unsigned int *) DADDR2
;
345 for (i
= 0; i
< 100; i
++) {
346 kprintf("0x%x ", *iptr
++);
356 #define MAX_FRAME_DELTA 65536
359 kdp_i386_backtrace(void *_frame
, int nframes
)
361 cframe_t
*frame
= (cframe_t
*)_frame
;
364 for (i
=0; i
<nframes
; i
++) {
365 if ((vm_offset_t
)frame
< VM_MIN_KERNEL_ADDRESS
||
366 (vm_offset_t
)frame
> VM_MAX_KERNEL_ADDRESS
) {
369 kprintf("frame 0x%x called by 0x%x ",
370 frame
, frame
->caller
);
371 kprintf("args 0x%x 0x%x 0x%x 0x%x\n",
372 frame
->args
[0], frame
->args
[1],
373 frame
->args
[2], frame
->args
[3]);
374 if ((frame
->prev
< frame
) || /* wrong direction */
375 ((frame
->prev
- frame
) > MAX_FRAME_DELTA
)) {
382 kprintf("invalid frame pointer 0x%x\n",frame
);
388 struct i386_saved_state
*saved_state
,
389 kern_return_t result
,
393 unsigned int exception
, subcode
= 0, code
;
397 if (trapno
!= T_INT3
&& trapno
!= T_DEBUG
)
398 kprintf("unexpected kernel trap 0x%x eip 0x%x cr2 0x%x \n",
399 trapno
, saved_state
->eip
, saved_state
->esp
);
404 exception
= EXC_ARITHMETIC
;
405 code
= EXC_I386_DIVERR
;
409 exception
= EXC_SOFTWARE
;
410 code
= EXC_I386_INTOFLT
;
413 case T_OUT_OF_BOUNDS
:
414 exception
= EXC_ARITHMETIC
;
415 code
= EXC_I386_BOUNDFLT
;
418 case T_INVALID_OPCODE
:
419 exception
= EXC_BAD_INSTRUCTION
;
420 code
= EXC_I386_INVOPFLT
;
423 case T_SEGMENT_NOT_PRESENT
:
424 exception
= EXC_BAD_INSTRUCTION
;
425 code
= EXC_I386_SEGNPFLT
;
426 subcode
= saved_state
->err
;
430 exception
= EXC_BAD_INSTRUCTION
;
431 code
= EXC_I386_STKFLT
;
432 subcode
= saved_state
->err
;
435 case T_GENERAL_PROTECTION
:
436 exception
= EXC_BAD_INSTRUCTION
;
437 code
= EXC_I386_GPFLT
;
438 subcode
= saved_state
->err
;
442 exception
= EXC_BAD_ACCESS
;
448 exception
= EXC_SOFTWARE
;
449 code
= EXC_I386_ALIGNFLT
;
454 exception
= EXC_BREAKPOINT
;
455 code
= EXC_I386_BPTFLT
;
459 exception
= EXC_BAD_INSTRUCTION
;
464 kdp_i386_backtrace((void *) saved_state
->ebp
, 10);
466 kdp_raise_exception(exception
, code
, subcode
, saved_state
);
479 kdp_ml_get_breakinsn(void)