[BACK]Return to winx64_wrap.S CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / ndis

File: [cvs.NetBSD.org] / src / sys / compat / ndis / winx64_wrap.S (download)

Revision 1.1, Thu Mar 30 22:56:50 2006 UTC (8 years, 4 months ago) by rittera
Branch: MAIN
CVS Tags: yamt-x86pmap-base4, yamt-x86pmap-base3, yamt-x86pmap-base2, yamt-x86pmap-base, yamt-x86pmap, yamt-splraiseipl-base5, yamt-splraiseipl-base4, yamt-splraiseipl-base3, yamt-splraiseipl-base2, yamt-splraiseipl-base, yamt-splraiseipl, yamt-pf42-baseX, yamt-pf42-base4, yamt-pf42-base3, yamt-pf42-base2, yamt-pf42-base, yamt-pf42, yamt-pdpolicy-base9, yamt-pdpolicy-base8, yamt-pdpolicy-base7, yamt-pdpolicy-base6, yamt-pdpolicy-base5, yamt-pdpolicy-base4, yamt-pdpolicy-base3, yamt-pdpolicy-base2, yamt-pagecache-tag8, yamt-pagecache-base9, yamt-pagecache-base8, yamt-pagecache-base7, yamt-pagecache-base6, yamt-pagecache-base5, yamt-pagecache-base4, yamt-pagecache-base3, yamt-pagecache-base2, yamt-pagecache-base, yamt-pagecache, yamt-nfs-mp-base9, yamt-nfs-mp-base8, yamt-nfs-mp-base7, yamt-nfs-mp-base6, yamt-nfs-mp-base5, yamt-nfs-mp-base4, yamt-nfs-mp-base3, yamt-nfs-mp-base2, yamt-nfs-mp-base11, yamt-nfs-mp-base10, yamt-nfs-mp-base, yamt-nfs-mp, yamt-lazymbuf-base15, yamt-lazymbuf-base14, yamt-kmem-base3, yamt-kmem-base2, yamt-kmem-base, yamt-kmem, yamt-idlelwp-base8, yamt-idlelwp, wrstuden-revivesa-base-4, wrstuden-revivesa-base-3, wrstuden-revivesa-base-2, wrstuden-revivesa-base-1, wrstuden-revivesa-base, wrstuden-revivesa, wrstuden-fixsa-newbase, wrstuden-fixsa-base-1, wrstuden-fixsa-base, wrstuden-fixsa, vmlocking2-base3, vmlocking2-base2, vmlocking2-base1, vmlocking2, vmlocking-nbase, vmlocking-base, vmlocking, uebayasi-xip-base4, uebayasi-xip-base3, uebayasi-xip-base2, uebayasi-xip-base1, uebayasi-xip-base, uebayasi-xip, tls-maxphys-base, tls-maxphys, tls-earlyentropy-base, tls-earlyentropy, thorpej-atomic-base, thorpej-atomic, simonb-wapbl-nbase, simonb-wapbl-base, simonb-wapbl, simonb-timecounters-base, rpaulo-netinet-merge-pcb-base, rmind-uvmplock-nbase, rmind-uvmplock-base, rmind-uvmplock, rmind-smpnet-nbase, rmind-smpnet-base, rmind-smpnet, riastradh-xf86-video-intel-2-7-1-pre-2-21-15, riastradh-drm2-base3, riastradh-drm2-base2, riastradh-drm2-base1, riastradh-drm2-base, riastradh-drm2, reinoud-bufcleanup-nbase, reinoud-bufcleanup-base, reinoud-bufcleanup, post-newlock2-merge, nick-net80211-sync-base, nick-net80211-sync, nick-hppapmap-base4, nick-hppapmap-base3, nick-hppapmap-base2, nick-hppapmap-base, nick-hppapmap, nick-csl-alignment-base5, nick-csl-alignment-base, nick-csl-alignment, newlock2-nbase, newlock2-base, newlock2, netbsd-6-base, netbsd-6-1-RELEASE, netbsd-6-1-RC4, netbsd-6-1-RC3, netbsd-6-1-RC2, netbsd-6-1-RC1, netbsd-6-1-4-RELEASE, netbsd-6-1-3-RELEASE, netbsd-6-1-2-RELEASE, netbsd-6-1-1-RELEASE, netbsd-6-1, netbsd-6-0-RELEASE, netbsd-6-0-RC2, netbsd-6-0-RC1, netbsd-6-0-5-RELEASE, netbsd-6-0-4-RELEASE, netbsd-6-0-3-RELEASE, netbsd-6-0-2-RELEASE, netbsd-6-0-1-RELEASE, netbsd-6-0, netbsd-6, netbsd-5-base, netbsd-5-2-RELEASE, netbsd-5-2-RC1, netbsd-5-2-2-RELEASE, netbsd-5-2-1-RELEASE, netbsd-5-2, netbsd-5-1-RELEASE, netbsd-5-1-RC4, netbsd-5-1-RC3, netbsd-5-1-RC2, netbsd-5-1-RC1, netbsd-5-1-4-RELEASE, netbsd-5-1-3-RELEASE, netbsd-5-1-2-RELEASE, netbsd-5-1-1-RELEASE, netbsd-5-1, netbsd-5-0-RELEASE, netbsd-5-0-RC4, netbsd-5-0-RC3, netbsd-5-0-RC2, netbsd-5-0-RC1, netbsd-5-0-2-RELEASE, netbsd-5-0-1-RELEASE, netbsd-5-0, netbsd-5, netbsd-4-base, netbsd-4-0-RELEASE, netbsd-4-0-RC5, netbsd-4-0-RC4, netbsd-4-0-RC3, netbsd-4-0-RC2, netbsd-4-0-RC1, netbsd-4-0-1-RELEASE, netbsd-4-0, netbsd-4, mjf-ufs-trans-base, mjf-ufs-trans, mjf-devfs2-base, mjf-devfs2, mjf-devfs-base, mjf-devfs, matt-premerge-20091211, matt-nb6-plus-nbase, matt-nb6-plus-base, matt-nb6-plus, matt-nb5-pq3-base, matt-nb5-pq3, matt-nb5-mips64-u2-k2-k4-k7-k8-k9, matt-nb5-mips64-u1-k1-k5, matt-nb5-mips64-premerge-20101231, matt-nb5-mips64-premerge-20091211, matt-nb5-mips64-k15, matt-nb5-mips64, matt-nb4-mips64-k7-u2a-k9b, matt-nb4-arm-base, matt-nb4-arm, matt-mips64-premerge-20101231, matt-mips64-base2, matt-mips64-base, matt-mips64, matt-armv6-prevmlocking, matt-armv6-nbase, matt-armv6-base, matt-armv6, khorben-n900, keiichi-mipv6-nbase, keiichi-mipv6-base, keiichi-mipv6, jymxensuspend-base, jym-xensuspend-nbase, jym-xensuspend-base, jym-xensuspend, jruoho-x86intr-base, jruoho-x86intr, jmcneill-usbmp-pre-base2, jmcneill-usbmp-base9, jmcneill-usbmp-base8, jmcneill-usbmp-base7, jmcneill-usbmp-base6, jmcneill-usbmp-base5, jmcneill-usbmp-base4, jmcneill-usbmp-base3, jmcneill-usbmp-base2, jmcneill-usbmp-base10, jmcneill-usbmp-base, jmcneill-usbmp, jmcneill-pm-base, jmcneill-pm, jmcneill-base, jmcneill-audiomp3-base, jmcneill-audiomp3, hpcarm-cleanup-nbase, hpcarm-cleanup-base, hpcarm-cleanup, haad-nbase2, haad-dm-base2, haad-dm-base1, haad-dm-base, haad-dm, gdamore-uart-base, gdamore-uart, elad-kernelauth-base, cube-autoconf-base, cube-autoconf, cherry-xenmp-base, cherry-xenmp, chap-midi-nbase, chap-midi-base, chap-midi, bouyer-xeni386-nbase, bouyer-xeni386-merge1, bouyer-xeni386-base, bouyer-xeni386, bouyer-xenamd64-base2, bouyer-xenamd64-base, bouyer-xenamd64, bouyer-quota2-nbase, bouyer-quota2-base, bouyer-quota2, agc-symver-base, agc-symver, ad-socklock-base1, ad-audiomp2-base, ad-audiomp2, ad-audiomp-base, ad-audiomp, abandoned-netbsd-4-base, abandoned-netbsd-4, HEAD
Branch point for: yamt-pdpolicy, yamt-lazymbuf, simonb-timecounters, rpaulo-netinet-merge-pcb, peter-altq, elad-kernelauth

Added the original FreeBSD RELENG_54 files in sys/compat/ndis.

/*-
 * Copyright (c) 2005
 *      Bill Paul <wpaul@windriver.com>.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Bill Paul.
 * 4. Neither the name of the author nor the names of any co-contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The x86_64 callback routines were written and graciously submitted
 * by Ville-Pertti Keinonen <will@exomi.com>.
 *
 * $FreeBSD: src/sys/compat/ndis/winx64_wrap.S,v 1.3.2.1 2005/02/18 16:30:09 wpaul Exp $
 */

#include <machine/asmacros.h>

/*
 * Wrapper for handling up to 16 arguments. We can't really
 * know how many arguments the caller will pass us. I'm taking an
 * educated guess that we'll never get over 16. Handling too
 * few arguments is bad. Handling too many is inefficient, but
 * not fatal. If someone can think of a way to handle an arbitrary
 * number of arguments with more elegant code, freel free to let
 * me know.
 *
 * Standard amd64 calling conventions specify the following registers
 * to be used for passing the first 6 arguments:
 *
 *   %rdi, %rsi, %rdx, %rcx, %r8, %r9
 *
 * Further arguments are passed on the stack (the 7th argument is
 * located immediately after the return address).
 *
 * Windows x86_64 calling conventions only pass the first 4
 * arguments in registers:
 *
 *   %rcx, %rdx, %r8, %r9
 *
 * Even when arguments are passed in registers, the stack must have
 * space reserved for those arguments.  Thus the 5th argument (the
 * first non-register argument) is placed 32 bytes after the return
 * address.  Additionally, %rdi and %rsi must be preserved. (These
 * two registers are not scratch registers in the standard convention.)
 *
 * Note that in this template, we load a contrived 64 bit address into
 * %r11 to represent our jump address. This is to guarantee that the
 * assembler leaves enough room to patch in an absolute 64-bit address
 * later. The idea behind this code is that we want to avoid having to
 * manually create all the wrapper functions at compile time with
 * a bunch of macros. This is doable, but a) messy and b) requires
 * us to maintain two separate tables (one for the UNIX function
 * pointers and another with the wrappers). This means I'd have to
 * update two different tables each time I added a function.
 *
 * To avoid this, we create the wrappers at runtime instead. The
 * image patch tables now contain two pointers: one two the normal
 * routine, and a blank one for the wrapper. To construct a wrapper,
 * we allocate some memory and copy the template function into it,
 * then patch the function pointer for the routine we want to wrap
 * into the newly created wrapper. The subr_pe module can then
 * simply patch the wrapper routine into the jump table into the
 * windows image. As a bonus, the wrapper pointer not only serves
 * as the wrapper entry point address, it's also a data pointer
 * that we can pass to free() later when we unload the module.
 */

	.globl x86_64_wrap_call
	.globl x86_64_wrap_end

ENTRY(x86_64_wrap)
	subq	$96,%rsp	# allocate space on stack
	mov     %rsi,96-8(%rsp)	# save %rsi
	mov     %rdi,96-16(%rsp)# save %rdi
	mov	%rcx,%r10	# temporarily save %rcx in scratch
	mov	%rsp,%rsi
	add	$96+56,%rsi	# source == old stack top (stack+56)
	mov	%rsp,%rdi	# destination == new stack top
	mov	$10,%rcx	# count == 10 quadwords
	rep
	movsq			# copy old stack contents to new location
	mov	%r10,%rdi	# set up arg0 (%rcx -> %rdi)
	mov     %rdx,%rsi	# set up arg1 (%rdx -> %rsi)
	mov     %r8,%rdx	# set up arg2 (%r8 -> %rdx)
	mov     %r9,%rcx	# set up arg3 (%r9 -> %rcx)
	mov	96+40(%rsp),%r8	# set up arg4 (stack+40 -> %r8)
	mov	96+48(%rsp),%r9	# set up arg5 (stack+48 -> %r9)
	xor	%rax,%rax	# clear return value
x86_64_wrap_call:
	mov	$0xFF00FF00FF00FF00,%r11
	callq	*%r11		# call routine
	mov	96-16(%rsp),%rdi# restore %rdi
	mov	96-8(%rsp),%rsi	# restore %rsi
	addq	$96,%rsp	# delete space on stack
	ret
x86_64_wrap_end:

/*
 * Functions for invoking x86_64 callbacks.  In each case, the first
 * argument is a pointer to the function.
 */

ENTRY(x86_64_call1)
	subq	$8,%rsp
	mov	%rsi,%rcx
	call	*%rdi
	addq	$8,%rsp
	ret

ENTRY(x86_64_call2)
	subq	$24,%rsp
	mov	%rsi,%rcx
	/* %rdx is already correct */
	call	*%rdi
	addq	$24,%rsp
	ret

ENTRY(x86_64_call3)
	subq	$24,%rsp
	mov	%rcx,%r8
	mov	%rsi,%rcx
	call	*%rdi
	addq	$24,%rsp
	ret

ENTRY(x86_64_call4)
	subq	$40,%rsp
	mov	%r8,%r9
	mov	%rcx,%r8
	mov	%rsi,%rcx
	call	*%rdi
	addq	$40,%rsp
	ret

ENTRY(x86_64_call5)
	subq	$40,%rsp
	mov	%r9,32(%rsp)
	mov	%r8,%r9
	mov	%rcx,%r8
	mov	%rsi,%rcx
	call	*%rdi
	addq	$40,%rsp
	ret

ENTRY(x86_64_call6)
	subq	$56,%rsp
	mov	56+8(%rsp),%rax
	mov	%r9,32(%rsp)
	mov	%rax,40(%rsp)
	mov	%r8,%r9
	mov	%rcx,%r8
	mov	%rsi,%rcx
	call	*%rdi
	addq	$56,%rsp
	ret