1/* 2 * Copyright (c) 2000-2012 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#ifndef _I386_SEG_H_ 57#define _I386_SEG_H_ 58#ifndef __ASSEMBLER__ 59#include <stdint.h> 60#include <mach/vm_types.h> 61#include <architecture/i386/sel.h> 62 63/* 64 * i386 segmentation. 65 */ 66 67static inline uint16_t 68sel_to_selector(sel_t sel) 69{ 70 union { 71 sel_t sel; 72 uint16_t selector; 73 } tconv; 74 75 tconv.sel = sel; 76 77 return (tconv.selector); 78} 79 80static inline sel_t 81selector_to_sel(uint16_t selector) 82{ 83 union { 84 uint16_t selector; 85 sel_t sel; 86 } tconv; 87 88 tconv.selector = selector; 89 90 return (tconv.sel); 91} 92 93#define LDTSZ 8192 /* size of the kernel ldt in entries */ 94#define LDTSZ_MIN SEL_TO_INDEX(USER_SETTABLE) 95 /* kernel ldt entries */ 96 97#define GDTSZ 19 98 99/* 100 * Interrupt table is always 256 entries long. 101 */ 102#define IDTSZ 256 103 104#include <sys/cdefs.h> 105 106/* 107 * Real segment descriptor. 108 */ 109struct real_descriptor { 110 uint32_t limit_low:16, /* limit 0..15 */ 111 base_low:16, /* base 0..15 */ 112 base_med:8, /* base 16..23 */ 113 access:8, /* access byte */ 114 limit_high:4, /* limit 16..19 */ 115 granularity:4, /* granularity */ 116 base_high:8; /* base 24..31 */ 117}; 118struct real_descriptor64 { 119 uint32_t limit_low16:16, /* limit 0..15 */ 120 base_low16:16, /* base 0..15 */ 121 base_med8:8, /* base 16..23 */ 122 access8:8, /* access byte */ 123 limit_high4:4, /* limit 16..19 */ 124 granularity4:4, /* granularity */ 125 base_high8:8, /* base 24..31 */ 126 base_top32:32, /* base 32..63 */ 127 reserved32:32; /* reserved/zero */ 128}; 129struct real_gate { 130 uint32_t offset_low:16, /* offset 0..15 */ 131 selector:16, 132 word_count:8, 133 access:8, 134 offset_high:16; /* offset 16..31 */ 135}; 136struct real_gate64 { 137 uint32_t offset_low16:16, /* offset 0..15 */ 138 selector16:16, 139 IST:3, 140 zeroes5:5, 141 access8:8, 142 offset_high16:16, /* offset 16..31 */ 143 offset_top32:32, /* offset 32..63 */ 144 reserved32:32; /* reserved/zero */ 145}; 146 147#define MAKE_REAL_DESCRIPTOR(base,lim,gran,acc) { \ 148 .limit_low = lim & 0xffff, \ 149 .limit_high = (lim >> 16) & 0xf, \ 150 .base_low = base & 0xffff, \ 151 .base_med = (base >> 16) & 0xff, \ 152 .base_high = (base >> 24) & 0xff, \ 153 .access = acc, \ 154 .granularity = gran \ 155} 156 157/* 158 * We build descriptors and gates in a 'fake' format to let the 159 * fields be contiguous. We shuffle them into the real format 160 * at runtime. 161 */ 162struct fake_descriptor { 163 uint32_t offset:32; /* offset */ 164 uint32_t lim_or_seg:20; /* limit */ 165 /* or segment, for gate */ 166 uint32_t size_or_wdct:4; /* size/granularity */ 167 /* word count, for gate */ 168 uint32_t access:8; /* access */ 169}; 170struct fake_descriptor64 { 171 uint64_t offset64; /* offset [0..31,32..63] */ 172 uint32_t lim_or_seg:20; /* limit */ 173 /* or segment, for gate */ 174 uint32_t size_or_IST:4; /* size/granularity */ 175 /* IST for gates */ 176 uint32_t access:8; /* access */ 177 uint32_t reserved:32; /* reserved/zero */ 178}; 179 180/* 181 * Boot-time data for master (or only) CPU 182 */ 183extern struct fake_descriptor master_idt[IDTSZ]; 184extern struct real_descriptor master_gdt[GDTSZ]; 185extern struct real_descriptor master_ldt[LDTSZ]; 186extern struct i386_tss master_ktss; 187extern struct sysenter_stack master_sstk; 188 189extern struct fake_descriptor64 master_idt64[IDTSZ]; 190extern struct x86_64_tss master_ktss64; 191 192__BEGIN_DECLS 193 194extern char df_task_stack[]; 195extern char df_task_stack_end[]; 196extern struct i386_tss master_dftss; 197extern void df_task_start(void); 198 199extern char mc_task_stack[]; 200extern char mc_task_stack_end[]; 201extern struct i386_tss master_mctss; 202extern void mc_task_start(void); 203 204__END_DECLS 205 206#endif /*__ASSEMBLER__*/ 207 208#define SZ_64 0x2 /* 64-bit segment */ 209#define SZ_32 0x4 /* 32-bit segment */ 210#define SZ_G 0x8 /* 4K limit field */ 211 212#define ACC_A 0x01 /* accessed */ 213#define ACC_TYPE 0x1e /* type field: */ 214 215#define ACC_TYPE_SYSTEM 0x00 /* system descriptors: */ 216 217#define ACC_LDT 0x02 /* LDT */ 218#define ACC_CALL_GATE_16 0x04 /* 16-bit call gate */ 219#define ACC_TASK_GATE 0x05 /* task gate */ 220#define ACC_TSS 0x09 /* task segment */ 221#define ACC_CALL_GATE 0x0c /* call gate */ 222#define ACC_INTR_GATE 0x0e /* interrupt gate */ 223#define ACC_TRAP_GATE 0x0f /* trap gate */ 224 225#define ACC_TSS_BUSY 0x02 /* task busy */ 226 227#define ACC_TYPE_USER 0x10 /* user descriptors */ 228 229#define ACC_DATA 0x10 /* data */ 230#define ACC_DATA_W 0x12 /* data, writable */ 231#define ACC_DATA_E 0x14 /* data, expand-down */ 232#define ACC_DATA_EW 0x16 /* data, expand-down, 233 writable */ 234#define ACC_CODE 0x18 /* code */ 235#define ACC_CODE_R 0x1a /* code, readable */ 236#define ACC_CODE_C 0x1c /* code, conforming */ 237#define ACC_CODE_CR 0x1e /* code, conforming, 238 readable */ 239#define ACC_PL 0x60 /* access rights: */ 240#define ACC_PL_K 0x00 /* kernel access only */ 241#define ACC_PL_U 0x60 /* user access */ 242#define ACC_P 0x80 /* segment present */ 243 244/* 245 * Components of a selector 246 */ 247#define SEL_LDTS 0x04 /* local selector */ 248#define SEL_PL 0x03 /* privilege level: */ 249#define SEL_PL_K 0x00 /* kernel selector */ 250#define SEL_PL_U 0x03 /* user selector */ 251 252/* 253 * Convert selector to descriptor table index. 254 */ 255#define sel_idx(sel) (selector_to_sel(sel).index) 256#define SEL_TO_INDEX(s) ((s)>>3) 257 258#define NULL_SEG 0 259 260 261/* 262 * Kernel descriptors for MACH - 64-bit flat address space. 263 */ 264#define KERNEL64_CS 0x08 /* 1: K64 code */ 265#define SYSENTER_CS 0x0b /* U32 sysenter pseudo-segment */ 266#define KERNEL64_SS 0x10 /* 2: KERNEL64_CS+8 for syscall */ 267#define USER_CS 0x1b /* 3: U32 code */ 268#define USER_DS 0x23 /* 4: USER_CS+8 for sysret */ 269#define USER64_CS 0x2b /* 5: USER_CS+16 for sysret */ 270#define USER64_DS USER_DS /* U64 data pseudo-segment */ 271#define KERNEL_LDT 0x30 /* 6: */ 272 /* 7: other 8 bytes of KERNEL_LDT */ 273#define KERNEL_TSS 0x40 /* 8: */ 274 /* 9: other 8 bytes of KERNEL_TSS */ 275#define KERNEL32_CS 0x50 /* 10: */ 276#define USER_LDT 0x58 /* 11: */ 277 /* 12: other 8 bytes of USER_LDT */ 278#define KERNEL_DS 0x68 /* 13: 32-bit kernel data */ 279 280 281#define SYSENTER_TF_CS (USER_CS|0x10000) 282#define SYSENTER_DS KERNEL64_SS /* sysenter kernel data segment */ 283 284#ifdef __x86_64__ 285/* 286 * 64-bit kernel LDT descriptors 287 */ 288#define SYSCALL_CS 0x07 /* syscall pseudo-segment */ 289#define USER_CTHREAD 0x0f /* user cthread area */ 290#define USER_SETTABLE 0x1f /* start of user settable ldt entries */ 291#endif 292 293#endif /* _I386_SEG_H_ */ 294