]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/seg.h
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / i386 / seg.h
index 3afe55d5daf449be3f6be2c47fa312467894ab42..eed66408bc068c6cfdd89aba162914720967dd09 100644 (file)
@@ -1,17 +1,20 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
  * 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. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
+ * 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.
+ *
+ * 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,
  * 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@
  */
-/* 
+/*
  * Mach Operating System
  * Copyright (c) 1991,1990 Carnegie Mellon University
  * All Rights Reserved.
- * 
+ *
  * Permission to use, copy, modify and distribute this software and its
  * documentation is hereby granted, provided that both the copyright
  * notice and this permission notice appear in all copies of the
  * software, derivative works or modified versions, and any portions
  * thereof, and that both notices appear in supporting documentation.
- * 
+ *
  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
+ *
  * Carnegie Mellon requests users of this software to return to
- * 
+ *
  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  *  School of Computer Science
  *  Carnegie Mellon University
  *  Pittsburgh PA 15213-3890
- * 
+ *
  * 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_
+#ifndef __ASSEMBLER__
+#include <stdint.h>
+#include <mach/vm_types.h>
+#include <mach/vm_param.h>
+#include <architecture/i386/sel.h>
+
 /*
+ * i386 segmentation.
  */
 
-#ifndef        _I386_SEG_H_
-#define        _I386_SEG_H_
-#include <mach_kdb.h>
+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_MAX       8192    /* maximal size of the kernel ldt in entries */
+#define LDTSZ_DFL       (128)
+#define LDTSZ           (LDTSZ_MAX)
+#define LDTSZ_MIN       SEL_TO_INDEX(USER_SETTABLE)
+/* kernel ldt entries */
+
+#define GDTSZ           19
 
 /*
- * i386 segmentation.
+ * Interrupt table is always 256 entries long.
  */
+#define IDTSZ           256
+
+#include <sys/cdefs.h>
 
-#ifndef        __ASSEMBLER__
 /*
  * Real segment descriptor.
  */
 struct real_descriptor {
-       unsigned int    limit_low:16,   /* limit 0..15 */
-                       base_low:16,    /* base  0..15 */
-                       base_med:8,     /* base  16..23 */
-                       access:8,       /* access byte */
-                       limit_high:4,   /* limit 16..19 */
-                       granularity:4,  /* granularity */
-                       base_high:8;    /* base 24..31 */
+       uint32_t        limit_low:16,   /* limit 0..15 */
+           base_low:16,                /* base  0..15 */
+           base_med:8,                 /* base  16..23 */
+           access:8,                   /* access byte */
+           limit_high:4,               /* limit 16..19 */
+           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 */
-                       selector:16,
-                       word_count:8,
-                       access:8,
-                       offset_high:16; /* offset 16..31 */
+       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
@@ -89,120 +163,139 @@ struct real_gate {
  * at runtime.
  */
 struct fake_descriptor {
-       unsigned int    offset:32;              /* offset */
-       unsigned int    lim_or_seg:20;          /* limit */
-                                               /* or segment, for gate */
-       unsigned int    size_or_wdct:4;         /* size/granularity */
-                                               /* word count, for gate */
-       unsigned int    access:8;               /* access */
+       uint32_t        offset:32;              /* offset */
+       uint32_t        lim_or_seg:20;          /* limit */
+                                               /* or segment, for gate */
+       uint32_t        size_or_wdct:4;         /* size/granularity */
+                                               /* word count, for gate */
+       uint32_t        access:8;               /* access */
 };
-#endif /*__ASSEMBLER__*/
-
-#define        SZ_32           0x4                     /* 32-bit segment */
-#define        SZ_G            0x8                     /* 4K limit field */
-
-#define        ACC_A           0x01                    /* accessed */
-#define        ACC_TYPE        0x1e                    /* type field: */
-
-#define        ACC_TYPE_SYSTEM 0x00                    /* system descriptors: */
-
-#define        ACC_LDT         0x02                        /* LDT */
-#define        ACC_CALL_GATE_16 0x04                       /* 16-bit call gate */
-#define        ACC_TASK_GATE   0x05                        /* task gate */
-#define        ACC_TSS         0x09                        /* task segment */
-#define        ACC_CALL_GATE   0x0c                        /* call gate */
-#define        ACC_INTR_GATE   0x0e                        /* interrupt gate */
-#define        ACC_TRAP_GATE   0x0f                        /* trap gate */
-
-#define        ACC_TSS_BUSY    0x02                        /* task busy */
-
-#define        ACC_TYPE_USER   0x10                    /* user descriptors */
-
-#define        ACC_DATA        0x10                        /* data */
-#define        ACC_DATA_W      0x12                        /* data, writable */
-#define        ACC_DATA_E      0x14                        /* data, expand-down */
-#define        ACC_DATA_EW     0x16                        /* data, expand-down,
-                                                            writable */
-#define        ACC_CODE        0x18                        /* code */
-#define        ACC_CODE_R      0x1a                        /* code, readable */
-#define        ACC_CODE_C      0x1c                        /* code, conforming */
-#define        ACC_CODE_CR     0x1e                        /* code, conforming,
-                                                      readable */
-#define        ACC_PL          0x60                    /* access rights: */
-#define        ACC_PL_K        0x00                    /* kernel access only */
-#define        ACC_PL_U        0x60                    /* user access */
-#define        ACC_P           0x80                    /* segment present */
+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;
+
+
 
 /*
- * Components of a selector
+ * Boot-time data for master (or only) CPU
  */
-#define        SEL_LDTS        0x04                    /* local selector */
-#define        SEL_PL          0x03                    /* privilege level: */
-#define        SEL_PL_K        0x00                        /* kernel selector */
-#define        SEL_PL_U        0x03                        /* user selector */
+extern struct real_descriptor   master_gdt[GDTSZ];
+extern struct real_descriptor   master_ldt[];
+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 */
+
+#define ACC_A           0x01                    /* accessed */
+#define ACC_TYPE        0x1e                    /* type field: */
+
+#define ACC_TYPE_SYSTEM 0x00                    /* system descriptors: */
+
+#define ACC_LDT         0x02                        /* LDT */
+#define ACC_CALL_GATE_16 0x04                       /* 16-bit call gate */
+#define ACC_TASK_GATE   0x05                        /* task gate */
+#define ACC_TSS         0x09                        /* task segment */
+#define ACC_CALL_GATE   0x0c                        /* call gate */
+#define ACC_INTR_GATE   0x0e                        /* interrupt gate */
+#define ACC_TRAP_GATE   0x0f                        /* trap gate */
+
+#define ACC_TSS_BUSY    0x02                        /* task busy */
+
+#define ACC_TYPE_USER   0x10                    /* user descriptors */
+
+#define ACC_DATA        0x10                        /* data */
+#define ACC_DATA_W      0x12                        /* data, writable */
+#define ACC_DATA_E      0x14                        /* data, expand-down */
+#define ACC_DATA_EW     0x16                        /* data, expand-down,
+                                                    *        writable */
+#define ACC_CODE        0x18                        /* code */
+#define ACC_CODE_R      0x1a                        /* code, readable */
+#define ACC_CODE_C      0x1c                        /* code, conforming */
+#define ACC_CODE_CR     0x1e                        /* code, conforming,
+                                                    *  readable */
+#define ACC_PL          0x60                    /* access rights: */
+#define ACC_PL_K        0x00                    /* kernel access only */
+#define ACC_PL_U        0x60                    /* user access */
+#define ACC_P           0x80                    /* segment present */
 
 /*
- * Convert selector to descriptor table index.
+ * Components of a selector
  */
-#define        sel_idx(sel)    ((sel)>>3)
+#define SEL_LDTS        0x04                    /* local selector */
+#define SEL_PL          0x03                    /* privilege level: */
+#define SEL_PL_K        0x00                        /* kernel selector */
+#define SEL_PL_U        0x03                        /* user selector */
 
 /*
- * User descriptors for MACH - 32-bit flat address space
+ * Convert selector to descriptor table index.
  */
-#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 sel_idx(sel)    (selector_to_sel(sel).index)
+#define SEL_TO_INDEX(s) ((s)>>3)
+
+#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 */
 
+#endif  /* _I386_SEG_H_ */
+#ifdef __x86_64__
 /*
- * Interrupt table is always 256 entries long.
+ * 64-bit kernel LDT descriptors
  */
-#define        IDTSZ           256
-
-#endif /* _I386_SEG_H_ */
+#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