UefiCpuPkg/CpuTimerDxeRiscV64: Add support for Sstc

Sstc extension allows to program the timer and receive the interrupt
without using an SBI call. This reduces the latency to generate the timer
interrupt. So, detect whether Sstc extension is supported and use the
stimecmp register directly to program the timer interrupt.

Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Andrei Warkentin <andrei.warkentin@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
Reviewed-by: Dhaval Sharma <dhaval@rivosinc.com>
This commit is contained in:
Sunil V L 2023-06-24 03:41:57 +05:30 committed by mergify[bot]
parent 8ae17a71af
commit f91029947b
3 changed files with 49 additions and 3 deletions

View File

@ -41,6 +41,7 @@
Timer.c
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES
[Protocols]

View File

@ -44,6 +44,45 @@ STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction;
STATIC UINT64 mTimerPeriod = 0;
STATIC UINT64 mLastPeriodStart = 0;
//
// Sstc support
//
STATIC BOOLEAN mSstcEnabled = FALSE;
/**
Program the timer.
Program either using stimecmp (when Sstc extension is enabled) or using SBI
TIME call.
@param NextValue Core tick value the timer should expire.
**/
STATIC
VOID
RiscVProgramTimer (
UINT64 NextValue
)
{
if (mSstcEnabled) {
RiscVSetSupervisorTimeCompareRegister (NextValue);
} else {
SbiSetTimer (NextValue);
}
}
/**
Check whether Sstc is enabled in PCD.
**/
STATIC
BOOLEAN
RiscVIsSstcEnabled (
VOID
)
{
return ((PcdGet64 (PcdRiscVFeatureOverride) & RISCV_CPU_FEATURE_SSTC_BITMASK) != 0);
}
/**
Timer Interrupt Handler.
@ -94,7 +133,7 @@ TimerInterruptHandler (
),
1000000u
); // convert to tick
SbiSetTimer (PeriodStart);
RiscVProgramTimer (PeriodStart);
RiscVEnableTimerInterrupt (); // enable SMode timer int
gBS->RestoreTPL (OriginalTPL);
}
@ -197,8 +236,7 @@ TimerDriverSetTimerPeriod (
),
1000000u
); // convert to tick
SbiSetTimer (PeriodStart);
RiscVProgramTimer (PeriodStart);
mCpu->EnableInterrupt (mCpu);
RiscVEnableTimerInterrupt (); // enable SMode timer int
return EFI_SUCCESS;
@ -282,6 +320,11 @@ TimerDriverInitialize (
//
mTimerNotifyFunction = NULL;
if (RiscVIsSstcEnabled ()) {
mSstcEnabled = TRUE;
DEBUG ((DEBUG_INFO, "TimerDriverInitialize: Timer interrupt is via Sstc extension\n"));
}
//
// Make sure the Timer Architectural Protocol is not already installed in the system
//

View File

@ -26,6 +26,8 @@
//
#define DEFAULT_TIMER_TICK_DURATION 100000
#define RISCV_CPU_FEATURE_SSTC_BITMASK BIT1
extern VOID
RiscvSetTimerPeriod (
UINT32 TimerPeriod