#------------------------------------------------------------------------------
#
# OS X Application requires 16 byte stack alignment. The problem is these
# APIs are exposed to code that does not have this requirement via 
# EFI_UNIX_THUNK_PROTOCOL. So these are wrapper functions that make sure
# the stack is aligned. This code should also work if the stack is already
# aligned. Extra stack padding is really the same as local varaibles so 
# it gets freed by the leave instruction
#
# I basically used the compiler, added extra 16 bytes to the local stack and
# made sure %esp ended in 0 before the call (16 byte algined)
#
# The EFI_UNIX_THUNK_PROTOCOL member functions call a C API that then calls 
# one of these generic assembly routines.  We do it that way to work around 
# some magic name changing that happens in C. For example stat() is _stat() 
# on Leopard and _stat$INDOE64 on Snow Leopard. That is why we pass stat()
# into one of these gaskets from C code.
#
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution.  The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#------------------------------------------------------------------------------

#ifdef __APPLE__

  .text

#------------------------------------------------------------------------------
# int GasketVoid (void *api)
#------------------------------------------------------------------------------    
.globl _GasketVoid
_GasketVoid:
  pushl %ebp
  movl  %esp, %ebp
  subl  $34, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintn
_GasketUintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $50, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUintn
_GasketUintnUintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $50, %esp           # sub extra 0x10 from the stack for the AND 
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  16(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUintnUintn
_GasketUintnUintnUintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $50, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  20(%ebp), %eax
  movl  %eax, 8(%esp)
  movl  16(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUintnUintnUintn
_GasketUintnUintnUintnUintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $50, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  24(%ebp), %eax
  movl  %eax, 12(%esp)
  movl  20(%ebp), %eax
  movl  %eax, 8(%esp)
  movl  16(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUintnUintnUintnUintn
_GasketUintnUintnUintnUintnUintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $50, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  28(%ebp), %eax
  movl  %eax, 16(%esp)
  movl  24(%ebp), %eax
  movl  %eax, 12(%esp)
  movl  20(%ebp), %eax
  movl  %eax, 8(%esp)
  movl  16(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintn10Args
_GasketUintn10Args:
  pushl %ebp
  movl  %esp, %ebp
  subl  $82, %esp         # sub extra 0x10 from the stack for the AND
  and   $-16, %esp        # stack needs to end in 0xFFFFFFF0 before call
  movl  8(%ebp), %eax     
  movl  %eax, -12(%ebp)
  movl  48(%ebp), %eax
  movl  %eax, 36(%esp)
  movl  44(%ebp), %eax
  movl  %eax, 32(%esp)
  movl  40(%ebp), %eax
  movl  %eax, 28(%esp)
  movl  36(%ebp), %eax
  movl  %eax, 24(%esp)
  movl  32(%ebp), %eax
  movl  %eax, 20(%esp)
  movl  28(%ebp), %eax
  movl  %eax, 16(%esp)
  movl  24(%ebp), %eax
  movl  %eax, 12(%esp)
  movl  20(%ebp), %eax
  movl  %eax, 8(%esp)
  movl  16(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret


#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUint64Uintn
_GasketUint64Uintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $66, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  12(%ebp), %eax
  movl  %eax, -32(%ebp)
  movl  16(%ebp), %eax
  movl  %eax, -28(%ebp)
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  20(%ebp), %eax
  movl  %eax, 8(%esp)
  movl  -32(%ebp), %eax
  movl  -28(%ebp), %edx
  movl  %eax, (%esp)
  movl  %edx, 4(%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUint64Uintn
_GasketUintnUint64Uintn:
  pushl %ebp
  movl  %esp, %ebp
  subl  $66, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  16(%ebp), %eax
  movl  %eax, -32(%ebp)
  movl  20(%ebp), %eax
  movl  %eax, -28(%ebp)
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  24(%ebp), %eax
  movl  %eax, 12(%esp)
  movl  -32(%ebp), %eax
  movl  -28(%ebp), %edx
  movl  %eax, 4(%esp)
  movl  %edx, 8(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
.globl _GasketUintnUint16
_GasketUintnUint16:
  pushl %ebp
  movl  %esp, %ebp
  subl  $66, %esp           # sub extra 0x10 from the stack for the AND
  and   $-16, %esp          # stack needs to end in 0xFFFFFFF0 before call
  movl  16(%ebp), %eax
  movw  %ax, -28(%ebp)
  movl  8(%ebp), %eax
  movl  %eax, -12(%ebp)
  movzwl  -28(%ebp), %eax
  movl  %eax, 4(%esp)
  movl  12(%ebp), %eax
  movl  %eax, (%esp)
  movl  -12(%ebp), %eax
  call  *%eax
  leave
  ret
  
  
.globl _ReverseGasketUint64
_ReverseGasketUint64:
  pushl  %ebp
  movl  %esp, %ebp
  subl  $40, %esp
  movl  12(%ebp), %eax
  movl  %eax, -16(%ebp)
  movl  16(%ebp), %eax
  movl  %eax, -12(%ebp)
  movl  -16(%ebp), %eax
  movl  -12(%ebp), %edx
  movl  %eax, (%esp)
  movl  %edx, 4(%esp)
  movl  8(%ebp), %eax
  call  *%eax
  leave
  ret
  
  
.globl _ReverseGasketUint64Uint64
_ReverseGasketUint64Uint64:
  pushl   %ebp
  movl    %esp, %ebp
  subl    $56, %esp
  movl    12(%ebp), %eax
  movl    %eax, -32(%ebp)
  movl    16(%ebp), %eax
  movl    %eax, -28(%ebp)
  movl    20(%ebp), %eax
  movl    %eax, -40(%ebp)
  movl    24(%ebp), %eax
  movl    %eax, -36(%ebp)
  movl    8(%ebp), %eax
  movl    %eax, -12(%ebp)
  movl    -40(%ebp), %eax
  movl    -36(%ebp), %edx
  movl    %eax, 8(%esp)
  movl    %edx, 12(%esp)
  movl    -32(%ebp), %eax
  movl    -28(%ebp), %edx
  movl    %eax, (%esp)
  movl    %edx, 4(%esp)
  movl    -12(%ebp), %eax
  call    *%eax
  leave
  ret

  
// Sec PPI Callbacks

.globl _GasketSecUnixPeiLoadFile
_GasketSecUnixPeiLoadFile:
  jmp    _SecUnixPeiLoadFile


.globl _GasketSecUnixPeiAutoScan
_GasketSecUnixPeiAutoScan:
  jmp    _SecUnixPeiAutoScan


.globl _GasketSecUnixUnixThunkAddress
_GasketSecUnixUnixThunkAddress:
  jmp    _SecUnixUnixThunkAddress


.globl _GasketSecPeiReportStatusCode
_GasketSecPeiReportStatusCode:
  jmp    _SecPeiReportStatusCode


.globl _GasketSecUnixFdAddress
_GasketSecUnixFdAddress:
  jmp    _SecUnixFdAddress


.globl _GasketSecTemporaryRamSupport
_GasketSecTemporaryRamSupport:
  jmp    _SecTemporaryRamSupport
  
  #endif
