diff options
Diffstat (limited to 'UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c')
-rw-r--r-- | UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c index 080e229c40..bb07200754 100644 --- a/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c +++ b/UefiCpuPkg/Library/BaseRiscV64CpuTimerLib/CpuTimerLib.c @@ -8,6 +8,7 @@ **/
#include <Uefi.h>
+#include <Guid/RiscVSecHobData.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
@@ -16,9 +17,12 @@ #include <Pi/PiHob.h>
#include <Library/HobLib.h>
#include <Library/FdtLib.h>
+#include <Library/TimerLib.h>
STATIC UINT64 mTimeBase;
+#define GET_TIME_BASE() (mTimeBase ?: GetPerformanceCounterProperties(NULL, NULL))
+
/**
Stalls the CPU for at least the given number of ticks.
@@ -63,7 +67,7 @@ MicroSecondDelay ( DivU64x32 (
MultU64x32 (
MicroSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000u
)
@@ -91,7 +95,7 @@ NanoSecondDelay ( DivU64x32 (
MultU64x32 (
NanoSeconds,
- mTimeBase
+ GET_TIME_BASE ()
),
1000000000u
)
@@ -150,6 +154,12 @@ GetPerformanceCounterProperties ( OUT UINT64 *EndValue OPTIONAL
)
{
+ VOID *Hob;
+ RISCV_SEC_HANDOFF_DATA *SecData;
+ CONST EFI_GUID SecHobDataGuid = RISCV_SEC_HANDOFF_HOB_GUID;
+ UINT64 TimeBase;
+ CONST VOID *FdtBase;
+
if (StartValue != NULL) {
*StartValue = 0;
}
@@ -165,20 +175,27 @@ GetPerformanceCounterProperties ( //
// Locate the FDT HOB and validate header
//
- CONST EFI_HOB_GUID_TYPE *Hob = GetFirstGuidHob (&gFdtHobGuid);
-
- ASSERT (Hob != NULL);
-
- CONST VOID *DeviceTreeBase =
- (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ Hob = GetFirstGuidHob (&gFdtHobGuid);
+ if (Hob) {
+ FdtBase = (CONST VOID *)(UINTN)*(CONST UINT64 *)GET_GUID_HOB_DATA (Hob);
+ } else {
+ //
+ // Get the FDT address from the SEC HOB
+ //
+ Hob = GetFirstGuidHob (&SecHobDataGuid);
+ ASSERT (Hob != NULL);
+ SecData = (RISCV_SEC_HANDOFF_DATA *)GET_GUID_HOB_DATA (Hob);
+ FdtBase = (CONST VOID *)SecData->FdtPointer;
+ }
- ASSERT (FdtCheckHeader (DeviceTreeBase) == 0);
+ ASSERT (FdtBase != NULL);
+ ASSERT (FdtCheckHeader ((VOID *)(UINTN)FdtBase) == 0);
//
// /cpus node
//
INT32 Node = FdtSubnodeOffsetNameLen (
- DeviceTreeBase,
+ FdtBase,
0,
"cpus",
sizeof ("cpus") - 1
@@ -191,15 +208,23 @@ GetPerformanceCounterProperties ( //
INT32 Len;
CONST FDT_PROPERTY *Prop =
- FdtGetProperty (DeviceTreeBase, Node, "timebase-frequency", &Len);
+ FdtGetProperty (FdtBase, Node, "timebase-frequency", &Len);
ASSERT (Prop != NULL && Len == sizeof (UINT32));
//
// Device-tree cells are big-endian
//
- mTimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
- return mTimeBase;
+ TimeBase = SwapBytes32 (*(CONST UINT32 *)Prop->Data);
+ ASSERT (TimeBase != 0);
+
+ //
+ // Save the time base for later use. Note that the mTimeBase maybe zero if
+ // this library is stored in read-only memory.
+ //
+ mTimeBase = TimeBase;
+
+ return TimeBase;
}
/**
@@ -227,13 +252,13 @@ GetTimeInNanoSecond ( // Time = --------- x 1,000,000,000
// Frequency
//
- NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, mTimeBase, &Remainder), 1000000000u);
+ NanoSeconds = MultU64x32 (DivU64x32Remainder (Ticks, GET_TIME_BASE (), &Remainder), 1000000000u);
//
// Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
// will not overflow 64-bit.
//
- NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), mTimeBase);
+ NanoSeconds += DivU64x32 (MultU64x32 ((UINT64)Remainder, 1000000000u), GET_TIME_BASE ());
return NanoSeconds;
}
|