xref: /titanic_41/usr/src/uts/intel/nskern/nsc_asm.s (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#if defined(lint) || defined(DS_DDICT)
27#include <sys/types.h>
28#include <sys/param.h>
29#else
30#include <sys/asm_linkage.h>
31#endif
32
33#ifdef DS_DDICT
34#define	uint8_t	uchar_t
35#endif
36
37#include "assym.h"	/* Determine value of CPU_THREAD */
38
39/*
40 * Special support routines that can't be done with C
41 * x86 variant
42 */
43
44/*
45 * uint8_t nsc_ldstub(uint8_t *cp)
46 *
47 * Store 0xFF at the specified location, and return its previous content.
48 */
49
50#if defined(lint) || defined(DS_DDICT)
51uint8_t
52nsc_ldstub(uint8_t *cp)
53{
54	uint8_t rv;
55	rv = *cp;
56	*cp = 0xFF;
57	return (rv);
58}
59#else
60	ENTRY(nsc_ldstub)
61#if defined(__amd64)
62	movl    $0xff,%eax
63	lock
64	xchgb   %al, (%rdi) 		/* rdi = lock addr */
65	ret
66#elif defined(__i386)
67	movl	4(%esp), %ecx		/* ecx = lock addr */
68	movl	$0xff, %eax		/* eax = 0xff */
69	lock
70	xchgb	%al, (%ecx)		/* atomic swap eax <-> *ecx */
71	ret
72#else
73#error  "port this routine"
74#endif
75	SET_SIZE(nsc_ldstub)
76#endif
77
78/*
79 * nsc_membar_stld(void)
80 *
81 * On SPARC this is a C callable interface to SPARC asm membar instruction.
82 * For x86 we brute force it with a #LOCK instruction.
83 */
84
85#if defined(lint) || defined(DS_DDICT)
86void
87nsc_membar_stld(void)
88{}
89#else
90
91	ENTRY(nsc_membar_stld)
92#if defined(__amd64)
93	mfence
94	ret
95#elif defined(__i386)
96	lock
97	xorl	$0, (%esp)
98	ret
99#else
100#error	"port this routine"
101#endif
102	SET_SIZE(nsc_membar_stld)
103
104#endif	/* lint || DS_DDICT */
105
106
107/*
108 * if a() calls b() calls nsc_caller(),
109 * nsc_caller() returns return address in a().
110 */
111
112#if defined(lint) || defined(DS_DDICT)
113caddr_t
114nsc_caller(void)
115{
116	return (0);
117}
118#else
119
120	ENTRY(nsc_caller)
121#if defined(__amd64)
122	movq	8(%rbp), %rax		/* b()'s return pc, in a() */
123	ret
124#elif defined(__i386)
125	movl	4(%ebp), %eax		/* b()'s return pc, in a() */
126	ret
127#else
128#error	"port this routine"
129#endif
130	SET_SIZE(nsc_caller)
131
132#endif  /* lint || DS_DDICT */
133
134
135/*
136 * if a() calls nsc_callee(), nsc_callee() returns the
137 * return address in a();
138 */
139
140#if defined(lint) || defined(DS_DDICT)
141caddr_t
142nsc_callee(void)
143{
144	return (0);
145}
146#else
147
148	ENTRY(nsc_callee)
149#if defined(__amd64)
150	movq	(%rsp), %rax		/* callee()'s return pc, in a() */
151	ret
152#elif defined(__i386)
153	movl	(%esp), %eax		/* callee()'s return pc, in a() */
154	ret
155#else
156#error	"port this routine"
157#endif
158	SET_SIZE(nsc_callee)
159
160#endif  /* lint || DS_DDICT */
161
162
163/*
164 * nsc_threadp(void)
165 *
166 * C callable interface to get the current thread pointer.
167 */
168
169#if defined(lint) || defined(DS_DDICT)
170void *
171nsc_threadp(void)
172{
173	return (NULL);
174}
175#else
176
177	ENTRY(nsc_threadp)
178#if defined(__amd64)
179	movq    %gs:CPU_THREAD, %rax
180	ret
181#elif defined(__i386)
182	movl %gs:CPU_THREAD,%eax
183	ret
184#else
185#error	"port this routine"
186#endif
187	SET_SIZE(nsc_threadp)
188
189#endif /* lint || DS_DDICT */
190