]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/seg.h
xnu-4570.1.46.tar.gz
[apple/xnu.git] / osfmk / i386 / seg.h
index 21c63306a8c8c2fdfc930ba0baf0729def7b090c..75f5182e08b30ef5320ba7c46bca64ecbdec24fa 100644 (file)
@@ -1,23 +1,29 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
  * any improvements or extensions that they make and grant Carnegie Mellon
  * the rights to redistribute these changes.
  */
-/*
- */
-
 #ifndef        _I386_SEG_H_
 #define        _I386_SEG_H_
-#include <mach_kdb.h>
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#include <mach/vm_types.h>
+#include <architecture/i386/sel.h>
 
 /*
  * i386 segmentation.
  */
 
-#ifndef        __ASSEMBLER__
+static inline uint16_t
+sel_to_selector(sel_t  sel)
+{
+    union {
+       sel_t           sel;
+       uint16_t        selector;
+    } tconv;
+    
+    tconv.sel = sel;
+    
+    return (tconv.selector);
+}
+
+static inline sel_t
+selector_to_sel(uint16_t selector)
+{
+    union {
+       uint16_t        selector;
+       sel_t           sel;
+    } tconv;
+    
+    tconv.selector = selector;
+    
+    return (tconv.sel);
+}
+
+#define LDTSZ          8192            /* size of the kernel ldt in entries */
+#define        LDTSZ_MIN       SEL_TO_INDEX(USER_SETTABLE)
+                                       /* kernel ldt entries */
+
+#define        GDTSZ           19
+
+/*
+ * Interrupt table is always 256 entries long.
+ */
+#define        IDTSZ           256
+
+#include <sys/cdefs.h>
+
 /*
  * Real segment descriptor.
  */
 struct real_descriptor {
-       unsigned int    limit_low:16,   /* limit 0..15 */
+       uint32_t        limit_low:16,   /* limit 0..15 */
                        base_low:16,    /* base  0..15 */
                        base_med:8,     /* base  16..23 */
                        access:8,       /* access byte */
@@ -71,14 +115,44 @@ struct real_descriptor {
                        granularity:4,  /* granularity */
                        base_high:8;    /* base 24..31 */
 };
-
+struct real_descriptor64 {
+       uint32_t        limit_low16:16, /* limit 0..15 */
+                       base_low16:16,  /* base  0..15 */
+                       base_med8:8,    /* base  16..23 */
+                       access8:8,      /* access byte */
+                       limit_high4:4,  /* limit 16..19 */
+                       granularity4:4, /* granularity */
+                       base_high8:8,   /* base 24..31 */
+                       base_top32:32,  /* base 32..63 */
+                       reserved32:32;  /* reserved/zero */
+};
 struct real_gate {
-       unsigned int    offset_low:16,  /* offset 0..15 */
+       uint32_t        offset_low:16,  /* offset 0..15 */
                        selector:16,
                        word_count:8,
                        access:8,
                        offset_high:16; /* offset 16..31 */
 };
+struct real_gate64 {
+       uint32_t        offset_low16:16,        /* offset 0..15 */
+                       selector16:16,
+                       IST:3,
+                       zeroes5:5,
+                       access8:8,
+                       offset_high16:16,       /* offset 16..31 */
+                       offset_top32:32,        /* offset 32..63 */
+                       reserved32:32;          /* reserved/zero */
+};
+
+#define MAKE_REAL_DESCRIPTOR(base,lim,gran,acc) { \
+       .limit_low = lim & 0xffff, \
+       .limit_high = (lim >> 16) & 0xf, \
+       .base_low = base & 0xffff, \
+       .base_med = (base >> 16) & 0xff, \
+       .base_high = (base >> 24) & 0xff, \
+       .access = acc, \
+       .granularity = gran \
+}
 
 /*
  * We build descriptors and gates in a 'fake' format to let the
@@ -86,15 +160,56 @@ struct real_gate {
  * at runtime.
  */
 struct fake_descriptor {
-       unsigned int    offset:32;              /* offset */
-       unsigned int    lim_or_seg:20;          /* limit */
+       uint32_t        offset:32;              /* offset */
+       uint32_t        lim_or_seg:20;          /* limit */
                                                /* or segment, for gate */
-       unsigned int    size_or_wdct:4;         /* size/granularity */
+       uint32_t        size_or_wdct:4;         /* size/granularity */
                                                /* word count, for gate */
-       unsigned int    access:8;               /* access */
+       uint32_t        access:8;               /* access */
 };
+struct fake_descriptor64 {
+       uint64_t        offset64;               /* offset [0..31,32..63] */
+       uint32_t        lim_or_seg:20;          /* limit */
+                                               /* or segment, for gate */
+       uint32_t        size_or_IST:4;          /* size/granularity */
+                                               /* IST for gates */
+       uint32_t        access:8;               /* access */
+       uint32_t        reserved:32;            /* reserved/zero */
+};
+
+typedef struct __attribute__((packed)) {
+       uint16_t        size;
+       void            *ptr;
+} x86_64_desc_register_t;
+
+/*
+ * Boot-time data for master (or only) CPU
+ */
+extern struct real_descriptor  master_gdt[GDTSZ];
+extern struct real_descriptor  master_ldt[LDTSZ];
+extern struct i386_tss         master_ktss;
+extern struct sysenter_stack   master_sstk;
+
+extern struct fake_descriptor64        master_idt64[IDTSZ];
+extern struct x86_64_tss       master_ktss64;
+
+__BEGIN_DECLS
+
+extern char                    df_task_stack[];
+extern char                    df_task_stack_end[];
+extern struct i386_tss         master_dftss;
+extern void                    df_task_start(void);
+
+extern char                    mc_task_stack[];
+extern char                    mc_task_stack_end[];
+extern struct i386_tss         master_mctss;
+extern void                    mc_task_start(void);
+
+__END_DECLS
+
 #endif /*__ASSEMBLER__*/
 
+#define        SZ_64           0x2                     /* 64-bit segment */
 #define        SZ_32           0x4                     /* 32-bit segment */
 #define        SZ_G            0x8                     /* 4K limit field */
 
@@ -141,65 +256,42 @@ struct fake_descriptor {
 /*
  * Convert selector to descriptor table index.
  */
-#define        sel_idx(sel)    ((sel)>>3)
+#define        sel_idx(sel)    (selector_to_sel(sel).index)
+#define SEL_TO_INDEX(s)        ((s)>>3)
 
-/*
- * User descriptors for MACH - 32-bit flat address space
- */
-#define        USER_SCALL      0x07            /* system call gate */
-#define        USER_RPC        0x0f            /* mach rpc call gate */
-#define        USER_CS         0x17            /* user code segment */
-#define        USER_DS         0x1f            /* user data segment */
+#define NULL_SEG       0
 
-#define        LDTSZ           4
 
 /*
- * Kernel descriptors for MACH - 32-bit flat address space.
+ * Kernel descriptors for MACH - 64-bit flat address space.
  */
-#define        KERNEL_CS       0x08            /* kernel code */
-#define        KERNEL_DS       0x10            /* kernel data */
-#define        KERNEL_LDT      0x18            /* master LDT */
-#define        KERNEL_TSS      0x20            /* master TSS (uniprocessor) */
-#ifdef MACH_BSD
-#define        BSD_SCALL_SEL   0x28            /* BSD System calls */
-#define        MK25_SCALL_SEL  0x30            /* MK25 System Calls */
-#define        MACHDEP_SCALL_SEL 0x38          /* Machdep SYstem calls */
-#else
-#define        USER_LDT        0x28            /* place for per-thread LDT */
-#define        USER_TSS        0x30            /* place for per-thread TSS
-                                          that holds IO bitmap */
-#define        FPE_CS          0x38            /* floating-point emulator code */
-#endif
-#define        USER_FPREGS     0x40            /* user-mode access to saved
-                                          floating-point registers */
-#define        CPU_DATA        0x48            /* per-cpu data */
-
-#ifdef MACH_BSD
-#define        USER_LDT        0x58
-#define        USER_TSS        0x60
-#define        FPE_CS          0x68
-#endif
+#define KERNEL64_CS    0x08            /* 1:  K64 code */
+#define SYSENTER_CS    0x0b            /*     U32 sysenter pseudo-segment */
+#define        KERNEL64_SS     0x10            /* 2:  KERNEL64_CS+8 for syscall */
+#define USER_CS                0x1b            /* 3:  U32 code */
+#define USER_DS                0x23            /* 4:  USER_CS+8 for sysret */
+#define USER64_CS      0x2b            /* 5:  USER_CS+16 for sysret */
+#define USER64_DS      USER_DS         /*     U64 data pseudo-segment */
+#define KERNEL_LDT     0x30            /* 6:  */
+                                       /* 7:  other 8 bytes of KERNEL_LDT */
+#define KERNEL_TSS     0x40            /* 8:  */
+                                       /* 9:  other 8 bytes of KERNEL_TSS */
+#define KERNEL32_CS    0x50            /* 10: */
+#define USER_LDT       0x58            /* 11: */
+                                       /* 12: other 8 bytes of USER_LDT */
+#define KERNEL_DS      0x68            /* 13: 32-bit kernel data */
 
-#if    MACH_KDB
-#define        DEBUG_TSS       0x50            /* debug TSS (uniprocessor) */
-
-#ifdef MACH_BSD
-#define        GDTSZ           14
-#else
-#define        GDTSZ           11
-#endif
-#else
 
-#ifdef MACH_BSD
-#define        GDTSZ           13
-#else
-#define        GDTSZ           10
-#endif
-#endif
+#define SYSENTER_TF_CS (USER_CS|0x10000)
+#define        SYSENTER_DS     KERNEL64_SS     /* sysenter kernel data segment */
 
+#ifdef __x86_64__
 /*
- * Interrupt table is always 256 entries long.
+ * 64-bit kernel LDT descriptors
  */
-#define        IDTSZ           256
+#define        SYSCALL_CS      0x07            /* syscall pseudo-segment */
+#define        USER_CTHREAD    0x0f            /* user cthread area */
+#define        USER_SETTABLE   0x1f            /* start of user settable ldt entries */
+#endif
 
 #endif /* _I386_SEG_H_ */