1. Advance IP in case of Break(3) in breakpoint exception

2. Add stack management algorithm to avoid pool allocation during EBC instruction interpretation. 
3. Add multi EBC image support.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2519 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qhuang8
2007-03-30 08:44:55 +00:00
parent 784220c3f7
commit 73ebf379a4
13 changed files with 420 additions and 121 deletions

View File

@@ -44,6 +44,8 @@
#
# Destroys no working registers.
#****************************************************************************
.global _CopyMem;
# VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
.global _EbcLLCALLEXNative;
_EbcLLCALLEXNative:
@@ -56,7 +58,12 @@ _EbcLLCALLEXNative:
mov %rcx, %rbx
# Set stack pointer to new value
mov %rdx, %rsp
sub %r8, %rdx
sub %rsp, %r8
mov %rsp, %rcx
sub %rsp, 0x20
call _CopyMem
add %rsp, 0x20
# Considering the worst case, load 4 potiential arguments
# into registers.

View File

@@ -49,7 +49,11 @@ text SEGMENT
; Destroys no working registers.
;****************************************************************************
; VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
EbcLLCALLEXNative PROC
CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
EbcLLCALLEXNative PROC NEAR PUBLIC
push rbp
push rbx
mov rbp, rsp
@@ -59,7 +63,12 @@ EbcLLCALLEXNative PROC
mov rbx, rcx
; Set stack pointer to new value
mov rsp, rdx
sub r8, rdx
sub rsp, r8
mov rcx, rsp
sub rsp, 20h
call CopyMem
add rsp, 20h
; Considering the worst case, load 4 potiential arguments
; into registers.
@@ -92,7 +101,7 @@ EbcLLCALLEXNative ENDP
; Returns:
; The contents of the register in which the entry point is passed.
;
EbcLLGetEbcEntryPoint PROC
EbcLLGetEbcEntryPoint PROC NEAR PUBLIC
ret
EbcLLGetEbcEntryPoint ENDP
@@ -115,7 +124,7 @@ EbcLLGetEbcEntryPoint ENDP
;--*/
; UINTN EbcLLGetStackPointer()
EbcLLGetStackPointer PROC
EbcLLGetStackPointer PROC NEAR PUBLIC
mov rax, rsp ; get current stack pointer
; Stack adjusted by this much when we were called,
; For this function, it's 4.
@@ -136,7 +145,7 @@ EbcLLGetStackPointer ENDP
; Returns:
; The unmodified value returned by the native code.
;
EbcLLGetReturnValue PROC
EbcLLGetReturnValue PROC NEAR PUBLIC
ret
EbcLLGetReturnValue ENDP

View File

@@ -32,6 +32,8 @@ Abstract:
#define VM_STACK_SIZE (1024 * 8)
#define EBC_THUNK_SIZE 64
#define STACK_REMAIN_SIZE (1024 * 4)
STATIC
VOID
PushU64 (
@@ -71,7 +73,18 @@ EbcInterpret (
UINTN Arg2,
UINTN Arg3,
UINTN Arg4,
UINTN Arg5
UINTN Arg5,
UINTN Arg6,
UINTN Arg7,
UINTN Arg8,
UINTN Arg9,
UINTN Arg10,
UINTN Arg11,
UINTN Arg12,
UINTN Arg13,
UINTN Arg14,
UINTN Arg15,
UINTN Arg16
)
/*++
@@ -98,6 +111,8 @@ Returns:
//
VM_CONTEXT VmContext;
UINTN Addr;
EFI_STATUS Status;
UINTN StackIndex;
//
// Get the EBC entry point from the processor register.
@@ -125,8 +140,15 @@ Returns:
//
// Adjust the VM's stack pointer down.
//
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
Status = GetEBCStack((EFI_HANDLE)(UINTN)-1, &VmContext.StackPool, &StackIndex);
if (EFI_ERROR(Status)) {
return Status;
}
VmContext.StackTop = (UINT8*)VmContext.StackPool + (STACK_REMAIN_SIZE);
VmContext.R[0] = (UINT64) ((UINT8*)VmContext.StackPool + STACK_POOL_SIZE);
VmContext.HighStackBottom = (UINTN) VmContext.R[0];
VmContext.R[0] -= sizeof (UINTN);
//
// Align the stack on a natural boundary.
@@ -148,6 +170,18 @@ Returns:
// 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) Arg8);
PushU64 (&VmContext, (UINT64) Arg7);
PushU64 (&VmContext, (UINT64) Arg6);
PushU64 (&VmContext, (UINT64) Arg5);
PushU64 (&VmContext, (UINT64) Arg4);
PushU64 (&VmContext, (UINT64) Arg3);
PushU64 (&VmContext, (UINT64) Arg2);
@@ -178,7 +212,6 @@ Returns:
// the stack too, so adjust accordingly.
// VmContext.HighStackBottom = (UINTN)(Addr + sizeof (VmContext) + sizeof (Addr));
//
VmContext.HighStackBottom = (UINTN) &Arg5;
//
// Begin executing the EBC code
@@ -188,6 +221,7 @@ Returns:
//
// Return the value in R[7] unless there was an error
//
ReturnEBCStack(StackIndex);
return (UINT64) VmContext.R[7];
}
@@ -221,6 +255,8 @@ Returns:
//
VM_CONTEXT VmContext;
UINTN Addr;
EFI_STATUS Status;
UINTN StackIndex;
//
// Get the EBC entry point from the processor register. Make sure you don't
@@ -250,8 +286,16 @@ Returns:
// pointer and adjust it down by the max needed for the interpreter.
//
Addr = EbcLLGetStackPointer ();
VmContext.R[0] = (UINT64) Addr;
VmContext.R[0] -= VM_STACK_SIZE;
Status = GetEBCStack(ImageHandle, &VmContext.StackPool, &StackIndex);
if (EFI_ERROR(Status)) {
return Status;
}
VmContext.StackTop = (UINT8*)VmContext.StackPool + (STACK_REMAIN_SIZE);
VmContext.R[0] = (UINT64) ((UINT8*)VmContext.StackPool + STACK_POOL_SIZE);
VmContext.HighStackBottom = (UINTN) VmContext.R[0];
VmContext.R[0] -= sizeof (UINTN);
//
// Put a magic value in the stack gap, then adjust down again
@@ -287,7 +331,6 @@ Returns:
// Entry function needn't access high stack context, simply
// put the stack pointer here.
//
VmContext.HighStackBottom = (UINTN) Addr;
//
// Begin executing the EBC code
@@ -297,6 +340,7 @@ Returns:
//
// Return the value in R[7] unless there was an error
//
ReturnEBCStack(StackIndex);
return (UINT64) VmContext.R[7];
}