xref: /onnv-gate/usr/src/uts/intel/nskern/nsc_asm.s (revision 7859:d0ab9df05bd7)
17836SJohn.Forte@Sun.COM/*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM/*
227836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
277836SJohn.Forte@Sun.COM#include <sys/types.h>
287836SJohn.Forte@Sun.COM#include <sys/param.h>
297836SJohn.Forte@Sun.COM#else
30*7859SJohn.Forte@Sun.COM#include "assym.h"	/* Determine value of CPU_THREAD */
317836SJohn.Forte@Sun.COM#include <sys/asm_linkage.h>
327836SJohn.Forte@Sun.COM#endif
337836SJohn.Forte@Sun.COM
347836SJohn.Forte@Sun.COM#ifdef DS_DDICT
357836SJohn.Forte@Sun.COM#define	uint8_t	uchar_t
367836SJohn.Forte@Sun.COM#endif
377836SJohn.Forte@Sun.COM
387836SJohn.Forte@Sun.COM
397836SJohn.Forte@Sun.COM/*
407836SJohn.Forte@Sun.COM * Special support routines that can't be done with C
417836SJohn.Forte@Sun.COM * x86 variant
427836SJohn.Forte@Sun.COM */
437836SJohn.Forte@Sun.COM
447836SJohn.Forte@Sun.COM/*
457836SJohn.Forte@Sun.COM * uint8_t nsc_ldstub(uint8_t *cp)
467836SJohn.Forte@Sun.COM *
477836SJohn.Forte@Sun.COM * Store 0xFF at the specified location, and return its previous content.
487836SJohn.Forte@Sun.COM */
497836SJohn.Forte@Sun.COM
507836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
517836SJohn.Forte@Sun.COMuint8_t
527836SJohn.Forte@Sun.COMnsc_ldstub(uint8_t *cp)
537836SJohn.Forte@Sun.COM{
547836SJohn.Forte@Sun.COM	uint8_t rv;
557836SJohn.Forte@Sun.COM	rv = *cp;
567836SJohn.Forte@Sun.COM	*cp = 0xFF;
577836SJohn.Forte@Sun.COM	return (rv);
587836SJohn.Forte@Sun.COM}
597836SJohn.Forte@Sun.COM#else
607836SJohn.Forte@Sun.COM	ENTRY(nsc_ldstub)
617836SJohn.Forte@Sun.COM#if defined(__amd64)
627836SJohn.Forte@Sun.COM	movl    $0xff,%eax
637836SJohn.Forte@Sun.COM	lock
647836SJohn.Forte@Sun.COM	xchgb   %al, (%rdi) 		/* rdi = lock addr */
657836SJohn.Forte@Sun.COM	ret
667836SJohn.Forte@Sun.COM#elif defined(__i386)
677836SJohn.Forte@Sun.COM	movl	4(%esp), %ecx		/* ecx = lock addr */
687836SJohn.Forte@Sun.COM	movl	$0xff, %eax		/* eax = 0xff */
697836SJohn.Forte@Sun.COM	lock
707836SJohn.Forte@Sun.COM	xchgb	%al, (%ecx)		/* atomic swap eax <-> *ecx */
717836SJohn.Forte@Sun.COM	ret
727836SJohn.Forte@Sun.COM#else
737836SJohn.Forte@Sun.COM#error  "port this routine"
747836SJohn.Forte@Sun.COM#endif
757836SJohn.Forte@Sun.COM	SET_SIZE(nsc_ldstub)
767836SJohn.Forte@Sun.COM#endif
777836SJohn.Forte@Sun.COM
787836SJohn.Forte@Sun.COM/*
797836SJohn.Forte@Sun.COM * nsc_membar_stld(void)
807836SJohn.Forte@Sun.COM *
817836SJohn.Forte@Sun.COM * On SPARC this is a C callable interface to SPARC asm membar instruction.
827836SJohn.Forte@Sun.COM * For x86 we brute force it with a #LOCK instruction.
837836SJohn.Forte@Sun.COM */
847836SJohn.Forte@Sun.COM
857836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
867836SJohn.Forte@Sun.COMvoid
877836SJohn.Forte@Sun.COMnsc_membar_stld(void)
887836SJohn.Forte@Sun.COM{}
897836SJohn.Forte@Sun.COM#else
907836SJohn.Forte@Sun.COM
917836SJohn.Forte@Sun.COM	ENTRY(nsc_membar_stld)
927836SJohn.Forte@Sun.COM#if defined(__amd64)
937836SJohn.Forte@Sun.COM	mfence
947836SJohn.Forte@Sun.COM	ret
957836SJohn.Forte@Sun.COM#elif defined(__i386)
967836SJohn.Forte@Sun.COM	lock
977836SJohn.Forte@Sun.COM	xorl	$0, (%esp)
987836SJohn.Forte@Sun.COM	ret
997836SJohn.Forte@Sun.COM#else
1007836SJohn.Forte@Sun.COM#error	"port this routine"
1017836SJohn.Forte@Sun.COM#endif
1027836SJohn.Forte@Sun.COM	SET_SIZE(nsc_membar_stld)
1037836SJohn.Forte@Sun.COM
1047836SJohn.Forte@Sun.COM#endif	/* lint || DS_DDICT */
1057836SJohn.Forte@Sun.COM
1067836SJohn.Forte@Sun.COM
1077836SJohn.Forte@Sun.COM/*
1087836SJohn.Forte@Sun.COM * if a() calls b() calls nsc_caller(),
1097836SJohn.Forte@Sun.COM * nsc_caller() returns return address in a().
1107836SJohn.Forte@Sun.COM */
1117836SJohn.Forte@Sun.COM
1127836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
1137836SJohn.Forte@Sun.COMcaddr_t
1147836SJohn.Forte@Sun.COMnsc_caller(void)
1157836SJohn.Forte@Sun.COM{
1167836SJohn.Forte@Sun.COM	return (0);
1177836SJohn.Forte@Sun.COM}
1187836SJohn.Forte@Sun.COM#else
1197836SJohn.Forte@Sun.COM
1207836SJohn.Forte@Sun.COM	ENTRY(nsc_caller)
1217836SJohn.Forte@Sun.COM#if defined(__amd64)
1227836SJohn.Forte@Sun.COM	movq	8(%rbp), %rax		/* b()'s return pc, in a() */
1237836SJohn.Forte@Sun.COM	ret
1247836SJohn.Forte@Sun.COM#elif defined(__i386)
1257836SJohn.Forte@Sun.COM	movl	4(%ebp), %eax		/* b()'s return pc, in a() */
1267836SJohn.Forte@Sun.COM	ret
1277836SJohn.Forte@Sun.COM#else
1287836SJohn.Forte@Sun.COM#error	"port this routine"
1297836SJohn.Forte@Sun.COM#endif
1307836SJohn.Forte@Sun.COM	SET_SIZE(nsc_caller)
1317836SJohn.Forte@Sun.COM
1327836SJohn.Forte@Sun.COM#endif  /* lint || DS_DDICT */
1337836SJohn.Forte@Sun.COM
1347836SJohn.Forte@Sun.COM
1357836SJohn.Forte@Sun.COM/*
1367836SJohn.Forte@Sun.COM * if a() calls nsc_callee(), nsc_callee() returns the
1377836SJohn.Forte@Sun.COM * return address in a();
1387836SJohn.Forte@Sun.COM */
1397836SJohn.Forte@Sun.COM
1407836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
1417836SJohn.Forte@Sun.COMcaddr_t
1427836SJohn.Forte@Sun.COMnsc_callee(void)
1437836SJohn.Forte@Sun.COM{
1447836SJohn.Forte@Sun.COM	return (0);
1457836SJohn.Forte@Sun.COM}
1467836SJohn.Forte@Sun.COM#else
1477836SJohn.Forte@Sun.COM
1487836SJohn.Forte@Sun.COM	ENTRY(nsc_callee)
1497836SJohn.Forte@Sun.COM#if defined(__amd64)
1507836SJohn.Forte@Sun.COM	movq	(%rsp), %rax		/* callee()'s return pc, in a() */
1517836SJohn.Forte@Sun.COM	ret
1527836SJohn.Forte@Sun.COM#elif defined(__i386)
1537836SJohn.Forte@Sun.COM	movl	(%esp), %eax		/* callee()'s return pc, in a() */
1547836SJohn.Forte@Sun.COM	ret
1557836SJohn.Forte@Sun.COM#else
1567836SJohn.Forte@Sun.COM#error	"port this routine"
1577836SJohn.Forte@Sun.COM#endif
1587836SJohn.Forte@Sun.COM	SET_SIZE(nsc_callee)
1597836SJohn.Forte@Sun.COM
1607836SJohn.Forte@Sun.COM#endif  /* lint || DS_DDICT */
1617836SJohn.Forte@Sun.COM
1627836SJohn.Forte@Sun.COM
1637836SJohn.Forte@Sun.COM/*
1647836SJohn.Forte@Sun.COM * nsc_threadp(void)
1657836SJohn.Forte@Sun.COM *
1667836SJohn.Forte@Sun.COM * C callable interface to get the current thread pointer.
1677836SJohn.Forte@Sun.COM */
1687836SJohn.Forte@Sun.COM
1697836SJohn.Forte@Sun.COM#if defined(lint) || defined(DS_DDICT)
1707836SJohn.Forte@Sun.COMvoid *
1717836SJohn.Forte@Sun.COMnsc_threadp(void)
1727836SJohn.Forte@Sun.COM{
1737836SJohn.Forte@Sun.COM	return (NULL);
1747836SJohn.Forte@Sun.COM}
1757836SJohn.Forte@Sun.COM#else
1767836SJohn.Forte@Sun.COM
1777836SJohn.Forte@Sun.COM	ENTRY(nsc_threadp)
1787836SJohn.Forte@Sun.COM#if defined(__amd64)
1797836SJohn.Forte@Sun.COM	movq    %gs:CPU_THREAD, %rax
1807836SJohn.Forte@Sun.COM	ret
1817836SJohn.Forte@Sun.COM#elif defined(__i386)
1827836SJohn.Forte@Sun.COM	movl %gs:CPU_THREAD,%eax
1837836SJohn.Forte@Sun.COM	ret
1847836SJohn.Forte@Sun.COM#else
1857836SJohn.Forte@Sun.COM#error	"port this routine"
1867836SJohn.Forte@Sun.COM#endif
1877836SJohn.Forte@Sun.COM	SET_SIZE(nsc_threadp)
1887836SJohn.Forte@Sun.COM
1897836SJohn.Forte@Sun.COM#endif /* lint || DS_DDICT */
190