public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Daniil Egranov <daniil.egranov@arm.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	leif.lindholm@linaro.org, edk2-devel@lists.01.org
Cc: feng.tian@intel.com, daniil.egranov@linaro.org, star.zeng@intel.com
Subject: Re: [PATCH 2/2] MdeModulePkg/EbcDxe: cleanup
Date: Fri, 5 Aug 2016 14:24:07 -0500	[thread overview]
Message-ID: <c9776331-3709-a5c5-ca58-bcecacc8f898@arm.com> (raw)
In-Reply-To: <1470061349-29611-2-git-send-email-ard.biesheuvel@linaro.org>

Hi Ard,


On 08/01/2016 09:22 AM, Ard Biesheuvel wrote:
> - indentation
> - premature optimization of the thunking code, i.e., align function prototypes
>    so we don't have to move arguments around or duplicate them on the stack,
>    and perform tail calls where possible
> - adhere to calling convention (stack frame layout)
> - replace instruction buffer with a fixed struct, so that we no longer have
>    to traverse it to find the entry point slots
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>   MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S | 188 ++++++++++---------
>   MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c  | 193 ++++++--------------
>   2 files changed, 159 insertions(+), 222 deletions(-)
>
> diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S
> index 3c1a461f5e87..d0a5a4c5a37d 100644
> --- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S
> +++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcLowLevel.S
> @@ -1,10 +1,12 @@
>   ///** @file
>   //
> -//    This code provides low level routines that support the Virtual Machine
> -//   for option ROMs.
> +//  This code provides low level routines that support the Virtual Machine
> +//  for option ROMs.
>   //
> -//  Copyright (c) 2015, The Linux Foundation. All rights reserved.
> +//  Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
> +//  Copyright (c) 2015, The Linux Foundation. All rights reserved.<BR>
>   //  Copyright (c) 2007 - 2014, Intel Corporation. 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
> @@ -15,9 +17,10 @@
>   //
>   //**/
>   
> -ASM_GLOBAL ASM_PFX(CopyMem);
> -ASM_GLOBAL ASM_PFX(EbcInterpret);
> -ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint);
> +ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret);
> +ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint);
> +
> +ASM_GLOBAL ASM_PFX(mEbcInstructionBufferTemplate);
The ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative); is missing here. The linking 
fails without it.
>   
>   //****************************************************************************
>   // EbcLLCALLEX
> @@ -30,102 +33,121 @@ ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint);
>   //
>   //****************************************************************************
>   // UINTN EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
> -ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative);
>   ASM_PFX(EbcLLCALLEXNative):
> -      stp  x19, x20, [sp, #-16]!
> -      stp  x29, x30, [sp, #-16]!
> -
> -      mov  x19, x0
> -      mov  x20, sp
> -      sub  x2, x2, x1   // Length = NewStackPointer-FramePtr
> -      sub  sp, sp, x2
> -      sub  sp, sp, #64  // Make sure there is room for at least 8 args in the new stack
> -      mov  x0, sp
> -
> -      bl   CopyMem      // Sp, NewStackPointer, Length
> -
> -      ldp  x0, x1, [sp], #16
> -      ldp  x2, x3, [sp], #16
> -      ldp  x4, x5, [sp], #16
> -      ldp  x6, x7, [sp], #16
> -
> -      blr  x19
> -
> -      mov  sp,  x20
> -      ldp  x29, x30, [sp], #16
> -      ldp  x19, x20, [sp], #16
> -
> -      ret
> +    mov     x8, x0                 // Preserve x0
> +    mov     x9, x1                 // Preserve x1
> +
> +    //
> +    // If the EBC stack frame is smaller than or equal to 64 bytes, we know there
> +    // are no stacked arguments #9 and beyond that we need to copy to the native
> +    // stack. In this case, we can perform a tail call which is much more
> +    // efficient, since there is no need to touch the native stack at all.
> +    //
> +    sub     x3, x2, x1              // Length = NewStackPointer - FramePtr
> +    cmp     x3, #64
> +    b.gt    1f
> +
> +    adr     x0, 0f
> +    sub     x0, x0, x3, lsr #1
> +    br      x0
> +
> +    ldr     x7, [x9, #56]
> +    ldr     x6, [x9, #48]
> +    ldr     x5, [x9, #40]
> +    ldr     x4, [x9, #32]
> +    ldr     x3, [x9, #24]
> +    ldr     x2, [x9, #16]
> +    ldr     x1, [x9, #8]
> +    ldr     x0, [x9]
> +
> +0:  br      x8
> +
> +    //
> +    // More than 64 bytes: we need to build the full native stack frame and copy
> +    // the part of the VM stack exceeding 64 bytes (which may contain stacked
> +    // arguments) to the native stack
> +    //
> +1:  stp     x29, x30, [sp, #-16]!
> +    mov     x29, sp
> +
> +    //
> +    // Ensure that the stack pointer remains 16 byte aligned,
> +    // even if the size of the VM stack frame is not a multiple of 16
> +    //
> +    add     x1, x1, #64             // Skip over [potential] reg params
> +    tbz     x3, #3, 2f              // Multiple of 16?
> +    ldr     x4, [x2, #-8]!          // No? Then push one word
> +    str     x4, [sp, #-16]!         // ... but use two slots
> +    b       3f
> +
> +2:  ldp     x4, x5, [x2, #-16]!
> +    stp     x4, x5, [sp, #-16]!
> +3:  cmp     x2, x1
> +    b.gt    2b
> +
> +    ldp     x0, x1, [x9]
> +    ldp     x2, x3, [x9, #16]
> +    ldp     x4, x5, [x9, #32]
> +    ldp     x6, x7, [x9, #48]
> +
> +    blr     x8
> +
> +    mov     sp, x29
> +    ldp     x29, x30, [sp], #16
> +    ret
>   
>   //****************************************************************************
>   // EbcLLEbcInterpret
>   //
>   // This function is called by the thunk code to handle an Native to EBC call
>   // This can handle up to 16 arguments (1-8 on in x0-x7, 9-16 are on the stack)
> -// x9 contains the Entry point that will be the first argument when
> +// x16 contains the Entry point that will be the first argument when
>   // EBCInterpret is called.
>   //
>   //****************************************************************************
> -ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret);
>   ASM_PFX(EbcLLEbcInterpret):
> -    stp  x29, x30, [sp, #-16]!
> -
> -    // copy the current arguments 9-16 from old location and add arg 7 to stack
> -    // keeping 16 byte stack alignment
> -    sub sp, sp, #80
> -    str x7, [sp]
> -    ldr x11, [sp, #96]
> -    str x11, [sp, #8]
> -    ldr x11, [sp, #104]
> -    str x11, [sp, #16]
> -    ldr x11, [sp, #112]
> -    str x11, [sp, #24]
> -    ldr x11, [sp, #120]
> -    str x11, [sp, #32]
> -    ldr x11, [sp, #128]
> -    str x11, [sp, #40]
> -    ldr x11, [sp, #136]
> -    str x11, [sp, #48]
> -    ldr x11, [sp, #144]
> -    str x11, [sp, #56]
> -    ldr x11, [sp, #152]
> -    str x11, [sp, #64]
> -
> -    // Shift arguments and add entry point and as argument 1
> -    mov x7, x6
> -    mov x6, x5
> -    mov x5, x4
> -    mov x4, x3
> -    mov x3, x2
> -    mov x2, x1
> -    mov x1, x0
> -    mov x0, x9
> -
> -    # call C-code
> -    bl ASM_PFX(EbcInterpret)
> -    add sp, sp, #80
> -
> -    ldp  x29, x30, [sp], #16
> +    stp     x29, x30, [sp, #-16]!
> +    mov     x29, sp
> +
> +    // push the entry point and the address of args #9 - #16 onto the stack
> +    add     x17, sp, #16
> +    stp     x16, x17, [sp, #-16]!
>   
> +    // call C-code
> +    bl      ASM_PFX(EbcInterpret)
> +
> +    ldp     x29, x30, [sp, #16]
> +    add     sp, sp, #32
>       ret
>   
>   //****************************************************************************
>   // EbcLLExecuteEbcImageEntryPoint
>   //
>   // This function is called by the thunk code to handle the image entry point
> -// x9 contains the Entry point that will be the first argument when
> +// x16 contains the Entry point that will be the third argument when
>   // ExecuteEbcImageEntryPoint is called.
>   //
>   //****************************************************************************
> -ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint);
>   ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
> -    stp  x29, x30, [sp, #-16]!
> -    # build new paramater calling convention
> -    mov  x2, x1
> -    mov  x1, x0
> -    mov  x0, x9
> -
> -    # call C-code
> -    bl ASM_PFX(ExecuteEbcImageEntryPoint)
> -    ldp  x29, x30, [sp], #16
> -    ret
> +    mov     x2, x16
> +
> +    // tail call to C code
> +    b       ASM_PFX(ExecuteEbcImageEntryPoint)
> +
> +//****************************************************************************
> +// mEbcInstructionBufferTemplate
> +//****************************************************************************
> +    .section    ".rodata", "a"
> +    .align      3
> +ASM_PFX(mEbcInstructionBufferTemplate):
> +    adr     x17, 0f
> +    ldp     x16, x17, [x17]
> +    br      x17
> +
> +    //
> +    // Add a magic code here to help the VM recognize the thunk.
> +    //
> +    .long   0xCA112EBC
> +
> +0:  .quad   0   // EBC_ENTRYPOINT_SIGNATURE
> +    .quad   0   // EBC_LL_EBC_ENTRYPOINT_SIGNATURE
> diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
> index 23261a070143..d15bbc861f33 100644
> --- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
> +++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c
> @@ -2,8 +2,10 @@
>     This module contains EBC support routines that are customized based on
>     the target AArch64 processor.
>   
> -Copyright (c) 2015, The Linux Foundation. All rights reserved.
> +Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
> +Copyright (c) 2015, The Linux Foundation. All rights reserved.<BR>
>   Copyright (c) 2006 - 2014, Intel Corporation. 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
> @@ -22,47 +24,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>   //
>   #define STACK_REMAIN_SIZE (1024 * 4)
>   
> -//
> -// This is instruction buffer used to create EBC thunk
> -//
> -#define EBC_MAGIC_SIGNATURE                0xCA112EBCCA112EBCull
> -#define EBC_ENTRYPOINT_SIGNATURE           0xAFAFAFAFAFAFAFAFull
> -#define EBC_LL_EBC_ENTRYPOINT_SIGNATURE    0xFAFAFAFAFAFAFAFAull
> -UINT8  mInstructionBufferTemplate[] = {
> -  0x03,  0x00, 0x00, 0x14, //b pc+16
> -  //
> -  // Add a magic code here to help the VM recognize the thunk..
> -  //
> -    (UINT8)(EBC_MAGIC_SIGNATURE & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 8) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 16) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 24) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 32) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 40) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 48) & 0xFF),
> -    (UINT8)((EBC_MAGIC_SIGNATURE >> 56) & 0xFF),
> -  0x69, 0x00, 0x00, 0x58, //ldr x9, #32
> -  0x8A, 0x00, 0x00, 0x58, //ldr x10, #40
> -  0x05, 0x00, 0x00, 0x14, //b pc+32
> -    (UINT8)(EBC_ENTRYPOINT_SIGNATURE & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
> -    (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
> -    (UINT8)(EBC_LL_EBC_ENTRYPOINT_SIGNATURE & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
> -    (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
> -  0x40, 0x01, 0x1F, 0xD6 //br x10
> -
> -};
> +#pragma pack(1)
> +typedef struct {
> +  UINT32    Instr[3];
> +  UINT32    Magic;
> +  UINT64    EbcEntryPoint;
> +  UINT64    EbcLlEntryPoint;
> +} EBC_INSTRUCTION_BUFFER;
> +#pragma pack()
> +
> +extern CONST EBC_INSTRUCTION_BUFFER       mEbcInstructionBufferTemplate;
>   
>   /**
>     Begin executing an EBC image.
> @@ -109,7 +80,6 @@ PushU64 (
>     //
>     VmPtr->Gpr[0] -= sizeof (UINT64);
>     *(UINT64 *) VmPtr->Gpr[0] = Arg;
> -  return;
>   }
>   
>   
> @@ -118,7 +88,6 @@ PushU64 (
>   
>     This is a thunk function.
>   
> -  @param  EntryPoint            The entrypoint of EBC code.
>     @param  Arg1                  The 1st argument.
>     @param  Arg2                  The 2nd argument.
>     @param  Arg3                  The 3rd argument.
> @@ -127,14 +96,8 @@ PushU64 (
>     @param  Arg6                  The 6th argument.
>     @param  Arg7                  The 7th argument.
>     @param  Arg8                  The 8th argument.
> -  @param  Arg9                  The 9th argument.
> -  @param  Arg10                 The 10th argument.
> -  @param  Arg11                 The 11th argument.
> -  @param  Arg12                 The 12th argument.
> -  @param  Arg13                 The 13th argument.
> -  @param  Arg14                 The 14th argument.
> -  @param  Arg15                 The 15th argument.
> -  @param  Arg16                 The 16th argument.
> +  @param  EntryPoint            The entrypoint of EBC code.
> +  @param  Args9_16[]            Array containing arguments #9 to #16.
>   
>     @return The value returned by the EBC application we're going to run.
>   
> @@ -142,7 +105,6 @@ PushU64 (
>   UINT64
>   EFIAPI
>   EbcInterpret (
> -  IN UINTN      EntryPoint,
>     IN UINTN      Arg1,
>     IN UINTN      Arg2,
>     IN UINTN      Arg3,
> @@ -151,14 +113,8 @@ EbcInterpret (
>     IN UINTN      Arg6,
>     IN UINTN      Arg7,
>     IN UINTN      Arg8,
> -  IN UINTN      Arg9,
> -  IN UINTN      Arg10,
> -  IN UINTN      Arg11,
> -  IN UINTN      Arg12,
> -  IN UINTN      Arg13,
> -  IN UINTN      Arg14,
> -  IN UINTN      Arg15,
> -  IN UINTN      Arg16
> +  IN UINTN      EntryPoint,
> +  IN UINTN      Args9_16[]
>     )
>   {
>     //
> @@ -222,14 +178,14 @@ EbcInterpret (
>     // For the worst case, assume there are 4 arguments passed in registers, store
>     // them to VM's stack.
>     //
> -  PushU64 (&VmContext, (UINT64) Arg16);
> -  PushU64 (&VmContext, (UINT64) Arg15);
> -  PushU64 (&VmContext, (UINT64) Arg14);
> -  PushU64 (&VmContext, (UINT64) Arg13);
> -  PushU64 (&VmContext, (UINT64) Arg12);
> -  PushU64 (&VmContext, (UINT64) Arg11);
> -  PushU64 (&VmContext, (UINT64) Arg10);
> -  PushU64 (&VmContext, (UINT64) Arg9);
> +  PushU64 (&VmContext, (UINT64) Args9_16[7]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[6]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[5]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[4]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[3]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[2]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[1]);
> +  PushU64 (&VmContext, (UINT64) Args9_16[0]);
>     PushU64 (&VmContext, (UINT64) Arg8);
>     PushU64 (&VmContext, (UINT64) Arg7);
>     PushU64 (&VmContext, (UINT64) Arg6);
> @@ -281,10 +237,10 @@ EbcInterpret (
>   /**
>     Begin executing an EBC image.
>   
> -  @param  EntryPoint       The entrypoint of EBC code.
>     @param  ImageHandle      image handle for the EBC application we're executing
>     @param  SystemTable      standard system table passed into an driver's entry
>                              point
> +  @param  EntryPoint       The entrypoint of EBC code.
>   
>     @return The value returned by the EBC application we're going to run.
>   
> @@ -292,9 +248,9 @@ EbcInterpret (
>   UINT64
>   EFIAPI
>   ExecuteEbcImageEntryPoint (
> -  IN UINTN                EntryPoint,
>     IN EFI_HANDLE           ImageHandle,
> -  IN EFI_SYSTEM_TABLE     *SystemTable
> +  IN EFI_SYSTEM_TABLE     *SystemTable,
> +  IN UINTN                EntryPoint
>     )
>   {
>     //
> @@ -335,7 +291,7 @@ ExecuteEbcImageEntryPoint (
>     if (EFI_ERROR(Status)) {
>       return Status;
>     }
> -  VmContext.StackTop = (UINT8*)VmContext.StackPool + (STACK_REMAIN_SIZE);
> +  VmContext.StackTop = (UINT8 *)VmContext.StackPool + (STACK_REMAIN_SIZE);
>     VmContext.Gpr[0] = (UINT64) ((UINT8*)VmContext.StackPool + STACK_POOL_SIZE);
>     VmContext.HighStackBottom = (UINTN) VmContext.Gpr[0];
>     VmContext.Gpr[0] -= sizeof (UINTN);
> @@ -372,11 +328,6 @@ ExecuteEbcImageEntryPoint (
>     VmContext.StackRetAddr  = (UINT64) VmContext.Gpr[0];
>   
>     //
> -  // Entry function needn't access high stack context, simply
> -  // put the stack pointer here.
> -  //
> -
> -  //
>     // Begin executing the EBC code
>     //
>     EbcExecute (&VmContext);
> @@ -414,10 +365,7 @@ EbcCreateThunks (
>     IN  UINT32              Flags
>     )
>   {
> -  UINT8       *Ptr;
> -  UINT8       *ThunkBase;
> -  UINT32      Index;
> -  INT32       ThunkSize;
> +  EBC_INSTRUCTION_BUFFER       *InstructionBuffer;
>   
>     //
>     // Check alignment of pointer to EBC code
> @@ -426,51 +374,38 @@ EbcCreateThunks (
>       return EFI_INVALID_PARAMETER;
>     }
>   
> -  ThunkSize = sizeof(mInstructionBufferTemplate);
> -
> -  Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
> -
> -  if (Ptr == NULL) {
> +  InstructionBuffer = AllocatePool (sizeof (EBC_INSTRUCTION_BUFFER));
> +  if (InstructionBuffer == NULL) {
>       return EFI_OUT_OF_RESOURCES;
>     }
> -  //
> -  //  Print(L"Allocate TH: 0x%X\n", (UINT32)Ptr);
> -  //
> -  // Save the start address so we can add a pointer to it to a list later.
> -  //
> -  ThunkBase = Ptr;
>   
>     //
>     // Give them the address of our buffer we're going to fix up
>     //
> -  *Thunk = (VOID *) Ptr;
> +  *Thunk = InstructionBuffer;
>   
>     //
>     // Copy whole thunk instruction buffer template
>     //
> -  CopyMem (Ptr, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate));
> +  CopyMem (InstructionBuffer, &mEbcInstructionBufferTemplate,
> +    sizeof (EBC_INSTRUCTION_BUFFER));
>   
>     //
>     // Patch EbcEntryPoint and EbcLLEbcInterpret
>     //
> -  for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
> -    if (*(UINTN *)&Ptr[Index] == EBC_ENTRYPOINT_SIGNATURE) {
> -      *(UINTN *)&Ptr[Index] = (UINTN)EbcEntryPoint;
> -    }
> -    if (*(UINTN *)&Ptr[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
> -      if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
> -        *(UINTN *)&Ptr[Index] = (UINTN)EbcLLExecuteEbcImageEntryPoint;
> -      } else {
> -        *(UINTN *)&Ptr[Index] = (UINTN)EbcLLEbcInterpret;
> -      }
> -    }
> +  InstructionBuffer->EbcEntryPoint = (UINT64)EbcEntryPoint;
> +  if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
> +    InstructionBuffer->EbcLlEntryPoint = (UINT64)EbcLLExecuteEbcImageEntryPoint;
> +  } else {
> +    InstructionBuffer->EbcLlEntryPoint = (UINT64)EbcLLEbcInterpret;
>     }
>   
>     //
>     // Add the thunk to the list for this image. Do this last since the add
>     // function flushes the cache for us.
>     //
> -  EbcAddImageThunk (ImageHandle, (VOID *) ThunkBase, ThunkSize);
> +  EbcAddImageThunk (ImageHandle, InstructionBuffer,
> +    sizeof (EBC_INSTRUCTION_BUFFER));
>   
>     return EFI_SUCCESS;
>   }
> @@ -500,40 +435,15 @@ EbcLLCALLEX (
>     IN UINT8        Size
>     )
>   {
> -  UINTN    IsThunk;
> -  UINTN    TargetEbcAddr;
> -  UINT8    InstructionBuffer[sizeof(mInstructionBufferTemplate)];
> -  UINTN    Index;
> -  UINTN    IndexOfEbcEntrypoint;
> -
> -  IsThunk       = 1;
> -  TargetEbcAddr = 0;
> -  IndexOfEbcEntrypoint = 0;
> +  CONST EBC_INSTRUCTION_BUFFER *InstructionBuffer;
>   
>     //
>     // Processor specific code to check whether the callee is a thunk to EBC.
>     //
> -  CopyMem (InstructionBuffer, (VOID *)FuncAddr, sizeof(InstructionBuffer));
> -  //
> -  // Fill the signature according to mInstructionBufferTemplate
> -  //
> -  for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
> -    if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_ENTRYPOINT_SIGNATURE) {
> -      *(UINTN *)&InstructionBuffer[Index] = EBC_ENTRYPOINT_SIGNATURE;
> -      IndexOfEbcEntrypoint = Index;
> -    }
> -    if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
> -      *(UINTN *)&InstructionBuffer[Index] = EBC_LL_EBC_ENTRYPOINT_SIGNATURE;
> -    }
> -  }
> -  //
> -  // Check if we need thunk to native
> -  //
> -  if (CompareMem (InstructionBuffer, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate)) != 0) {
> -    IsThunk = 0;
> -  }
> +  InstructionBuffer = (EBC_INSTRUCTION_BUFFER *)FuncAddr;
>   
> -  if (IsThunk == 1){
> +  if (CompareMem (InstructionBuffer, &mEbcInstructionBufferTemplate,
> +        sizeof(EBC_INSTRUCTION_BUFFER) - 2 * sizeof (UINT64)) == 0) {
>       //
>       // The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
>       // put our return address and frame pointer on the VM stack.
> @@ -545,14 +455,19 @@ EbcLLCALLEX (
>       VmPtr->Gpr[0] -= 8;
>       VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (UINTN) (VmPtr->Ip + Size));
>   
> -    CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + IndexOfEbcEntrypoint, sizeof(UINTN));
> -    VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
> +    VmPtr->Ip = (VMIP) InstructionBuffer->EbcEntryPoint;
>     } else {
>       //
>       // The callee is not a thunk to EBC, call native code,
>       // and get return value.
>       //
> -    VmPtr->Gpr[7] = EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);
> +    // Note that we will not be able to distinguish which part of the interval
> +    // [NewStackPointer, FramePtr) consists of stacked function arguments for
> +    // this call, and which part simply consists of locals in the caller's
> +    // stack frame. All we know is that there is an 8 byte gap at the top that
> +    // we can ignore.
> +    //
> +    VmPtr->Gpr[7] = EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr - 8);
>   
>       //
>       // Advance the IP.



  reply	other threads:[~2016-08-05 19:24 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-01 14:22 [PATCH 1/2] MdeModulePkg/EbcDxe AARCH64: fix comment style Ard Biesheuvel
2016-08-01 14:22 ` [PATCH 2/2] MdeModulePkg/EbcDxe: cleanup Ard Biesheuvel
2016-08-05 19:24   ` Daniil Egranov [this message]
2016-08-05 19:27     ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c9776331-3709-a5c5-ca58-bcecacc8f898@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox