1/*
2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * @OSF_COPYRIGHT@
30 */
31/*
32 * Mach Operating System
33 * Copyright (c) 1991,1990 Carnegie Mellon University
34 * All Rights Reserved.
35 *
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.
41 *
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.
45 *
46 * Carnegie Mellon requests users of this software to return to
47 *
48 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
49 *  School of Computer Science
50 *  Carnegie Mellon University
51 *  Pittsburgh PA 15213-3890
52 *
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
55 */
56/*
57 */
58
59#ifndef	_I386_DB_MACHDEP_H_
60#define	_I386_DB_MACHDEP_H_
61
62/*
63 * Machine-dependent defines for new kernel debugger.
64 */
65
66#include <kern/kern_types.h>
67#include <mach/i386/vm_types.h>
68#include <mach/i386/vm_param.h>
69#include <i386/thread.h>		/* for thread_status */
70#include <i386/eflags.h>
71#include <i386/trap.h>
72#include <i386/pmCPU.h>
73
74typedef	addr64_t	db_addr_t;	/* address - unsigned */
75typedef	uint64_t	db_expr_t;	/* expression */
76
77typedef struct x86_saved_state32 db_regs_t;
78db_regs_t	ddb_regs;	/* register state */
79#define	DDB_REGS	(&ddb_regs)
80extern int	db_active;	/* ddb is active */
81
82#define	PC_REGS(regs)	((db_addr_t)(regs)->eip)
83
84#define	BKPT_INST	0xcc		/* breakpoint instruction */
85#define	BKPT_SIZE	(1)		/* size of breakpoint inst */
86#define	BKPT_SET(inst)	(BKPT_INST)
87
88#define	FIXUP_PC_AFTER_BREAK	ddb_regs.eip -= 1;
89
90#define	db_clear_single_step(regs)	((regs)->efl &= ~EFL_TF)
91#define	db_set_single_step(regs)	((regs)->efl |=  EFL_TF)
92
93#define	IS_BREAKPOINT_TRAP(type, code)	((type) == T_INT3)
94#define IS_WATCHPOINT_TRAP(type, code)	((type) == T_WATCHPOINT)
95
96#define	I_CALL		0xe8
97#define	I_CALLI		0xff
98#define	I_RET		0xc3
99#define	I_IRET		0xcf
100
101#define	inst_trap_return(ins)	(((ins)&0xff) == I_IRET)
102#define	inst_return(ins)	(((ins)&0xff) == I_RET)
103#define	inst_call(ins)		(((ins)&0xff) == I_CALL || \
104				 (((ins)&0xff) == I_CALLI && \
105				  ((ins)&0x3800) == 0x1000))
106
107int db_inst_load(unsigned long);
108int db_inst_store(unsigned long);
109
110/* access capability and access macros */
111
112#define DB_ACCESS_LEVEL		2	/* access any space */
113#define DB_CHECK_ACCESS(addr,size,task)				\
114	db_check_access(addr,size,task)
115#define DB_PHYS_EQ(task1,addr1,task2,addr2)			\
116	db_phys_eq(task1,addr1,task2,addr2)
117#define DB_VALID_KERN_ADDR(addr)		(1)
118#define DB_VALID_ADDRESS(addr,user)				\
119	((!(user) && DB_VALID_KERN_ADDR(addr)) ||		\
120	 ((user) && (addr) < VM_MAX_ADDRESS))
121
122/*
123 * Given pointer to i386_saved_state, determine if it represents
124 * a thread executing in user space.
125 */
126#define IS_USER_TRAP(regs, etext)	(((regs)->cs & 3) != 0)
127
128extern boolean_t	db_check_access(
129				vm_offset_t	addr,
130				int		size,
131				task_t		task);
132extern boolean_t	db_phys_eq(
133				task_t		task1,
134				vm_offset_t	addr1,
135				task_t		task2,
136				vm_offset_t	addr2);
137extern db_addr_t	db_disasm(
138				db_addr_t	loc,
139				boolean_t	altfmt,
140				task_t		task);
141extern void		db_read_bytes(
142				vm_offset_t	addr,
143				int		size,
144				char		*data,
145				task_t		task);
146extern void		db_write_bytes(
147				vm_offset_t	addr,
148				int		size,
149				char		*data,
150				task_t		task);
151extern void		db_stack_trace_cmd(
152				db_expr_t	addr,
153				boolean_t	have_addr,
154				db_expr_t	count,
155				char		*modif);
156extern void		db_reboot(
157				db_expr_t	addr,
158				boolean_t	have_addr,
159				db_expr_t	count,
160				char		*modif);
161
162extern void db_display_kmod(db_expr_t addr, boolean_t have_addr,
163			    db_expr_t count, char *modif);
164extern void db_display_real(db_expr_t addr, boolean_t have_addr,
165			    db_expr_t count, char *modif);
166extern void db_display_iokit(db_expr_t addr, boolean_t have_addr,
167			     db_expr_t count, char * modif);
168extern void db_cpuid(db_expr_t addr, boolean_t have_addr, db_expr_t count,
169		     char *modif);
170extern void db_msr(db_expr_t addr, boolean_t have_addr, db_expr_t count,
171		   char *modif);
172extern void db_apic(db_expr_t addr, boolean_t have_addr, db_expr_t count,
173		    char *modif);
174
175/* macros for printing OS server dependent task name */
176
177#define DB_TASK_NAME(task)	db_task_name(task)
178#define DB_TASK_NAME_TITLE	"COMMAND                "
179#define DB_TASK_NAME_LEN	23
180#define DB_NULL_TASK_NAME	"?                      "
181
182extern void		db_task_name(
183				task_t			task);
184
185/* macro for checking if a thread has used floating-point */
186
187#define db_act_fp_used(act)	(act && act->machine.pcb->ifps)
188
189extern void		db_tss_to_frame(
190				int			tss_sel,
191				x86_saved_state32_t	*regs);
192extern int		kdb_trap(
193				int			type,
194				int			code,
195				x86_saved_state32_t	*regs);
196extern boolean_t	db_trap_from_asm(
197				x86_saved_state32_t *regs);
198extern void		kdb_on(
199				int			cpu);
200
201#if MACH_KDB
202extern void db_chkpmgr(void);
203#endif /* MACH_KDB */
204extern void db_pmgr(db_expr_t addr, int have_addr, db_expr_t count, char * modif);
205extern void db_nap(db_expr_t addr, int have_addr, db_expr_t count, char * modif);
206
207#endif	/* _I386_DB_MACHDEP_H_ */
208