summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf1
-rw-r--r--UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c49
-rw-r--r--UefiCpuPkg/CpuTimerDxeRiscV64/Timer.h2
3 files changed, 49 insertions, 3 deletions
diff --git a/UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf b/UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf
index aba660186d..f2a2cf12ca 100644
--- a/UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf
+++ b/UefiCpuPkg/CpuTimerDxeRiscV64/CpuTimerDxeRiscV64.inf
@@ -41,6 +41,7 @@
Timer.c
[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdRiscVFeatureOverride ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES
[Protocols]
diff --git a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c b/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c
index 30e48061cd..216f48a529 100644
--- a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c
+++ b/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.c
@@ -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
//
diff --git a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.h b/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.h
index 9b3542230c..067bbd29f3 100644
--- a/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.h
+++ b/UefiCpuPkg/CpuTimerDxeRiscV64/Timer.h
@@ -26,6 +26,8 @@
//
#define DEFAULT_TIMER_TICK_DURATION 100000
+#define RISCV_CPU_FEATURE_SSTC_BITMASK BIT1
+
extern VOID
RiscvSetTimerPeriod (
UINT32 TimerPeriod