From: mikewuping Date: Fri, 3 Nov 2006 03:34:43 +0000 (+0000) Subject: I fixed following bugs in EDKII. X-Git-Tag: edk2-stable201903~23986 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=c91eaa3d55d88598baaa979097a31cb1001ecc0d 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 --- diff --git a/EdkModulePkg/Core/Dxe/Image/Image.c b/EdkModulePkg/Core/Dxe/Image/Image.c index 9b9720d897..0bef1ff82e 100644 --- a/EdkModulePkg/Core/Dxe/Image/Image.c +++ b/EdkModulePkg/Core/Dxe/Image/Image.c @@ -595,6 +595,7 @@ Returns: EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; UINTN FilePathSize; + SecurityStatus = EFI_SUCCESS; ASSERT (gEfiCurrentTpl < EFI_TPL_NOTIFY); ParentImage = NULL; @@ -753,6 +754,8 @@ Done: CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0)); *ImageHandle = NULL; } + } else if (EFI_ERROR (SecurityStatus)) { + Status = SecurityStatus; } return Status; diff --git a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm index 89c9f83176..1741ce83c0 100644 --- a/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm +++ b/EdkModulePkg/Universal/DebugSupport/Dxe/Ia32/AsmFuncs.asm @@ -189,7 +189,8 @@ Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD mov eax, Vector mov ecx, DestPtr mov word ptr [ecx], ax ; write bits 15..0 of offset - mov word ptr [ecx+2], 20h ; SYS_CODE_SEL from GDT + mov dx, cs + mov word ptr [ecx+2], dx ; SYS_CODE_SEL from GDT mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present shr eax, 16 mov word ptr [ecx+6], ax ; write bits 31..16 of offset diff --git a/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c b/EdkModulePkg/Universal/Ebc/Dxe/EbcExecute.c index 13e2d7c08f..70db1574bf 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 2a5d48a431..e38f5be730 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,7 +329,14 @@ 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. // @@ -302,6 +344,44 @@ Returns: 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 51bd785a53..11b72f64aa 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 // diff --git a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c index d575417fe9..178fa1ea59 100644 --- a/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/EdkModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -15,7 +15,7 @@ Module Name: Abstract: -Revision History + Provide support functions for variable services. --*/ @@ -125,7 +125,8 @@ Arguments: Returns: - EFI STATUS + EFI_INVALID_PARAMETER - Parameters not valid + EFI_SUCCESS - Variable store successfully updated --*/ { @@ -176,11 +177,10 @@ Returns: if ((DataPtr + DataSize) >= ((UINTN) ((UINT8 *) VolatileBase + VolatileBase->Size))) { return EFI_INVALID_PARAMETER; } - } - // - // If Volatile Variable just do a simple mem copy. - // - if (Volatile) { + + // + // If Volatile Variable just do a simple mem copy. + // CopyMem ((UINT8 *) ((UINTN) DataPtr), Buffer, DataSize); return EFI_SUCCESS; } @@ -212,9 +212,7 @@ Returns: &CurrWriteSize, CurrBuffer ); - if (EFI_ERROR (Status)) { - return Status; - } + return Status; } else { Size = (UINT32) (LinearOffset + PtrBlockMapEntry->BlockLength - CurrWritePtr); Status = EfiFvbWriteBlock ( diff --git a/EdkNt32Pkg/RuntimeDxe/FvbServices/FWBlockService.c b/EdkNt32Pkg/RuntimeDxe/FvbServices/FWBlockService.c index 1f2f8fd2b4..8824dc412a 100644 --- a/EdkNt32Pkg/RuntimeDxe/FvbServices/FWBlockService.c +++ b/EdkNt32Pkg/RuntimeDxe/FvbServices/FWBlockService.c @@ -1196,8 +1196,9 @@ Returns: Ptr = (UINT16 *) FwVolHeader; Checksum = 0; while (HeaderLength > 0) { - Checksum = *Ptr++; + Checksum = Checksum + (*Ptr); HeaderLength--; + Ptr++; } if (Checksum != 0) {