UefiCpuPkg: Restore HpetTimer after CpuExceptionHandlerLib test
Disable/Restore HpetTimer before and after running the Dxe CpuExceptionHandlerLib unit test module. During the UnitTest, a new Idt is initialized for the test. There is no handler for timer intrrupt in this new idt. After the test module, HpetTimer does not work any more since the comparator value register and main counter value register for timer does not match. To fix this issue, disable/restore HpetTimer before and after Unit Test if HpetTimer driver has been dispatched. We don't need to send Apic Eoi in this unit test module.When disabling timer, after RaiseTPL(), if there is a pending timer interrupt, bit64 of Interrupt Request Register (IRR) will be set to 1 to indicate there is a pending timer interrupt. After RestoreTPL(), CPU will handle the pending interrupt in IRR.Then TimerInterruptHandler calls SendApicEoi(). Signed-off-by: Dun Tan <dun.tan@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiMpServiceProtocolGuid
|
gEfiMpServiceProtocolGuid
|
||||||
|
gEfiTimerArchProtocolGuid
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiMpServiceProtocolGuid
|
gEfiMpServiceProtocolGuid
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "CpuExceptionHandlerTest.h"
|
#include "CpuExceptionHandlerTest.h"
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
#include <Protocol/Timer.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize Bsp Idt with a new Idt table and return the IA32_DESCRIPTOR buffer.
|
Initialize Bsp Idt with a new Idt table and return the IA32_DESCRIPTOR buffer.
|
||||||
@ -162,8 +163,12 @@ CpuExceptionHandlerTestEntry (
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UNIT_TEST_FRAMEWORK_HANDLE Framework;
|
UNIT_TEST_FRAMEWORK_HANDLE Framework;
|
||||||
|
EFI_TIMER_ARCH_PROTOCOL *TimerArchProtocol;
|
||||||
|
UINT64 TimerPeriod;
|
||||||
|
|
||||||
Framework = NULL;
|
Framework = NULL;
|
||||||
|
TimerArchProtocol = NULL;
|
||||||
|
TimerPeriod = 0;
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
|
DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
|
||||||
|
|
||||||
@ -182,11 +187,34 @@ CpuExceptionHandlerTestEntry (
|
|||||||
goto EXIT;
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If HpetTimer driver has been dispatched, disable HpetTimer before Unit Test.
|
||||||
|
//
|
||||||
|
gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **)&TimerArchProtocol);
|
||||||
|
if (TimerArchProtocol != NULL) {
|
||||||
|
Status = TimerArchProtocol->GetTimerPeriod (TimerArchProtocol, &TimerPeriod);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
if (TimerPeriod > 0) {
|
||||||
|
DEBUG ((DEBUG_INFO, "HpetTimer has been dispatched. Disable HpetTimer.\n"));
|
||||||
|
Status = TimerArchProtocol->SetTimerPeriod (TimerArchProtocol, 0);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Execute the tests.
|
// Execute the tests.
|
||||||
//
|
//
|
||||||
Status = RunAllTestSuites (Framework);
|
Status = RunAllTestSuites (Framework);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Restore HpetTimer after Unit Test.
|
||||||
|
//
|
||||||
|
if ((TimerArchProtocol != NULL) && (TimerPeriod > 0)) {
|
||||||
|
DEBUG ((DEBUG_INFO, "Restore HpetTimer after DxeCpuExceptionHandlerLib UnitTest.\n"));
|
||||||
|
Status = TimerArchProtocol->SetTimerPeriod (TimerArchProtocol, TimerPeriod);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
}
|
||||||
|
|
||||||
EXIT:
|
EXIT:
|
||||||
if (Framework) {
|
if (Framework) {
|
||||||
FreeUnitTestFramework (Framework);
|
FreeUnitTestFramework (Framework);
|
||||||
|
Reference in New Issue
Block a user