xref: /titanic_41/usr/src/uts/intel/ia32/ml/desctbls_asm.s (revision 9404882939d18ddd3c94a5bd3da7a0449c195a5d)
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*/
52void
53rd_idtr(desctbr_t *idtr)
54{}
55
56/*ARGSUSED*/
57void
58wr_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*/
101void
102rd_gdtr(desctbr_t *gdtr)
103{}
104
105/*ARGSUSED*/
106void
107wr_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
1281:
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
1511:
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*/
163void
164load_segment_registers(selector_t cs, selector_t fs, selector_t gs,
165    selector_t ss)
166{}
167
168#else	/* __lint */
169
170	/*
171	 * loads zero selector for ds and es.
172	 */
173	ENTRY_NP(load_segment_registers)
174	pushq	%rbp
175	movq	%rsp, %rbp
176	pushq	%rdi
177	pushq	$.newcs
178	lretq
179.newcs:
180	/*
181	 * zero %ds and %es - they're ignored anyway
182	 */
183	xorl	%eax, %eax
184	movw	%ax, %ds
185	movw	%ax, %es
186	movl	%esi, %eax
187	movw	%ax, %fs
188	movl	%edx, %eax
189	movw	%ax, %gs
190	movl	%ecx, %eax
191	movw	%ax, %ss
192	leave
193	ret
194	SET_SIZE(load_segment_registers)
195
196#endif	/* __lint */
197#elif defined(__i386)
198
199#if defined(__lint)
200
201/*ARGSUSED*/
202void
203load_segment_registers(
204    selector_t cs, selector_t ds, selector_t es,
205    selector_t fs, selector_t gs, selector_t ss)
206{}
207
208#else	/* __lint */
209
210	ENTRY_NP(load_segment_registers)
211	pushl	%ebp
212	movl	%esp, %ebp
213
214	pushl	0x8(%ebp)
215	pushl	$.newcs
216	lret
217.newcs:
218	movw	0xc(%ebp), %ax
219	movw	%ax, %ds
220	movw	0x10(%ebp), %ax
221	movw	%ax, %es
222	movw	0x14(%ebp), %ax
223	movw	%ax, %fs
224	movw	0x18(%ebp), %ax
225	movw	%ax, %gs
226	movw	0x1c(%ebp), %ax
227	movw	%ax, %ss
228	leave
229	ret
230	SET_SIZE(load_segment_registers)
231
232#endif	/* __lint */
233#endif	/* __i386 */
234
235#if defined(__lint)
236
237/*ARGSUSED*/
238void
239wr_ldtr(selector_t ldtsel)
240{}
241
242selector_t
243rd_ldtr(void)
244{ return (0); }
245
246#if defined(__amd64)
247void
248clr_ldt_sregs(void)
249{}
250#endif
251
252#else	/* __lint */
253
254#if defined(__amd64)
255
256	ENTRY_NP(wr_ldtr)
257	movq	%rdi, %rax
258	lldt	%ax
259	ret
260	SET_SIZE(wr_ldtr)
261
262	ENTRY_NP(rd_ldtr)
263	xorl	%eax, %eax
264	sldt	%ax
265	ret
266	SET_SIZE(rd_ldtr)
267
268	/*
269	 * Make sure any stale ldt selectors are cleared by loading
270	 * KDS_SEL (kernel %ds gdt selector). This is necessary
271	 * since the kernel does not use %es, %fs and %ds. %cs and
272	 * %ss are necessary and setup by the kernel along with %gs
273	 * to point to current cpu struct. If we take a kmdb breakpoint
274	 * in the kernel and resume with a stale ldt selector kmdb
275	 * would #gp fault if it points to a ldt in the context of
276	 * another process.
277	 *
278	 * WARNING: Nocona and AMD have different behaviour about storing
279	 * the null selector into %fs and %gs while in long mode. On AMD
280	 * chips fsbase and gsbase is not cleared. But on nocona storing
281	 * null selector into %fs or %gs has the side effect of clearing
282	 * fsbase or gsbase. For that reason we use KDS_SEL which has
283	 * consistent behavoir between AMD and Nocona.
284	 */
285	ENTRY_NP(clr_ldt_sregs)
286
287	/*
288	 * Save GSBASE before resetting %gs to KDS_SEL
289	 * then restore GSBASE.
290	 */
291	cli
292	movq	%rbx, %rdi
293	movw	$KDS_SEL, %bx
294        movl    $MSR_AMD_GSBASE, %ecx
295        rdmsr
296        movw    %bx, %gs
297	wrmsr
298	sti
299	movw	%bx, %ds
300	movw	%bx, %es
301	movw	%bx, %fs
302	movq	%rdi, %rbx
303	ret
304	SET_SIZE(clr_ldt_sregs)
305
306#elif defined(__i386)
307
308	ENTRY_NP(wr_ldtr)
309	movw	4(%esp), %ax
310	lldt	%ax
311	ret
312	SET_SIZE(wr_ldtr)
313
314	ENTRY_NP(rd_ldtr)
315	xorl	%eax, %eax
316	sldt	%ax
317	ret
318	SET_SIZE(rd_ldtr)
319
320#endif	/* __i386 */
321#endif	/* __lint */
322
323#if defined(__lint)
324
325/*ARGSUSED*/
326void
327wr_tsr(selector_t tsssel)
328{}
329
330#else	/* __lint */
331
332#if defined(__amd64)
333
334	ENTRY_NP(wr_tsr)
335	movq	%rdi, %rax
336	ltr	%ax
337	ret
338	SET_SIZE(wr_tsr)
339
340#elif defined(__i386)
341
342	ENTRY_NP(wr_tsr)
343	movw	4(%esp), %ax
344	ltr	%ax
345	ret
346	SET_SIZE(wr_tsr)
347
348#endif	/* __i386 */
349#endif	/* __lint */
350