1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #ifndef _SYS_MACHPRIVREGS_H
  28 #define _SYS_MACHPRIVREGS_H
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 /*
  33  * Platform dependent instruction sequences for manipulating
  34  * privileged state
  35  */
  36 
  37 #ifdef __cplusplus
  38 extern "C" {
  39 #endif
  40 
  41 #define ASSERT_UPCALL_MASK_IS_SET               /* empty */
  42 
  43 /*
  44  * CLI and STI
  45  */
  46 
  47 #define CLI(r)                  \
  48         cli
  49 
  50 #define STI                     \
  51         sti
  52 
  53 /*
  54  * Used to re-enable interrupts in the body of exception handlers
  55  */
  56 
  57 #if defined(__amd64)
  58 
  59 #define ENABLE_INTR_FLAGS               \
  60         pushq   $F_ON;                  \
  61         popfq
  62 
  63 #elif defined(__i386)
  64 
  65 #define ENABLE_INTR_FLAGS               \
  66         pushl   $F_ON;                  \
  67         popfl
  68 
  69 #endif  /* __i386 */
  70 
  71 /*
  72  * IRET and SWAPGS
  73  */
  74 #if defined(__amd64)
  75 
  76 #define IRET    iretq
  77 #define SYSRETQ sysretq
  78 #define SYSRETL sysretl
  79 #define SWAPGS  swapgs
  80 #define XPV_TRAP_POP    /* empty */
  81 #define XPV_TRAP_PUSH   /* empty */
  82 
  83 #elif defined(__i386)
  84 
  85 #define IRET    iret
  86 
  87 #endif  /* __i386 */
  88 
  89 #define CLEAN_CS        /* empty */
  90 
  91 
  92 /*
  93  * Macros for saving the original segment registers and restoring them
  94  * for fast traps.
  95  */
  96 #if defined(__amd64)
  97 
  98 /*
  99  * Smaller versions of INTR_PUSH and INTR_POP for fast traps.
 100  * The following registers have been pushed onto the stack by
 101  * hardware at this point:
 102  *
 103  *      greg_t  r_rip;
 104  *      greg_t  r_cs;
 105  *      greg_t  r_rfl;
 106  *      greg_t  r_rsp;
 107  *      greg_t  r_ss;
 108  *
 109  * This handler is executed both by 32-bit and 64-bit applications.
 110  * 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx,
 111  * %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls.
 112  * However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile
 113  * across a function call -- in particular, %esi and %edi MUST be saved!
 114  *
 115  * We could do this differently by making a FAST_INTR_PUSH32 for 32-bit
 116  * programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem
 117  * particularly worth it.
 118  */
 119 #define FAST_INTR_PUSH                  \
 120         INTGATE_INIT_KERNEL_FLAGS;      \
 121         subq    $REGOFF_RIP, %rsp;      \
 122         movq    %rsi, REGOFF_RSI(%rsp); \
 123         movq    %rdi, REGOFF_RDI(%rsp); \
 124         swapgs
 125 
 126 #define FAST_INTR_POP                   \
 127         swapgs;                         \
 128         movq    REGOFF_RSI(%rsp), %rsi; \
 129         movq    REGOFF_RDI(%rsp), %rdi; \
 130         addq    $REGOFF_RIP, %rsp
 131 
 132 #define FAST_INTR_RETURN        iretq
 133 
 134 #elif defined(__i386)
 135 
 136 #define FAST_INTR_PUSH          \
 137         cld;                    \
 138         __SEGREGS_PUSH          \
 139         __SEGREGS_LOAD_KERNEL
 140 
 141 #define FAST_INTR_POP           \
 142         __SEGREGS_POP
 143 
 144 #define FAST_INTR_RETURN        iret
 145 
 146 #endif  /* __i386 */
 147 
 148 /*
 149  * Handling the CR0.TS bit for floating point handling.
 150  *
 151  * When the TS bit is *set*, attempts to touch the floating
 152  * point hardware will result in a #nm trap.
 153  */
 154 #if defined(__amd64)
 155 
 156 #define STTS(rtmp)              \
 157         movq    %cr0, rtmp;     \
 158         orq     $CR0_TS, rtmp;  \
 159         movq    rtmp, %cr0
 160 
 161 #elif defined(__i386)
 162 
 163 #define STTS(rtmp)              \
 164         movl    %cr0, rtmp;     \
 165         orl     $CR0_TS, rtmp;  \
 166         movl    rtmp, %cr0
 167 
 168 #endif  /* __i386 */
 169 
 170 #define CLTS                    \
 171         clts
 172 
 173 #ifdef __cplusplus
 174 }
 175 #endif
 176 
 177 #endif  /* _SYS_MACHPRIVREGS_H */