1/* 2 * Copyright (c) 2000-2010 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,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/* 60 * File: machine/thread.h 61 * 62 * This file contains the structure definitions for the thread 63 * state as applied to I386 processors. 64 */ 65 66#ifndef _I386_THREAD_H_ 67#define _I386_THREAD_H_ 68 69#include <mach/boolean.h> 70#include <mach/i386/vm_types.h> 71#include <mach/i386/fp_reg.h> 72#include <mach/thread_status.h> 73 74#include <kern/lock.h> 75 76#include <i386/iopb.h> 77#include <i386/seg.h> 78#include <i386/tss.h> 79#include <i386/eflags.h> 80 81#include <i386/cpu_data.h> 82 83#include <machine/pal_routines.h> 84 85/* 86 * x86_kernel_state: 87 * 88 * This structure corresponds to the state of kernel registers 89 * as saved in a context-switch. It lives at the base of the stack. 90 */ 91 92#ifdef __i386__ 93struct x86_kernel_state { 94 uint32_t k_ebx; /* kernel context */ 95 uint32_t k_esp; 96 uint32_t k_ebp; 97 uint32_t k_edi; 98 uint32_t k_esi; 99 uint32_t k_eip; 100 /* 101 * Kernel stacks are 16-byte aligned with x86_kernel_state at the top, 102 * so we need a couple of dummy 32-bit words here. 103 */ 104 uint32_t dummy[2]; 105}; 106#else 107struct x86_kernel_state { 108 uint64_t k_rbx; /* kernel context */ 109 uint64_t k_rsp; 110 uint64_t k_rbp; 111 uint64_t k_r12; 112 uint64_t k_r13; 113 uint64_t k_r14; 114 uint64_t k_r15; 115 uint64_t k_rip; 116}; 117#endif 118 119/* 120 * Maps state flavor to number of words in the state: 121 */ 122__private_extern__ unsigned int _MachineStateCount[]; 123 124/* 125 * The machine-dependent thread state - registers and all platform-dependent 126 * state - is saved in the machine thread structure which is embedded in 127 * the thread data structure. For historical reasons this is also referred to 128 * as the PCB. 129 */ 130struct machine_thread { 131 void *sf; 132 x86_saved_state_t *iss; 133 void *ifps; 134 void *ids; 135 decl_simple_lock_data(,lock); /* protects ifps and ids */ 136 uint64_t iss_pte0; 137 uint64_t iss_pte1; 138 uint32_t arg_store_valid; 139#ifdef MACH_BSD 140 uint64_t cthread_self; /* for use of cthread package */ 141 struct real_descriptor cthread_desc; 142 unsigned long uldt_selector; /* user ldt selector to set */ 143 struct real_descriptor uldt_desc; /* actual user setable ldt */ 144#endif 145 146 struct pal_pcb pal_pcb; 147 148 uint32_t specFlags; 149#define OnProc 0x1 150#define CopyIOActive 0x2 /* Checked to ensure DTrace actions do not re-enter copyio(). */ 151 152#if NCOPY_WINDOWS > 0 153 struct { 154 user_addr_t user_base; 155 } copy_window[NCOPY_WINDOWS]; 156 int nxt_window; 157 int copyio_state; 158#define WINDOWS_DIRTY 0 159#define WINDOWS_CLEAN 1 160#define WINDOWS_CLOSED 2 161#define WINDOWS_OPENED 3 162 uint64_t physwindow_pte; 163 int physwindow_busy; 164#endif 165}; 166typedef struct machine_thread *pcb_t; 167 168#define THREAD_TO_PCB(Thr) (&(Thr)->machine) 169 170#define USER_STATE(Thr) ((Thr)->machine.iss) 171#define USER_REGS32(Thr) (saved_state32(USER_STATE(Thr))) 172#define USER_REGS64(Thr) (saved_state64(USER_STATE(Thr))) 173 174#define user_pc(Thr) (is_saved_state32(USER_STATE(Thr)) ? \ 175 USER_REGS32(Thr)->eip : \ 176 USER_REGS64(Thr)->isf.rip ) 177 178extern void *get_user_regs(thread_t); 179 180extern void *act_thread_csave(void); 181extern void act_thread_catt(void *ctx); 182extern void act_thread_cfree(void *ctx); 183 184 185/* 186 * On the kernel stack is: 187 * stack: ... 188 * struct x86_kernel_state 189 * stack+kernel_stack_size 190 */ 191 192#define STACK_IKS(stack) \ 193 ((struct x86_kernel_state *)((stack) + kernel_stack_size) - 1) 194 195/* 196 * Return the current stack depth including x86_kernel_state 197 */ 198static inline vm_offset_t 199current_stack_depth(void) 200{ 201 vm_offset_t stack_ptr; 202 203 assert(get_preemption_level() > 0 || !ml_get_interrupts_enabled()); 204 205#if defined(__x86_64__) 206 __asm__ volatile("mov %%rsp, %0" : "=m" (stack_ptr)); 207#else 208 __asm__ volatile("mov %%esp, %0" : "=m" (stack_ptr)); 209#endif 210 return (current_cpu_datap()->cpu_kernel_stack 211 + sizeof(struct x86_kernel_state) 212 - stack_ptr); 213} 214 215/* 216 * Return address of the function that called current function, given 217 * address of the first parameter of current function. 218 */ 219#define GET_RETURN_PC(addr) (__builtin_return_address(0)) 220 221#endif /* _I386_THREAD_H_ */ 222