X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPkg%2FDrivers%2FTimerDxe%2FTimerDxe.c;h=a3202fa056f3026cd1c6ab3781649923d848d62c;hp=40ccf161be637461db6fd089c168d8f40b450655;hb=ac9b530e6b47c0957345e421b618d8bdd2bf21cf;hpb=d4bb43cee15895da3d53009396f1a53aae15c056 diff --git a/ArmPkg/Drivers/TimerDxe/TimerDxe.c b/ArmPkg/Drivers/TimerDxe/TimerDxe.c index 40ccf161be..a3202fa056 100644 --- a/ArmPkg/Drivers/TimerDxe/TimerDxe.c +++ b/ArmPkg/Drivers/TimerDxe/TimerDxe.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -101,7 +101,7 @@ ExitBootServicesEvent ( IN VOID *Context ) { - ArmArchTimerDisableTimer (); + ArmGenericTimerDisableTimer (); } /** @@ -144,13 +144,13 @@ TimerDriverSetTimerPeriod ( EFI_TPL OriginalTPL; // Always disable the timer - ArmArchTimerDisableTimer (); + ArmGenericTimerDisableTimer (); if (TimerPeriod != 0) { // mTimerTicks = TimerPeriod in 1ms unit x Frequency.10^-3 // = TimerPeriod.10^-4 x Frequency.10^-3 // = (TimerPeriod x Frequency) x 10^-7 - TimerTicks = MultU64x32 (TimerPeriod, FixedPcdGet32 (PcdArmArchTimerFreqInHz)); + TimerTicks = MultU64x32 (TimerPeriod, ArmGenericTimerGetTimerFreq ()); TimerTicks = DivU64x32 (TimerTicks, 10000000U); // Raise TPL to update the mTimerTicks and mTimerPeriod to ensure these values @@ -163,13 +163,13 @@ TimerDriverSetTimerPeriod ( gBS->RestoreTPL (OriginalTPL); - // Get value of the current physical timer - CounterValue = ArmReadCntPct (); + // Get value of the current timer + CounterValue = ArmGenericTimerGetSystemCount (); // Set the interrupt in Current Time + mTimerTick - ArmWriteCntpCval (CounterValue + mTimerTicks); + ArmGenericTimerSetCompareVal (CounterValue + mTimerTicks); // Enable the timer - ArmArchTimerEnableTimer (); + ArmGenericTimerEnableTimer (); } else { // Save the new timer period mTimerPeriod = TimerPeriod; @@ -306,11 +306,12 @@ TimerInterruptHandler ( // OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); - // Check if the timer interrupt is active - if ((ArmArchTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) { + // Signal end of interrupt early to help avoid losing subsequent ticks + // from long duration handlers + gInterrupt->EndOfInterrupt (gInterrupt, Source); - // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers - gInterrupt->EndOfInterrupt (gInterrupt, Source); + // Check if the timer interrupt is active + if ((ArmGenericTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) { if (mTimerNotifyFunction) { mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod); @@ -321,9 +322,9 @@ TimerInterruptHandler ( // // Get current counter value - CurrentValue = ArmReadCntPct (); + CurrentValue = ArmGenericTimerGetSystemCount (); // Get the counter value to compare with - CompareValue = ArmReadCntpCval (); + CompareValue = ArmGenericTimerGetCompareVal (); // This loop is needed in case we missed interrupts (eg: case when the interrupt handling // has taken longer than mTickPeriod). @@ -335,12 +336,11 @@ TimerInterruptHandler ( } while (CompareValue < CurrentValue); // Set next compare value - ArmWriteCntpCval (CompareValue); + ArmGenericTimerSetCompareVal (CompareValue); + ArmGenericTimerEnableTimer (); + ArmInstructionSynchronizationBarrier (); } - // Enable timer interrupts - gInterrupt->EnableInterruptSource (gInterrupt, Source); - gBS->RestoreTPL (OriginalTPL); } @@ -367,7 +367,8 @@ TimerInitialize ( { EFI_HANDLE Handle = NULL; EFI_STATUS Status; - UINTN TimerCtrlReg; + UINTN TimerCtrlReg; + UINT32 TimerHypIntrNum; if (ArmIsArchTimerImplemented () == 0) { DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n")); @@ -379,10 +380,10 @@ TimerInitialize ( ASSERT_EFI_ERROR (Status); // Disable the timer - TimerCtrlReg = ArmArchTimerGetTimerCtrlReg (); + TimerCtrlReg = ArmGenericTimerGetTimerCtrlReg (); TimerCtrlReg |= ARM_ARCH_TIMER_IMASK; TimerCtrlReg &= ~ARM_ARCH_TIMER_ENABLE; - ArmArchTimerSetTimerCtrlReg (TimerCtrlReg); + ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg); Status = TimerDriverSetTimerPeriod (&gTimer, 0); ASSERT_EFI_ERROR (Status); @@ -390,6 +391,19 @@ TimerInitialize ( // Note: Because it is not possible to determine the security state of the // CPU dynamically, we just install interrupt handler for both sec and non-sec // timer PPI + Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler); + ASSERT_EFI_ERROR (Status); + + // + // The hypervisor timer interrupt may be omitted by implementations that + // execute under virtualization. + // + TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum); + if (TimerHypIntrNum != 0) { + Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler); + ASSERT_EFI_ERROR (Status); + } + Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler); ASSERT_EFI_ERROR (Status); @@ -410,7 +424,7 @@ TimerInitialize ( // Everything is ready, unmask and enable timer interrupts TimerCtrlReg = ARM_ARCH_TIMER_ENABLE; - ArmArchTimerSetTimerCtrlReg (TimerCtrlReg); + ArmGenericTimerSetTimerCtrlReg (TimerCtrlReg); // Register for an ExitBootServicesEvent Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);