]>
git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/ml/i386/kdp_machdep.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 #include <mach/mach_types.h>
27 #include <mach/machine.h>
28 #include <mach/exception_types.h>
29 #include <i386/trap.h>
31 #include <kdp/kdp_internal.h>
33 #define KDP_TEST_HARNESS 0
35 #define dprintf(x) printf x
40 void print_saved_state(void *);
42 void kdp_i386_trap(unsigned int, struct i386_saved_state
*, kern_return_t
, vm_offset_t
);
49 unsigned short *remote_port
,
50 unsigned int exception
,
55 kdp_exception_t
*rq
= (kdp_exception_t
*)pkt
;
57 rq
->hdr
.request
= KDP_EXCEPTION
;
59 rq
->hdr
.seq
= kdp
.exception_seq
;
61 rq
->hdr
.len
= sizeof (*rq
);
64 rq
->exc_info
[0].cpu
= 0;
65 rq
->exc_info
[0].exception
= exception
;
66 rq
->exc_info
[0].code
= code
;
67 rq
->exc_info
[0].subcode
= subcode
;
69 rq
->hdr
.len
+= rq
->n_exc_info
* sizeof (kdp_exc_info_t
);
71 bcopy((char *)rq
, (char *)pkt
, rq
->hdr
.len
);
73 kdp
.exception_ack_needed
= TRUE
;
75 *remote_port
= kdp
.exception_port
;
85 kdp_exception_ack_t
*rq
= (kdp_exception_ack_t
*)pkt
;
87 if (len
< sizeof (*rq
))
90 if (!rq
->hdr
.is_reply
|| rq
->hdr
.request
!= KDP_EXCEPTION
)
93 dprintf(("kdp_exception_ack seq %x %x\n", rq
->hdr
.seq
, kdp
.exception_seq
));
95 if (rq
->hdr
.seq
== kdp
.exception_seq
) {
96 kdp
.exception_ack_needed
= FALSE
;
104 i386_thread_state_t
*state
107 struct i386_saved_state
*saved_state
;
109 saved_state
= (struct i386_saved_state
*)kdp
.saved_state
;
111 *state
= (i386_thread_state_t
) { 0 };
112 state
->eax
= saved_state
->eax
;
113 state
->ebx
= saved_state
->ebx
;
114 state
->ecx
= saved_state
->ecx
;
115 state
->edx
= saved_state
->edx
;
116 state
->edi
= saved_state
->edi
;
117 state
->esi
= saved_state
->esi
;
118 state
->ebp
= saved_state
->ebp
;
120 if ((saved_state
->cs
& 0x3) == 0){ /* Kernel State */
121 state
->esp
= (unsigned int) &saved_state
->uesp
;
122 state
->ss
= KERNEL_DS
;
124 state
->esp
= saved_state
->uesp
;
125 state
->ss
= saved_state
->ss
;
128 state
->eflags
= saved_state
->efl
;
129 state
->eip
= saved_state
->eip
;
130 state
->cs
= saved_state
->cs
;
131 state
->ds
= saved_state
->ds
;
132 state
->es
= saved_state
->es
;
133 state
->fs
= saved_state
->fs
;
134 state
->gs
= saved_state
->gs
;
140 i386_thread_state_t
*state
143 struct i386_saved_state
*saved_state
;
145 saved_state
= (struct i386_saved_state
*)kdp
.saved_state
;
147 saved_state
->eax
= state
->eax
;
148 saved_state
->ebx
= state
->ebx
;
149 saved_state
->ecx
= state
->ecx
;
150 saved_state
->edx
= state
->edx
;
151 saved_state
->edi
= state
->edi
;
152 saved_state
->esi
= state
->esi
;
153 saved_state
->ebp
= state
->ebp
;
154 saved_state
->efl
= state
->eflags
;
156 saved_state
->frame
.eflags
&= ~( EFL_VM
| EFL_NT
| EFL_IOPL
| EFL_CLR
);
157 saved_state
->frame
.eflags
|= ( EFL_IF
| EFL_SET
);
159 saved_state
->eip
= state
->eip
;
160 saved_state
->fs
= state
->fs
;
161 saved_state
->gs
= state
->gs
;
166 kdp_machine_read_regs(
175 case i386_THREAD_STATE
:
176 dprintf(("kdp_readregs THREAD_STATE\n"));
177 kdp_getstate((i386_thread_state_t
*)data
);
178 *size
= sizeof (i386_thread_state_t
);
179 return KDPERR_NO_ERROR
;
181 case i386_THREAD_FPSTATE
:
182 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
183 *(i386_thread_fpstate_t
*)data
= (i386_thread_fpstate_t
) { 0 };
184 *size
= sizeof (i386_thread_fpstate_t
);
185 return KDPERR_NO_ERROR
;
188 dprintf(("kdp_readregs bad flavor %d\n"));
189 return KDPERR_BADFLAVOR
;
194 kdp_machine_write_regs(
203 case i386_THREAD_STATE
:
204 dprintf(("kdp_writeregs THREAD_STATE\n"));
205 kdp_setstate((i386_thread_state_t
*)data
);
206 return KDPERR_NO_ERROR
;
208 case i386_THREAD_FPSTATE
:
209 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
210 return KDPERR_NO_ERROR
;
213 dprintf(("kdp_writeregs bad flavor %d\n"));
214 return KDPERR_BADFLAVOR
;
221 kdp_machine_hostinfo(
222 kdp_hostinfo_t
*hostinfo
228 hostinfo
->cpus_mask
= 0;
230 for (i
= 0; i
< machine_info
.max_cpus
; i
++) {
231 m
= &machine_slot
[i
];
235 hostinfo
->cpus_mask
|= (1 << i
);
239 hostinfo
->cpu_type
= CPU_TYPE_I386
;
240 hostinfo
->cpu_subtype
= CPU_SUBTYPE_486
;
248 printf("kdp panic: %s\n", msg
);
249 __asm__
volatile("hlt");
278 kdp_us_spin(int usec
)
280 extern void delay(int);
285 void print_saved_state(void *state
)
287 struct i386_saved_state
*saved_state
;
291 printf("pc = 0x%x\n", saved_state
->eip
);
292 printf("cr3= 0x%x\n", saved_state
->cr2
);
293 printf("rp = TODO FIXME\n");
294 printf("sp = 0x%x\n", saved_state
->esp
);
301 return; /* No op here. */
307 __asm__
volatile ("int $3"); /* Let the processor do the work */
311 typedef struct _cframe_t
{
312 struct _cframe_t
*prev
;
318 #define MAX_FRAME_DELTA 65536
321 kdp_i386_backtrace(void *_frame
, int nframes
)
323 cframe_t
*frame
= (cframe_t
*)_frame
;
326 for (i
=0; i
<nframes
; i
++) {
327 if ((vm_offset_t
)frame
< VM_MIN_KERNEL_ADDRESS
||
328 (vm_offset_t
)frame
> VM_MAX_KERNEL_ADDRESS
) {
331 printf("frame %x called by %x ",
332 frame
, frame
->caller
);
333 printf("args %x %x %x %x\n",
334 frame
->args
[0], frame
->args
[1],
335 frame
->args
[2], frame
->args
[3]);
336 if ((frame
->prev
< frame
) || /* wrong direction */
337 ((frame
->prev
- frame
) > MAX_FRAME_DELTA
)) {
344 printf("invalid frame pointer %x\n",frame
);
350 struct i386_saved_state
*saved_state
,
351 kern_return_t result
,
355 unsigned int exception
, subcode
= 0, code
;
359 if (trapno
!= T_INT3
&& trapno
!= T_DEBUG
)
360 printf("unexpected kernel trap %x eip %x\n", trapno
, saved_state
->eip
);
365 exception
= EXC_ARITHMETIC
;
366 code
= EXC_I386_DIVERR
;
370 exception
= EXC_SOFTWARE
;
371 code
= EXC_I386_INTOFLT
;
374 case T_OUT_OF_BOUNDS
:
375 exception
= EXC_ARITHMETIC
;
376 code
= EXC_I386_BOUNDFLT
;
379 case T_INVALID_OPCODE
:
380 exception
= EXC_BAD_INSTRUCTION
;
381 code
= EXC_I386_INVOPFLT
;
384 case T_SEGMENT_NOT_PRESENT
:
385 exception
= EXC_BAD_INSTRUCTION
;
386 code
= EXC_I386_SEGNPFLT
;
387 subcode
= saved_state
->err
;
391 exception
= EXC_BAD_INSTRUCTION
;
392 code
= EXC_I386_STKFLT
;
393 subcode
= saved_state
->err
;
396 case T_GENERAL_PROTECTION
:
397 exception
= EXC_BAD_INSTRUCTION
;
398 code
= EXC_I386_GPFLT
;
399 subcode
= saved_state
->err
;
403 exception
= EXC_BAD_ACCESS
;
409 exception
= EXC_SOFTWARE
;
410 code
= EXC_I386_ALIGNFLT
;
415 exception
= EXC_BREAKPOINT
;
416 code
= EXC_I386_BPTFLT
;
420 exception
= EXC_BAD_INSTRUCTION
;
425 // kdp_i386_backtrace((void *) saved_state->ebp, 10);
427 kdp_raise_exception(exception
, code
, subcode
, saved_state
);
439 unsigned int kdp_ml_get_breakinsn()