1/*
2 * Copyright (c) 2000-2006 Apple Computer, 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,1989 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 *	File:	thread_status.h
60 *	Author:	Avadis Tevanian, Jr.
61 *	Date:	1985
62 *
63 *	This file contains the structure definitions for the thread
64 *	state as applied to I386 processors.
65 */
66
67#ifndef	_MACH_I386_THREAD_STATUS_H_
68#define _MACH_I386_THREAD_STATUS_H_
69
70#include <mach/i386/_structs.h>
71#include <mach/message.h>
72#include <mach/i386/fp_reg.h>
73#include <mach/i386/thread_state.h>
74#include <i386/eflags.h>
75
76/*
77 * the i386_xxxx form is kept for legacy purposes since these types
78 * are externally known... eventually they should be deprecated.
79 * our internal implementation has moved to the following naming convention
80 *
81 *   x86_xxxx32 names are used to deal with 32 bit states
82 *   x86_xxxx64 names are used to deal with 64 bit states
83 *   x86_xxxx   names are used to deal with either 32 or 64 bit states
84 *	via a self-describing mechanism
85 */
86
87/*
88 * these are the legacy names which should be deprecated in the future
89 * they are externally known which is the only reason we don't just get
90 * rid of them
91 */
92#define i386_THREAD_STATE		1
93#define i386_FLOAT_STATE		2
94#define i386_EXCEPTION_STATE		3
95
96/*
97 * THREAD_STATE_FLAVOR_LIST 0
98 * 	these are the supported flavors
99 */
100#define x86_THREAD_STATE32		1
101#define x86_FLOAT_STATE32		2
102#define x86_EXCEPTION_STATE32		3
103#define x86_THREAD_STATE64		4
104#define x86_FLOAT_STATE64		5
105#define x86_EXCEPTION_STATE64		6
106#define x86_THREAD_STATE		7
107#define x86_FLOAT_STATE			8
108#define x86_EXCEPTION_STATE		9
109#define x86_DEBUG_STATE32		10
110#define x86_DEBUG_STATE64		11
111#define x86_DEBUG_STATE			12
112#define THREAD_STATE_NONE		13
113/* 14 and 15 are used for the internal x86_SAVED_STATE flavours */
114#define x86_AVX_STATE32			16
115#define x86_AVX_STATE64			17
116#define x86_AVX_STATE			18
117
118
119/*
120 * Largest state on this machine:
121 * (be sure mach/machine/thread_state.h matches!)
122 */
123#define THREAD_MACHINE_STATE_MAX	THREAD_STATE_MAX
124
125/*
126 * VALID_THREAD_STATE_FLAVOR is a platform specific macro that when passed
127 * an exception flavor will return if that is a defined flavor for that
128 * platform. The macro must be manually updated to include all of the valid
129 * exception flavors as defined above.
130 */
131#define VALID_THREAD_STATE_FLAVOR(x)       \
132	 ((x == x86_THREAD_STATE32)	|| \
133	  (x == x86_FLOAT_STATE32)	|| \
134	  (x == x86_EXCEPTION_STATE32)	|| \
135	  (x == x86_DEBUG_STATE32)	|| \
136	  (x == x86_THREAD_STATE64)	|| \
137	  (x == x86_FLOAT_STATE64)	|| \
138	  (x == x86_EXCEPTION_STATE64)	|| \
139	  (x == x86_DEBUG_STATE64)	|| \
140	  (x == x86_THREAD_STATE)	|| \
141	  (x == x86_FLOAT_STATE)	|| \
142	  (x == x86_EXCEPTION_STATE)	|| \
143	  (x == x86_DEBUG_STATE)	|| \
144	  (x == x86_AVX_STATE32)	|| \
145	  (x == x86_AVX_STATE64)	|| \
146	  (x == x86_AVX_STATE)		|| \
147	  (x == THREAD_STATE_NONE))
148
149struct x86_state_hdr {
150	int	flavor;
151	int	count;
152};
153typedef struct x86_state_hdr x86_state_hdr_t;
154
155/*
156 * Default segment register values.
157 */
158
159#define USER_CODE_SELECTOR	0x0017
160#define USER_DATA_SELECTOR	0x001f
161#define KERN_CODE_SELECTOR	0x0008
162#define KERN_DATA_SELECTOR	0x0010
163
164/*
165 * to be deprecated in the future
166 */
167typedef _STRUCT_X86_THREAD_STATE32 i386_thread_state_t;
168#define i386_THREAD_STATE_COUNT	((mach_msg_type_number_t) \
169    ( sizeof (i386_thread_state_t) / sizeof (int) ))
170
171typedef _STRUCT_X86_THREAD_STATE32 x86_thread_state32_t;
172#define x86_THREAD_STATE32_COUNT	((mach_msg_type_number_t) \
173    ( sizeof (x86_thread_state32_t) / sizeof (int) ))
174
175/*
176 * to be deprecated in the future
177 */
178typedef _STRUCT_X86_FLOAT_STATE32 i386_float_state_t;
179#define i386_FLOAT_STATE_COUNT ((mach_msg_type_number_t) \
180		(sizeof(i386_float_state_t)/sizeof(unsigned int)))
181
182typedef _STRUCT_X86_FLOAT_STATE32 x86_float_state32_t;
183#define x86_FLOAT_STATE32_COUNT ((mach_msg_type_number_t) \
184		(sizeof(x86_float_state32_t)/sizeof(unsigned int)))
185
186typedef _STRUCT_X86_AVX_STATE32 x86_avx_state32_t;
187#define x86_AVX_STATE32_COUNT ((mach_msg_type_number_t) \
188		(sizeof(x86_avx_state32_t)/sizeof(unsigned int)))
189
190/*
191 * to be deprecated in the future
192 */
193typedef _STRUCT_X86_EXCEPTION_STATE32 i386_exception_state_t;
194#define i386_EXCEPTION_STATE_COUNT	((mach_msg_type_number_t) \
195    ( sizeof (i386_exception_state_t) / sizeof (int) ))
196
197typedef _STRUCT_X86_EXCEPTION_STATE32 x86_exception_state32_t;
198#define x86_EXCEPTION_STATE32_COUNT	((mach_msg_type_number_t) \
199    ( sizeof (x86_exception_state32_t) / sizeof (int) ))
200
201#define I386_EXCEPTION_STATE_COUNT i386_EXCEPTION_STATE_COUNT
202
203typedef _STRUCT_X86_DEBUG_STATE32 x86_debug_state32_t;
204#define x86_DEBUG_STATE32_COUNT       ((mach_msg_type_number_t) \
205	( sizeof (x86_debug_state32_t) / sizeof (int) ))
206
207#define X86_DEBUG_STATE32_COUNT x86_DEBUG_STATE32_COUNT
208
209typedef _STRUCT_X86_THREAD_STATE64 x86_thread_state64_t;
210#define x86_THREAD_STATE64_COUNT	((mach_msg_type_number_t) \
211    ( sizeof (x86_thread_state64_t) / sizeof (int) ))
212
213typedef _STRUCT_X86_FLOAT_STATE64 x86_float_state64_t;
214#define x86_FLOAT_STATE64_COUNT ((mach_msg_type_number_t) \
215		(sizeof(x86_float_state64_t)/sizeof(unsigned int)))
216
217typedef _STRUCT_X86_AVX_STATE64 x86_avx_state64_t;
218#define x86_AVX_STATE64_COUNT ((mach_msg_type_number_t) \
219		(sizeof(x86_avx_state64_t)/sizeof(unsigned int)))
220
221typedef _STRUCT_X86_EXCEPTION_STATE64 x86_exception_state64_t;
222#define x86_EXCEPTION_STATE64_COUNT	((mach_msg_type_number_t) \
223    ( sizeof (x86_exception_state64_t) / sizeof (int) ))
224
225#define X86_EXCEPTION_STATE64_COUNT x86_EXCEPTION_STATE64_COUNT
226
227typedef _STRUCT_X86_DEBUG_STATE64 x86_debug_state64_t;
228#define x86_DEBUG_STATE64_COUNT	((mach_msg_type_number_t) \
229    ( sizeof (x86_debug_state64_t) / sizeof (int) ))
230
231#define X86_DEBUG_STATE64_COUNT x86_DEBUG_STATE64_COUNT
232
233/*
234 * Combined thread, float and exception states
235 */
236struct x86_thread_state {
237	x86_state_hdr_t			tsh;
238	union {
239	    x86_thread_state32_t	ts32;
240	    x86_thread_state64_t	ts64;
241	} uts;
242};
243
244struct x86_float_state {
245	x86_state_hdr_t			fsh;
246	union {
247		x86_float_state32_t	fs32;
248		x86_float_state64_t	fs64;
249	} ufs;
250};
251
252struct x86_exception_state {
253	x86_state_hdr_t			esh;
254	union {
255		x86_exception_state32_t	es32;
256		x86_exception_state64_t	es64;
257	} ues;
258};
259
260struct x86_debug_state {
261	x86_state_hdr_t			dsh;
262	union {
263		x86_debug_state32_t	ds32;
264		x86_debug_state64_t	ds64;
265	} uds;
266};
267
268struct x86_avx_state {
269	x86_state_hdr_t			ash;
270	union {
271		x86_avx_state32_t	as32;
272		x86_avx_state64_t	as64;
273	} ufs;
274};
275
276typedef struct x86_thread_state x86_thread_state_t;
277#define x86_THREAD_STATE_COUNT	((mach_msg_type_number_t) \
278		( sizeof (x86_thread_state_t) / sizeof (int) ))
279
280typedef struct x86_float_state x86_float_state_t;
281#define x86_FLOAT_STATE_COUNT ((mach_msg_type_number_t) \
282		(sizeof(x86_float_state_t)/sizeof(unsigned int)))
283
284typedef struct x86_exception_state x86_exception_state_t;
285#define x86_EXCEPTION_STATE_COUNT ((mach_msg_type_number_t) \
286		(sizeof(x86_exception_state_t)/sizeof(unsigned int)))
287
288typedef struct x86_debug_state x86_debug_state_t;
289#define x86_DEBUG_STATE_COUNT ((mach_msg_type_number_t) \
290		(sizeof(x86_debug_state_t)/sizeof(unsigned int)))
291
292typedef struct x86_avx_state x86_avx_state_t;
293#define x86_AVX_STATE_COUNT ((mach_msg_type_number_t) \
294		(sizeof(x86_avx_state_t)/sizeof(unsigned int)))
295
296/*
297 * Machine-independent way for servers and Mach's exception mechanism to
298 * choose the most efficient state flavor for exception RPC's:
299 */
300#define MACHINE_THREAD_STATE		x86_THREAD_STATE
301#define MACHINE_THREAD_STATE_COUNT	x86_THREAD_STATE_COUNT
302
303#ifdef XNU_KERNEL_PRIVATE
304
305#define x86_SAVED_STATE32		THREAD_STATE_NONE + 1
306#define x86_SAVED_STATE64		THREAD_STATE_NONE + 2
307
308/*
309 * The format in which thread state is saved by Mach on this machine.  This
310 * state flavor is most efficient for exception RPC's to kernel-loaded
311 * servers, because copying can be avoided:
312 */
313struct x86_saved_state32 {
314	uint32_t	gs;
315	uint32_t	fs;
316	uint32_t	es;
317	uint32_t	ds;
318	uint32_t	edi;
319	uint32_t	esi;
320	uint32_t	ebp;
321	uint32_t	cr2;	/* kernel esp stored by pusha - we save cr2 here later */
322	uint32_t	ebx;
323	uint32_t	edx;
324	uint32_t	ecx;
325	uint32_t	eax;
326	uint16_t	trapno;
327	uint16_t	cpu;
328	uint32_t	err;
329	uint32_t	eip;
330	uint32_t	cs;
331	uint32_t	efl;
332	uint32_t	uesp;
333	uint32_t	ss;
334};
335typedef struct x86_saved_state32 x86_saved_state32_t;
336
337#define x86_SAVED_STATE32_COUNT	((mach_msg_type_number_t) \
338	(sizeof (x86_saved_state32_t)/sizeof(unsigned int)))
339
340#pragma pack(4)
341
342/*
343 * This is the state pushed onto the 64-bit interrupt stack
344 * on any exception/trap/interrupt.
345 */
346struct x86_64_intr_stack_frame {
347	uint16_t	trapno;
348	uint16_t	cpu;
349	uint32_t 	_pad;
350	uint64_t	trapfn;
351	uint64_t	err;
352	uint64_t	rip;
353	uint64_t	cs;
354	uint64_t	rflags;
355	uint64_t	rsp;
356	uint64_t	ss;
357};
358typedef struct x86_64_intr_stack_frame x86_64_intr_stack_frame_t;
359/* Note: sizeof(x86_64_intr_stack_frame_t) must be a multiple of 16 bytes */
360
361/*
362 * thread state format for task running in 64bit long mode
363 * in long mode, the same hardware frame is always pushed regardless
364 * of whether there was a change in privlege level... therefore, there
365 * is no need for an x86_saved_state64_from_kernel variant
366 */
367struct x86_saved_state64 {
368        /*
369	 * saved state organized to reflect the
370	 * system call ABI register convention
371	 * so that we can just pass a pointer
372	 * to the saved state when calling through
373	 * to the actual system call functions
374	 * the ABI limits us to 6 args passed in
375	 * registers... I've add v_arg6 - v_arg8
376	 * to accomodate our most 'greedy' system
377	 * calls (both BSD and MACH)... the individual
378	 * system call handlers will fill these in
379	 * via copyin if needed...
380	 */
381	uint64_t	rdi;		/* arg0 for system call */
382	uint64_t	rsi;
383	uint64_t	rdx;
384	uint64_t	r10;		/* R10 := RCX prior to syscall trap */
385	uint64_t	r8;
386	uint64_t	r9;		/* arg5 for system call */
387	uint64_t	v_arg6;
388	uint64_t	v_arg7;
389	uint64_t	v_arg8;
390
391        uint64_t	cr2;
392        uint64_t	r15;
393        uint64_t	r14;
394        uint64_t	r13;
395        uint64_t	r12;
396        uint64_t	r11;
397	uint64_t	rbp;
398	uint64_t	rbx;
399	uint64_t	rcx;
400	uint64_t	rax;
401
402	uint32_t	gs;
403	uint32_t	fs;
404
405	struct	x86_64_intr_stack_frame	isf;
406};
407typedef struct x86_saved_state64 x86_saved_state64_t;
408#define x86_SAVED_STATE64_COUNT	((mach_msg_type_number_t) \
409	(sizeof (struct x86_saved_state64)/sizeof(unsigned int)))
410
411extern uint32_t get_eflags_exportmask(void);
412
413/*
414 * Unified, tagged saved state:
415 */
416typedef struct {
417	uint32_t			flavor;
418	uint32_t			_pad_for_16byte_alignment[3];
419	union {
420		x86_saved_state32_t	ss_32;
421		x86_saved_state64_t	ss_64;
422	} uss;
423} x86_saved_state_t;
424#define	ss_32	uss.ss_32
425#define	ss_64	uss.ss_64
426#pragma pack()
427
428static inline boolean_t
429is_saved_state64(x86_saved_state_t *iss)
430{
431	return (iss->flavor == x86_SAVED_STATE64);
432}
433
434static inline boolean_t
435is_saved_state32(x86_saved_state_t *iss)
436{
437	return (iss->flavor == x86_SAVED_STATE32);
438}
439
440static inline x86_saved_state32_t *
441saved_state32(x86_saved_state_t *iss)
442{
443	return &iss->ss_32;
444}
445
446static inline x86_saved_state64_t *
447saved_state64(x86_saved_state_t *iss)
448{
449	return &iss->ss_64;
450}
451
452#endif /* XNU_KERNEL_PRIVATE */
453
454#endif	/* _MACH_I386_THREAD_STATUS_H_ */
455