//\r
// The current period of the timer interrupt\r
//\r
-STATIC UINT64 mTimerPeriod = 0;\r
+STATIC UINT64 mTimerPeriod = 0;\r
+STATIC UINT64 mLastPeriodStart = 0;\r
\r
/**\r
Timer Interrupt Handler.\r
)\r
{\r
EFI_TPL OriginalTPL;\r
- UINT64 RiscvTimer;\r
+ UINT64 PeriodStart;\r
+\r
+ PeriodStart = RiscVReadTimer ();\r
\r
OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
if (mTimerNotifyFunction != NULL) {\r
- mTimerNotifyFunction (mTimerPeriod);\r
+ //\r
+ // For any number of reasons, the ticks could be coming\r
+ // in slower than mTimerPeriod. For example, some code\r
+ // is doing a *lot* of stuff inside an EFI_TPL_HIGH\r
+ // critical section, and this should not cause the EFI\r
+ // time to increment slower. So when we take an interrupt,\r
+ // account for the actual time passed.\r
+ //\r
+ mTimerNotifyFunction (PeriodStart - mLastPeriodStart);\r
}\r
\r
- RiscVDisableTimerInterrupt (); // Disable SMode timer int\r
- RiscVClearPendingTimerInterrupt ();\r
if (mTimerPeriod == 0) {\r
+ RiscVDisableTimerInterrupt ();\r
gBS->RestoreTPL (OriginalTPL);\r
- RiscVDisableTimerInterrupt (); // Disable SMode timer int\r
return;\r
}\r
\r
- RiscvTimer = RiscVReadTimer ();\r
- SbiSetTimer (RiscvTimer += mTimerPeriod);\r
- gBS->RestoreTPL (OriginalTPL);\r
+ mLastPeriodStart = PeriodStart;\r
+ SbiSetTimer (PeriodStart += mTimerPeriod);\r
RiscVEnableTimerInterrupt (); // enable SMode timer int\r
+ gBS->RestoreTPL (OriginalTPL);\r
}\r
\r
/**\r
IN UINT64 TimerPeriod\r
)\r
{\r
- UINT64 RiscvTimer;\r
-\r
DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod));\r
\r
if (TimerPeriod == 0) {\r
return EFI_SUCCESS;\r
}\r
\r
- mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us\r
- RiscvTimer = RiscVReadTimer ();\r
- SbiSetTimer (RiscvTimer + mTimerPeriod);\r
+ mTimerPeriod = TimerPeriod / 10; // convert unit from 100ns to 1us\r
+ mLastPeriodStart = RiscVReadTimer ();\r
+ SbiSetTimer (mLastPeriodStart + mTimerPeriod);\r
\r
mCpu->EnableInterrupt (mCpu);\r
RiscVEnableTimerInterrupt (); // enable SMode timer int\r