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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #include <sys/asm_linkage.h>
  29 #include <sys/asm_misc.h>
  30 #include <sys/regset.h>
  31 #include <sys/panic.h>
  32 #include <sys/ontrap.h>
  33 #include <sys/privregs.h>
  34 #include <sys/segments.h>
  35 #include <sys/trap.h>
  36 
  37 #if defined(__lint)
  38 #include <sys/types.h>
  39 #include <sys/systm.h>
  40 #include <sys/thread.h>
  41 #include <sys/archsystm.h>
  42 #include <sys/byteorder.h>
  43 #include <sys/dtrace.h>
  44 #include <sys/x86_archext.h>
  45 #else   /* __lint */
  46 #include "assym.h"
  47 #endif  /* __lint */
  48 
  49 #if defined(__lint)
  50 
  51 /*ARGSUSED*/
  52 void
  53 rd_idtr(desctbr_t *idtr)
  54 {}
  55 
  56 /*ARGSUSED*/
  57 void
  58 wr_idtr(desctbr_t *idtr)
  59 {}
  60 
  61 #else   /* __lint */
  62 
  63 #if defined(__amd64)
  64 
  65         ENTRY_NP(rd_idtr)
  66         sidt    (%rdi)
  67         ret
  68         SET_SIZE(rd_idtr)
  69 
  70         ENTRY_NP(wr_idtr)
  71         lidt    (%rdi)
  72         ret
  73         SET_SIZE(wr_idtr)
  74 
  75 #elif defined(__i386)
  76 
  77         ENTRY_NP(rd_idtr)
  78         pushl   %ebp
  79         movl    %esp, %ebp
  80         movl    8(%ebp), %edx
  81         sidt    (%edx)
  82         leave
  83         ret
  84         SET_SIZE(rd_idtr)
  85 
  86         ENTRY_NP(wr_idtr)
  87         pushl   %ebp
  88         movl    %esp, %ebp
  89         movl    8(%ebp), %edx
  90         lidt    (%edx)
  91         leave
  92         ret
  93         SET_SIZE(wr_idtr)
  94 
  95 #endif  /* __i386 */
  96 #endif  /* __lint */
  97 
  98 #if defined(__lint)
  99 
 100 /*ARGSUSED*/
 101 void
 102 rd_gdtr(desctbr_t *gdtr)
 103 {}
 104 
 105 /*ARGSUSED*/
 106 void
 107 wr_gdtr(desctbr_t *gdtr)
 108 {}
 109 
 110 #else   /* __lint */
 111 
 112 #if defined(__amd64)
 113 
 114         ENTRY_NP(rd_gdtr)
 115         pushq   %rbp
 116         movq    %rsp, %rbp
 117         sgdt    (%rdi)
 118         leave
 119         ret
 120         SET_SIZE(rd_gdtr)
 121 
 122         ENTRY_NP(wr_gdtr)
 123         pushq   %rbp
 124         movq    %rsp, %rbp
 125         lgdt    (%rdi)
 126         jmp     1f
 127         nop
 128 1:
 129         leave
 130         ret
 131         SET_SIZE(wr_gdtr)
 132 
 133 #elif defined(__i386)
 134 
 135         ENTRY_NP(rd_gdtr)
 136         pushl   %ebp
 137         movl    %esp, %ebp
 138         movl    8(%ebp), %edx
 139         sgdt    (%edx)
 140         leave
 141         ret
 142         SET_SIZE(rd_gdtr)
 143 
 144         ENTRY_NP(wr_gdtr)
 145         pushl   %ebp
 146         movl    %esp, %ebp
 147         movl    8(%ebp), %edx
 148         lgdt    (%edx)
 149         jmp     1f
 150         nop
 151 1:
 152         leave
 153         ret
 154         SET_SIZE(wr_gdtr)
 155 
 156 #endif  /* __i386 */
 157 #endif  /* __lint */
 158 
 159 #if defined(__amd64)
 160 #if defined(__lint)
 161 
 162 /*ARGSUSED*/
 163 void
 164 load_segment_registers(selector_t cs, selector_t fs, selector_t gs,
 165     selector_t ss)
 166 {}
 167 
 168 selector_t
 169 get_cs_register()
 170 { return (0); }
 171 
 172 #else   /* __lint */
 173 
 174         /*
 175          * loads zero selector for ds and es.
 176          */
 177         ENTRY_NP(load_segment_registers)
 178         pushq   %rbp
 179         movq    %rsp, %rbp
 180         pushq   %rdi
 181         pushq   $.newcs
 182         lretq
 183 .newcs:
 184         /*
 185          * zero %ds and %es - they're ignored anyway
 186          */
 187         xorl    %eax, %eax
 188         movw    %ax, %ds
 189         movw    %ax, %es
 190         movl    %esi, %eax
 191         movw    %ax, %fs
 192         movl    %edx, %eax
 193         movw    %ax, %gs
 194         movl    %ecx, %eax
 195         movw    %ax, %ss
 196         leave
 197         ret
 198         SET_SIZE(load_segment_registers)
 199 
 200         ENTRY_NP(get_cs_register)
 201         movq    $0, %rax
 202         movw    %cs, %rax
 203         ret
 204         SET_SIZE(get_cs_register)
 205 
 206 #endif  /* __lint */
 207 #elif defined(__i386)
 208 
 209 #if defined(__lint)
 210 
 211 /*ARGSUSED*/
 212 void
 213 load_segment_registers(
 214     selector_t cs, selector_t ds, selector_t es,
 215     selector_t fs, selector_t gs, selector_t ss)
 216 {}
 217 
 218 selector_t
 219 get_cs_register()
 220 { return ((selector_t) 0); }
 221 
 222 #else   /* __lint */
 223 
 224         ENTRY_NP(load_segment_registers)
 225         pushl   %ebp
 226         movl    %esp, %ebp
 227 
 228         pushl   0x8(%ebp)
 229         pushl   $.newcs
 230         lret
 231 .newcs:
 232         movw    0xc(%ebp), %ax
 233         movw    %ax, %ds
 234         movw    0x10(%ebp), %ax
 235         movw    %ax, %es
 236         movw    0x14(%ebp), %ax
 237         movw    %ax, %fs
 238         movw    0x18(%ebp), %ax
 239         movw    %ax, %gs
 240         movw    0x1c(%ebp), %ax
 241         movw    %ax, %ss
 242         leave
 243         ret
 244         SET_SIZE(load_segment_registers)
 245 
 246         ENTRY_NP(get_cs_register)
 247         movl    $0, %eax
 248         movw    %cs, %ax
 249         ret
 250         SET_SIZE(get_cs_register)
 251 
 252 #endif  /* __lint */
 253 #endif  /* __i386 */
 254 
 255 #if defined(__lint)
 256 
 257 /*ARGSUSED*/
 258 void
 259 wr_ldtr(selector_t ldtsel)
 260 {}
 261 
 262 selector_t
 263 rd_ldtr(void)
 264 { return (0); }
 265 
 266 #else   /* __lint */
 267 
 268 #if defined(__amd64)
 269 
 270         ENTRY_NP(wr_ldtr)
 271         movq    %rdi, %rax
 272         lldt    %ax
 273         ret
 274         SET_SIZE(wr_ldtr)
 275 
 276         ENTRY_NP(rd_ldtr)
 277         xorl    %eax, %eax
 278         sldt    %ax
 279         ret
 280         SET_SIZE(rd_ldtr)
 281 
 282 #elif defined(__i386)
 283 
 284         ENTRY_NP(wr_ldtr)
 285         movw    4(%esp), %ax
 286         lldt    %ax
 287         ret
 288         SET_SIZE(wr_ldtr)
 289 
 290         ENTRY_NP(rd_ldtr)
 291         xorl    %eax, %eax
 292         sldt    %ax
 293         ret
 294         SET_SIZE(rd_ldtr)
 295 
 296 #endif  /* __i386 */
 297 #endif  /* __lint */
 298 
 299 #if defined(__lint)
 300 
 301 /*ARGSUSED*/
 302 void
 303 wr_tsr(selector_t tsssel)
 304 {}
 305 
 306 #else   /* __lint */
 307 
 308 #if defined(__amd64)
 309 
 310         ENTRY_NP(wr_tsr)
 311         movq    %rdi, %rax
 312         ltr     %ax
 313         ret
 314         SET_SIZE(wr_tsr)
 315 
 316 #elif defined(__i386)
 317 
 318         ENTRY_NP(wr_tsr)
 319         movw    4(%esp), %ax
 320         ltr     %ax
 321         ret
 322         SET_SIZE(wr_tsr)
 323 
 324 #endif  /* __i386 */
 325 #endif  /* __lint */