On 5 August 2016 at 21:24, Daniil Egranov <daniil.egra...@arm.com> wrote:
> 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.biesheu...@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.
>

Thanks for the report. I had a single patch and split it into two, and
apparently, I was sloppy

>>
>> //****************************************************************************
>>   // 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.
>
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to