]> git.proxmox.com Git - mirror_edk2.git/commit - UefiCpuPkg/UefiCpuPkg.dsc
UefiCpuPkg: Remove PEI/DXE instances of CpuTimerLib.
authorJason Lou <yun.lou@intel.com>
Wed, 7 Apr 2021 08:16:25 +0000 (16:16 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 9 Apr 2021 01:00:22 +0000 (01:00 +0000)
commit19d5bccc7663399c0726aac800ddd4591be0176a
tree4a7365e0d51f5662e396601507b8e22db4c1888c
parentdc4d42302c22f012d78f6495ea23ceaa3e23842e
UefiCpuPkg: Remove PEI/DXE instances of CpuTimerLib.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2832

1. Remove PEI instance(PeiCpuTimerLib).
PeiCpuTimerLib is currently designed to save time by getting CPU TSC
frequency from Hob. BaseCpuTimerLib is designed to calculate TSC frequency
by using CPUID[15h] each time.
The time it takes to find CpuCrystalFrequencyHob (about 2000ns) is much
longer than it takes to calculate TSC frequency with CPUID[15h] (about
450ns), which means using BaseCpuTimerLib to trigger a delay is more
accurate than using PeiCpuTimerLib, recommend to use BaseCpuTimerLib
instead of PeiCpuTimerLib.

2. Remove DXE instance(DxeCpuTimerLib).
DxeCpuTimerLib is designed to calculate TSC frequency with CPUID[15h] in
its constructor function, then save it in a global variable. For this
design, once the driver containing this instance is running, this
constructor function is called, it will take extra time to calculate TSC
frequency.
The time it takes to get TSC frequency from global variable is shorter
than it takes to calculate TSC frequency with CPUID[15h], but 450ns is a
short time, the impact on the platform is very limited.
In addition, in order to simplify the code, recommend to use
BaseCpuTimerLib instead of DxeCpuTimerLib.

I did some experiments on one server platform and collected following data:
1. Average time required to find CpuCrystalFrequencyHob: about 2000 ns.
2. Average time required to find the last Hob: about 2700 ns.
2. Average time required to calculate TSC frequency: about 450 ns.

Reference code:
    //
    // Calculate average time required to find Hob.
    //
    DEBUG((DEBUG_ERROR, "[PeiCpuTimerLib] GetPerformanceCounterFrequency - GetFirstGuidHob (1000 cycles)\n"));
    Ticks1 = AsmReadTsc();
    for (i = 0; i < 1000; i++) {
      GuidHob = GetFirstGuidHob (&mCpuCrystalFrequencyHobGuid);
    }
    Ticks2 = AsmReadTsc();

    if (GuidHob == NULL) {
      DEBUG((DEBUG_ERROR, "[PeiCpuTimerLib]  - CpuCrystalFrequencyHob can not be found!\n"));
    } else {
      DEBUG((DEBUG_ERROR, "[PeiCpuTimerLib]  - Average time required to find Hob = %d ns\n", \
          DivU64x32(DivU64x64Remainder(MultU64x32((Ticks2 - Ticks1), 1000000000), *CpuCrystalCounterFrequency, NULL), 1000)));
    }

    //
    // Calculate average time required to calculate CPU frequency.
    //
    DEBUG((DEBUG_ERROR, "[PeiCpuTimerLib] GetPerformanceCounterFrequency - CpuidCoreClockCalculateTscFrequency (1000 cycles)\n"));
    Ticks1 = AsmReadTsc();
    for (i = 0; i < 1000; i++) {
      Freq = CpuidCoreClockCalculateTscFrequency ();
    }
    Ticks2 = AsmReadTsc();
    DEBUG((DEBUG_ERROR, "[PeiCpuTimerLib]  - Average time required to calculate TSC frequency = %d ns\n", \
        DivU64x32(DivU64x64Remainder(MultU64x32((Ticks2 - Ticks1), 1000000000), *CpuCrystalCounterFrequency, NULL), 1000)));

Signed-off-by: Jason Lou <yun.lou@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c [deleted file]
UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf [deleted file]
UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni [deleted file]
UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c [deleted file]
UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf [deleted file]
UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni [deleted file]
UefiCpuPkg/UefiCpuPkg.dsc