xref: /titanic_41/usr/src/uts/intel/nskern/nsc_asm.s (revision fd65ca2882506123b77fd24431c8f6fbfdb37ce5)
1fcf3ce44SJohn Forte/*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte/*
22fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte * Use is subject to license terms.
24fcf3ce44SJohn Forte */
25fcf3ce44SJohn Forte
26fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
27fcf3ce44SJohn Forte#include <sys/types.h>
28fcf3ce44SJohn Forte#include <sys/param.h>
29fcf3ce44SJohn Forte#else
30*fd65ca28SJohn Forte#include "assym.h"	/* Determine value of CPU_THREAD */
31fcf3ce44SJohn Forte#include <sys/asm_linkage.h>
32fcf3ce44SJohn Forte#endif
33fcf3ce44SJohn Forte
34fcf3ce44SJohn Forte#ifdef DS_DDICT
35fcf3ce44SJohn Forte#define	uint8_t	uchar_t
36fcf3ce44SJohn Forte#endif
37fcf3ce44SJohn Forte
38fcf3ce44SJohn Forte
39fcf3ce44SJohn Forte/*
40fcf3ce44SJohn Forte * Special support routines that can't be done with C
41fcf3ce44SJohn Forte * x86 variant
42fcf3ce44SJohn Forte */
43fcf3ce44SJohn Forte
44fcf3ce44SJohn Forte/*
45fcf3ce44SJohn Forte * uint8_t nsc_ldstub(uint8_t *cp)
46fcf3ce44SJohn Forte *
47fcf3ce44SJohn Forte * Store 0xFF at the specified location, and return its previous content.
48fcf3ce44SJohn Forte */
49fcf3ce44SJohn Forte
50fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
51fcf3ce44SJohn Forteuint8_t
52fcf3ce44SJohn Fortensc_ldstub(uint8_t *cp)
53fcf3ce44SJohn Forte{
54fcf3ce44SJohn Forte	uint8_t rv;
55fcf3ce44SJohn Forte	rv = *cp;
56fcf3ce44SJohn Forte	*cp = 0xFF;
57fcf3ce44SJohn Forte	return (rv);
58fcf3ce44SJohn Forte}
59fcf3ce44SJohn Forte#else
60fcf3ce44SJohn Forte	ENTRY(nsc_ldstub)
61fcf3ce44SJohn Forte#if defined(__amd64)
62fcf3ce44SJohn Forte	movl    $0xff,%eax
63fcf3ce44SJohn Forte	lock
64fcf3ce44SJohn Forte	xchgb   %al, (%rdi) 		/* rdi = lock addr */
65fcf3ce44SJohn Forte	ret
66fcf3ce44SJohn Forte#elif defined(__i386)
67fcf3ce44SJohn Forte	movl	4(%esp), %ecx		/* ecx = lock addr */
68fcf3ce44SJohn Forte	movl	$0xff, %eax		/* eax = 0xff */
69fcf3ce44SJohn Forte	lock
70fcf3ce44SJohn Forte	xchgb	%al, (%ecx)		/* atomic swap eax <-> *ecx */
71fcf3ce44SJohn Forte	ret
72fcf3ce44SJohn Forte#else
73fcf3ce44SJohn Forte#error  "port this routine"
74fcf3ce44SJohn Forte#endif
75fcf3ce44SJohn Forte	SET_SIZE(nsc_ldstub)
76fcf3ce44SJohn Forte#endif
77fcf3ce44SJohn Forte
78fcf3ce44SJohn Forte/*
79fcf3ce44SJohn Forte * nsc_membar_stld(void)
80fcf3ce44SJohn Forte *
81fcf3ce44SJohn Forte * On SPARC this is a C callable interface to SPARC asm membar instruction.
82fcf3ce44SJohn Forte * For x86 we brute force it with a #LOCK instruction.
83fcf3ce44SJohn Forte */
84fcf3ce44SJohn Forte
85fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
86fcf3ce44SJohn Fortevoid
87fcf3ce44SJohn Fortensc_membar_stld(void)
88fcf3ce44SJohn Forte{}
89fcf3ce44SJohn Forte#else
90fcf3ce44SJohn Forte
91fcf3ce44SJohn Forte	ENTRY(nsc_membar_stld)
92fcf3ce44SJohn Forte#if defined(__amd64)
93fcf3ce44SJohn Forte	mfence
94fcf3ce44SJohn Forte	ret
95fcf3ce44SJohn Forte#elif defined(__i386)
96fcf3ce44SJohn Forte	lock
97fcf3ce44SJohn Forte	xorl	$0, (%esp)
98fcf3ce44SJohn Forte	ret
99fcf3ce44SJohn Forte#else
100fcf3ce44SJohn Forte#error	"port this routine"
101fcf3ce44SJohn Forte#endif
102fcf3ce44SJohn Forte	SET_SIZE(nsc_membar_stld)
103fcf3ce44SJohn Forte
104fcf3ce44SJohn Forte#endif	/* lint || DS_DDICT */
105fcf3ce44SJohn Forte
106fcf3ce44SJohn Forte
107fcf3ce44SJohn Forte/*
108fcf3ce44SJohn Forte * if a() calls b() calls nsc_caller(),
109fcf3ce44SJohn Forte * nsc_caller() returns return address in a().
110fcf3ce44SJohn Forte */
111fcf3ce44SJohn Forte
112fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
113fcf3ce44SJohn Fortecaddr_t
114fcf3ce44SJohn Fortensc_caller(void)
115fcf3ce44SJohn Forte{
116fcf3ce44SJohn Forte	return (0);
117fcf3ce44SJohn Forte}
118fcf3ce44SJohn Forte#else
119fcf3ce44SJohn Forte
120fcf3ce44SJohn Forte	ENTRY(nsc_caller)
121fcf3ce44SJohn Forte#if defined(__amd64)
122fcf3ce44SJohn Forte	movq	8(%rbp), %rax		/* b()'s return pc, in a() */
123fcf3ce44SJohn Forte	ret
124fcf3ce44SJohn Forte#elif defined(__i386)
125fcf3ce44SJohn Forte	movl	4(%ebp), %eax		/* b()'s return pc, in a() */
126fcf3ce44SJohn Forte	ret
127fcf3ce44SJohn Forte#else
128fcf3ce44SJohn Forte#error	"port this routine"
129fcf3ce44SJohn Forte#endif
130fcf3ce44SJohn Forte	SET_SIZE(nsc_caller)
131fcf3ce44SJohn Forte
132fcf3ce44SJohn Forte#endif  /* lint || DS_DDICT */
133fcf3ce44SJohn Forte
134fcf3ce44SJohn Forte
135fcf3ce44SJohn Forte/*
136fcf3ce44SJohn Forte * if a() calls nsc_callee(), nsc_callee() returns the
137fcf3ce44SJohn Forte * return address in a();
138fcf3ce44SJohn Forte */
139fcf3ce44SJohn Forte
140fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
141fcf3ce44SJohn Fortecaddr_t
142fcf3ce44SJohn Fortensc_callee(void)
143fcf3ce44SJohn Forte{
144fcf3ce44SJohn Forte	return (0);
145fcf3ce44SJohn Forte}
146fcf3ce44SJohn Forte#else
147fcf3ce44SJohn Forte
148fcf3ce44SJohn Forte	ENTRY(nsc_callee)
149fcf3ce44SJohn Forte#if defined(__amd64)
150fcf3ce44SJohn Forte	movq	(%rsp), %rax		/* callee()'s return pc, in a() */
151fcf3ce44SJohn Forte	ret
152fcf3ce44SJohn Forte#elif defined(__i386)
153fcf3ce44SJohn Forte	movl	(%esp), %eax		/* callee()'s return pc, in a() */
154fcf3ce44SJohn Forte	ret
155fcf3ce44SJohn Forte#else
156fcf3ce44SJohn Forte#error	"port this routine"
157fcf3ce44SJohn Forte#endif
158fcf3ce44SJohn Forte	SET_SIZE(nsc_callee)
159fcf3ce44SJohn Forte
160fcf3ce44SJohn Forte#endif  /* lint || DS_DDICT */
161fcf3ce44SJohn Forte
162fcf3ce44SJohn Forte
163fcf3ce44SJohn Forte/*
164fcf3ce44SJohn Forte * nsc_threadp(void)
165fcf3ce44SJohn Forte *
166fcf3ce44SJohn Forte * C callable interface to get the current thread pointer.
167fcf3ce44SJohn Forte */
168fcf3ce44SJohn Forte
169fcf3ce44SJohn Forte#if defined(lint) || defined(DS_DDICT)
170fcf3ce44SJohn Fortevoid *
171fcf3ce44SJohn Fortensc_threadp(void)
172fcf3ce44SJohn Forte{
173fcf3ce44SJohn Forte	return (NULL);
174fcf3ce44SJohn Forte}
175fcf3ce44SJohn Forte#else
176fcf3ce44SJohn Forte
177fcf3ce44SJohn Forte	ENTRY(nsc_threadp)
178fcf3ce44SJohn Forte#if defined(__amd64)
179fcf3ce44SJohn Forte	movq    %gs:CPU_THREAD, %rax
180fcf3ce44SJohn Forte	ret
181fcf3ce44SJohn Forte#elif defined(__i386)
182fcf3ce44SJohn Forte	movl %gs:CPU_THREAD,%eax
183fcf3ce44SJohn Forte	ret
184fcf3ce44SJohn Forte#else
185fcf3ce44SJohn Forte#error	"port this routine"
186fcf3ce44SJohn Forte#endif
187fcf3ce44SJohn Forte	SET_SIZE(nsc_threadp)
188fcf3ce44SJohn Forte
189fcf3ce44SJohn Forte#endif /* lint || DS_DDICT */
190