summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/Ebc
diff options
context:
space:
mode:
authormikewuping <mikewuping@6f19259b-4bc3-4df7-8a09-765794883524>2006-11-03 03:34:43 +0000
committermikewuping <mikewuping@6f19259b-4bc3-4df7-8a09-765794883524>2006-11-03 03:34:43 +0000
commitc91eaa3d55d88598baaa979097a31cb1001ecc0d (patch)
tree222ee4336cc2884c432a7f2ce14561a4a953c6b7 /EdkModulePkg/Universal/Ebc
parent511710d68f477e0210ae1830769e5d0cde4ea36a (diff)
downloadedk2-c91eaa3d55d88598baaa979097a31cb1001ecc0d.zip
edk2-c91eaa3d55d88598baaa979097a31cb1001ecc0d.tar.gz
edk2-c91eaa3d55d88598baaa979097a31cb1001ecc0d.tar.bz2
I fixed following bugs in EDKII.
1. In AsmFuncs.asm, DebugSupport, Vect2Desc() function will use hardcode CS to fill the IDT. 20h for Ia32.If the system CS is changed by CPU driver, this driver can not work. System maybe crash. 2. In EBC, RegisterExceptionCallback() can not restore the environment and I add some enhancements. 3. In Image.c, CoreLoadImageCommon never return EFI_SECURITY_VIOLATION when SecurityStatus == EFI_SECURITY_VIOLATION. 4. In Variable.c, 1. There're additional unnecessary loop. All blocks will be gone through even if all the data has been written. We should check the "CurrWriteSize" to see if there's no more data to write, and stop the for loop immediately. 2 "if.else." can be merged to save lines of code. 5. in FvbServices,c, Checksum calculation error. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1891 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/Ebc')
-rw-r--r--EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c2
-rw-r--r--EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c418
-rw-r--r--EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h2
3 files changed, 285 insertions, 137 deletions
diff --git a/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c b/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c
index 13e2d7c..70db157 100644
--- a/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c
+++ b/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c
@@ -685,6 +685,7 @@ Returns:
EFI_STATUS Status;
EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL *EbcSimpleDebugger;
+ mVmPtr = VmPtr;
EbcSimpleDebugger = NULL;
Status = EFI_SUCCESS;
StackCorrupted = 0;
@@ -779,6 +780,7 @@ Returns:
}
Done:
+ mVmPtr = NULL;
return Status;
}
diff --git a/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c b/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c
index 2a5d48a..e38f5be 100644
--- a/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c
+++ b/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.c
@@ -77,6 +77,32 @@ EbcGetVersion (
IN OUT UINT64 *Version
);
+EFI_STATUS
+EFIAPI
+InitializeEbcCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This
+ );
+
+VOID
+EFIAPI
+CommonEbcExceptionHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ );
+
+VOID
+EFIAPI
+EbcPeriodicNotifyFunction (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+EbcDebugPeriodic (
+ IN VM_CONTEXT *VmPtr
+ );
+
//
// These two functions and the GUID are used to produce an EBC test protocol.
// This functionality is definitely not required for execution.
@@ -158,6 +184,12 @@ static EFI_PERIODIC_CALLBACK mDebugPeriodicCallback
static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL};
static EFI_GUID mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID;
+//
+// Event for Periodic callback
+//
+static EFI_EVENT mEbcPeriodicEvent;
+VM_CONTEXT *mVmPtr = NULL;
+
EFI_STATUS
EFIAPI
InitializeEbcDriver (
@@ -190,6 +222,9 @@ Returns:
UINTN Index;
BOOLEAN Installed;
+ EbcProtocol = NULL;
+ EbcDebugProtocol = NULL;
+
//
// Allocate memory for our protocol. Then fill in the blanks.
//
@@ -271,7 +306,7 @@ Returns:
(VOID **) &EbcDebugProtocol
);
if (Status != EFI_SUCCESS) {
- return EFI_OUT_OF_RESOURCES;
+ goto ErrorExit;
}
EbcDebugProtocol->Isa = IsaEbc;
@@ -294,14 +329,59 @@ Returns:
//
if (EFI_ERROR (Status)) {
gBS->FreePool (EbcDebugProtocol);
+ goto ErrorExit;
}
//
+ // Install EbcDebugSupport Protocol Successfully
+ // Now we need to initialize the Ebc default Callback
+ //
+ Status = InitializeEbcCallback (EbcDebugProtocol);
+
+ //
// Produce a VM test interface protocol. Not required for execution.
//
DEBUG_CODE_BEGIN ();
InitEbcVmTestProtocol (&ImageHandle);
DEBUG_CODE_END ();
+ return EFI_SUCCESS;
+
+ErrorExit:
+ HandleBuffer = NULL;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiEbcProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Loop through the handles
+ //
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiEbcProtocolGuid,
+ (VOID **) &OldEbcProtocol
+ );
+ if (Status == EFI_SUCCESS) {
+ gBS->UninstallProtocolInterface (
+ HandleBuffer[Index],
+ &gEfiEbcProtocolGuid,
+ OldEbcProtocol
+ );
+ }
+ }
+ }
+
+ if (HandleBuffer != NULL) {
+ gBS->FreePool (HandleBuffer);
+ HandleBuffer = NULL;
+ }
+
+ gBS->FreePool (EbcProtocol);
+
return Status;
}
@@ -508,8 +588,8 @@ Returns:
{
EFI_SYSTEM_CONTEXT_EBC EbcContext;
EFI_SYSTEM_CONTEXT SystemContext;
- EFI_STATUS_CODE_VALUE StatusCodeValue;
- BOOLEAN Report;
+
+ ASSERT ((ExceptionType >= 0) && (ExceptionType <= MAX_EBC_EXCEPTION));
//
// Save the exception in the context passed in
//
@@ -522,156 +602,179 @@ Returns:
if (ExceptionFlags & EXCEPTION_FLAG_FATAL) {
VmPtr->StopFlags |= STOPFLAG_APP_DONE;
}
- //
- // Initialize the context structure
- //
- EbcContext.R0 = VmPtr->R[0];
- EbcContext.R1 = VmPtr->R[1];
- EbcContext.R2 = VmPtr->R[2];
- EbcContext.R3 = VmPtr->R[3];
- EbcContext.R4 = VmPtr->R[4];
- EbcContext.R5 = VmPtr->R[5];
- EbcContext.R6 = VmPtr->R[6];
- EbcContext.R7 = VmPtr->R[7];
- EbcContext.Ip = (UINT64) (UINTN) VmPtr->Ip;
- EbcContext.Flags = VmPtr->Flags;
- EbcContext.ControlFlags = 0;
- SystemContext.SystemContextEbc = &EbcContext;
+
//
// If someone's registered for exception callbacks, then call them.
- // Otherwise report the status code via the status code API
//
- if ((ExceptionType >= 0) && (ExceptionType <= MAX_EBC_EXCEPTION) &&
- (mDebugExceptionCallback[ExceptionType] != NULL)) {
+ // EBC driver will register default exception callback to report the
+ // status code via the status code API
+ //
+ if (mDebugExceptionCallback[ExceptionType] != NULL) {
+
+ //
+ // Initialize the context structure
+ //
+ EbcContext.R0 = VmPtr->R[0];
+ EbcContext.R1 = VmPtr->R[1];
+ EbcContext.R2 = VmPtr->R[2];
+ EbcContext.R3 = VmPtr->R[3];
+ EbcContext.R4 = VmPtr->R[4];
+ EbcContext.R5 = VmPtr->R[5];
+ EbcContext.R6 = VmPtr->R[6];
+ EbcContext.R7 = VmPtr->R[7];
+ EbcContext.Ip = (UINT64)(UINTN)VmPtr->Ip;
+ EbcContext.Flags = VmPtr->Flags;
+ EbcContext.ControlFlags = 0;
+ SystemContext.SystemContextEbc = &EbcContext;
+
mDebugExceptionCallback[ExceptionType] (ExceptionType, SystemContext);
+ //
+ // Restore the context structure and continue to execute
+ //
+ VmPtr->R[0] = EbcContext.R0;
+ VmPtr->R[1] = EbcContext.R1;
+ VmPtr->R[2] = EbcContext.R2;
+ VmPtr->R[3] = EbcContext.R3;
+ VmPtr->R[4] = EbcContext.R4;
+ VmPtr->R[5] = EbcContext.R5;
+ VmPtr->R[6] = EbcContext.R6;
+ VmPtr->R[7] = EbcContext.R7;
+ VmPtr->Ip = (VMIP)(UINTN)EbcContext.Ip;
+ VmPtr->Flags = EbcContext.Flags;
}
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeEbcCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ To install default Callback function for the VM interpreter.
+
+Arguments:
+
+ This - pointer to the instance of DebugSupport protocol
+
+Returns:
+
+ None
+
+--*/
+{
+ INTN Index;
+ EFI_STATUS Status;
+
//
- // Determine if we should report the exception. We report all of them by default,
- // but if a debugger is attached don't report the breakpoint, debug, and step exceptions.
- // Note that EXCEPT_EBC_OVERFLOW is never reported by this VM implementation, so is
- // not included in the switch statement.
- //
- Report = TRUE;
- switch (ExceptionType) {
- case EXCEPT_EBC_UNDEFINED:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_UNDEFINED;
- break;
-
- case EXCEPT_EBC_DIVIDE_ERROR:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_DIVIDE_ERROR;
- break;
-
- case EXCEPT_EBC_DEBUG:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_DEBUG;
- Report = (BOOLEAN) ((mDebugExceptionCallback[ExceptionType] == NULL) ? TRUE : FALSE);
- break;
-
- case EXCEPT_EBC_BREAKPOINT:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_BREAKPOINT;
- Report = (BOOLEAN) ((mDebugExceptionCallback[ExceptionType] == NULL) ? TRUE : FALSE);
- break;
-
- case EXCEPT_EBC_INVALID_OPCODE:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_INVALID_OPCODE;
- break;
-
- case EXCEPT_EBC_STACK_FAULT:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_STACK_FAULT;
- break;
-
- case EXCEPT_EBC_ALIGNMENT_CHECK:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_ALIGNMENT_CHECK;
- break;
-
- case EXCEPT_EBC_INSTRUCTION_ENCODING:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_INSTRUCTION_ENCODING;
- break;
-
- case EXCEPT_EBC_BAD_BREAK:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_BAD_BREAK;
- break;
-
- case EXCEPT_EBC_STEP:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_EBC_STEP;
- Report = (BOOLEAN) ((mDebugExceptionCallback[ExceptionType] == NULL) ? TRUE : FALSE);
- break;
-
- default:
- StatusCodeValue = EFI_SOFTWARE_EBC_EXCEPTION | EFI_SW_EC_NON_SPECIFIC;
- break;
+ // For ExceptionCallback
+ //
+ for (Index = 0; Index <= MAX_EBC_EXCEPTION; Index++) {
+ EbcDebugRegisterExceptionCallback (
+ This,
+ 0,
+ CommonEbcExceptionHandler,
+ Index
+ );
}
+
//
- // If we determined that we should report the condition, then do so now.
+ // For PeriodicCallback
//
- if (Report) {
- REPORT_STATUS_CODE (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, StatusCodeValue);
+ Status = gBS->CreateEvent (
+ EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_NOTIFY,
+ EbcPeriodicNotifyFunction,
+ &mVmPtr,
+ &mEbcPeriodicEvent
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
}
- switch (ExceptionType) {
- //
- // If ReportStatusCode returned, then for most exceptions we do an assert. The
- // ExceptionType++ is done simply to force the ASSERT() condition to be met.
- // For breakpoints, assume a debugger did not insert a software breakpoint
- // and skip the instruction.
- //
- case EXCEPT_EBC_BREAKPOINT:
- VmPtr->Ip += 2;
- break;
-
- case EXCEPT_EBC_STEP:
- break;
-
- case EXCEPT_EBC_UNDEFINED:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_UNDEFINED);
- break;
-
- case EXCEPT_EBC_DIVIDE_ERROR:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_DIVIDE_ERROR);
- break;
-
- case EXCEPT_EBC_DEBUG:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_DEBUG);
- break;
-
- case EXCEPT_EBC_INVALID_OPCODE:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_INVALID_OPCODE);
- break;
-
- case EXCEPT_EBC_STACK_FAULT:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_STACK_FAULT);
- break;
-
- case EXCEPT_EBC_ALIGNMENT_CHECK:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_ALIGNMENT_CHECK);
- break;
-
- case EXCEPT_EBC_INSTRUCTION_ENCODING:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_INSTRUCTION_ENCODING);
- break;
-
- case EXCEPT_EBC_BAD_BREAK:
- ExceptionType++;
- ASSERT (ExceptionType == EXCEPT_EBC_BAD_BREAK);
- break;
-
- default:
- //
- // Unknown
- //
- ASSERT (0);
- break;
+ Status = gBS->SetTimer (
+ mEbcPeriodicEvent,
+ TimerPeriodic,
+ EBC_VM_PERIODIC_CALLBACK_RATE
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
}
return EFI_SUCCESS;
}
+VOID
+CommonEbcExceptionHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+/*++
+
+Routine Description:
+
+ The default Exception Callback for the VM interpreter.
+ In this function, we report status code, and print debug information
+ about EBC_CONTEXT, then dead loop.
+
+Arguments:
+
+ InterruptType - Interrupt type.
+ SystemContext - EBC system context.
+
+Returns:
+
+ None
+
+--*/
+{
+ //
+ // We deadloop here to make it easy to debug this issue.
+ //
+ ASSERT (FALSE);
+
+ return ;
+}
+
+VOID
+EFIAPI
+EbcPeriodicNotifyFunction (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ The periodic callback function for EBC VM interpreter, which is used
+ to support the EFI debug support protocol.
+
+Arguments:
+
+ Event - The Periodic Callback Event.
+ Context - It should be the address of VM_CONTEXT pointer.
+
+Returns:
+
+ None.
+
+--*/
+{
+ VM_CONTEXT *VmPtr;
+
+ VmPtr = *(VM_CONTEXT **)Context;
+
+ if (VmPtr != NULL) {
+ EbcDebugPeriodic (VmPtr);
+ }
+
+ return ;
+}
+
+
EFI_STATUS
EbcDebugPeriodic (
IN VM_CONTEXT *VmPtr
@@ -693,6 +796,47 @@ Returns:
--*/
{
+ EFI_SYSTEM_CONTEXT_EBC EbcContext;
+ EFI_SYSTEM_CONTEXT SystemContext;
+
+ //
+ // If someone's registered for periodic callbacks, then call them.
+ //
+ if (mDebugPeriodicCallback != NULL) {
+
+ //
+ // Initialize the context structure
+ //
+ EbcContext.R0 = VmPtr->R[0];
+ EbcContext.R1 = VmPtr->R[1];
+ EbcContext.R2 = VmPtr->R[2];
+ EbcContext.R3 = VmPtr->R[3];
+ EbcContext.R4 = VmPtr->R[4];
+ EbcContext.R5 = VmPtr->R[5];
+ EbcContext.R6 = VmPtr->R[6];
+ EbcContext.R7 = VmPtr->R[7];
+ EbcContext.Ip = (UINT64)(UINTN)VmPtr->Ip;
+ EbcContext.Flags = VmPtr->Flags;
+ EbcContext.ControlFlags = 0;
+ SystemContext.SystemContextEbc = &EbcContext;
+
+ mDebugPeriodicCallback (SystemContext);
+
+ //
+ // Restore the context structure and continue to execute
+ //
+ VmPtr->R[0] = EbcContext.R0;
+ VmPtr->R[1] = EbcContext.R1;
+ VmPtr->R[2] = EbcContext.R2;
+ VmPtr->R[3] = EbcContext.R3;
+ VmPtr->R[4] = EbcContext.R4;
+ VmPtr->R[5] = EbcContext.R5;
+ VmPtr->R[6] = EbcContext.R6;
+ VmPtr->R[7] = EbcContext.R7;
+ VmPtr->Ip = (VMIP)(UINTN)EbcContext.Ip;
+ VmPtr->Flags = EbcContext.Flags;
+ }
+
return EFI_SUCCESS;
}
diff --git a/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h b/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h
index 51bd785..11b72f6 100644
--- a/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h
+++ b/EdkModulePkg/Universal/Ebc/Dxe/EbcInt.h
@@ -51,6 +51,8 @@ typedef struct {
UINTN ImageBase;
} VM_CONTEXT;
+extern VM_CONTEXT *mVmPtr;
+
//
// Bits of exception flags field of VM context
//