diff options
Diffstat (limited to 'Core/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c')
-rw-r--r-- | Core/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/Core/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c b/Core/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c new file mode 100644 index 0000000000..d01d1ae484 --- /dev/null +++ b/Core/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c @@ -0,0 +1,149 @@ +/** @file
+ Code for debug timer to support debug agent library implementation.
+
+ Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "DebugAgent.h"
+
+/**
+ Initialize CPU local APIC timer.
+
+ @param[out] TimerFrequency Local APIC timer frequency returned.
+ @param[in] DumpFlag If TRUE, dump Local APIC timer's parameter.
+
+ @return 32-bit Local APIC timer init count.
+**/
+UINT32
+InitializeDebugTimer (
+ OUT UINT32 *TimerFrequency,
+ IN BOOLEAN DumpFlag
+ )
+{
+ UINTN ApicTimerDivisor;
+ UINT32 InitialCount;
+ UINT32 ApicTimerFrequency;
+
+ InitializeLocalApicSoftwareEnable (TRUE);
+ GetApicTimerState (&ApicTimerDivisor, NULL, NULL);
+ ApicTimerFrequency = PcdGet32(PcdFSBClock) / (UINT32)ApicTimerDivisor;
+ //
+ // Cpu Local Apic timer interrupt frequency, it is set to 0.1s
+ //
+ InitialCount = (UINT32)DivU64x32 (
+ MultU64x64 (
+ ApicTimerFrequency,
+ DEBUG_TIMER_INTERVAL
+ ),
+ 1000000u
+ );
+
+ InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR);
+ //
+ // Disable Debug Timer interrupt to avoid it is delivered before Debug Port
+ // is initialized
+ //
+ DisableApicTimerInterrupt ();
+
+ if (DumpFlag) {
+ DEBUG ((EFI_D_INFO, "Debug Timer: FSB Clock = %d\n", PcdGet32(PcdFSBClock)));
+ DEBUG ((EFI_D_INFO, "Debug Timer: Divisor = %d\n", ApicTimerDivisor));
+ DEBUG ((EFI_D_INFO, "Debug Timer: Frequency = %d\n", ApicTimerFrequency));
+ DEBUG ((EFI_D_INFO, "Debug Timer: InitialCount = %d\n", InitialCount));
+ }
+ if (TimerFrequency != NULL) {
+ *TimerFrequency = ApicTimerFrequency;
+ }
+ return InitialCount;
+}
+
+/**
+ Enable/Disable the interrupt of debug timer and return the interrupt state
+ prior to the operation.
+
+ If EnableStatus is TRUE, enable the interrupt of debug timer.
+ If EnableStatus is FALSE, disable the interrupt of debug timer.
+
+ @param[in] EnableStatus Enable/Disable.
+
+ @retval TRUE Debug timer interrupt were enabled on entry to this call.
+ @retval FALSE Debug timer interrupt were disabled on entry to this call.
+
+**/
+BOOLEAN
+EFIAPI
+SaveAndSetDebugTimerInterrupt (
+ IN BOOLEAN EnableStatus
+ )
+{
+ BOOLEAN OldDebugTimerInterruptState;
+
+ OldDebugTimerInterruptState = GetApicTimerInterruptState ();
+
+ if (OldDebugTimerInterruptState != EnableStatus) {
+ if (EnableStatus) {
+ EnableApicTimerInterrupt ();
+ } else {
+ DisableApicTimerInterrupt ();
+ }
+ //
+ // Validate the Debug Timer interrupt state
+ // This will make additional delay after Local Apic Timer interrupt state is changed.
+ // Thus, CPU could handle the potential pending interrupt of Local Apic timer.
+ //
+ while (GetApicTimerInterruptState () != EnableStatus) {
+ CpuPause ();
+ }
+ }
+
+ return OldDebugTimerInterruptState;
+}
+
+/**
+ Check if the timer is time out.
+
+ @param[in] TimerCycle Timer initial count.
+ @param[in] Timer The start timer from the begin.
+ @param[in] TimeoutTicker Ticker number need time out.
+
+ @return TRUE Timer time out occurs.
+ @retval FALSE Timer does not time out.
+
+**/
+BOOLEAN
+IsDebugTimerTimeout (
+ IN UINT32 TimerCycle,
+ IN UINT32 Timer,
+ IN UINT32 TimeoutTicker
+ )
+{
+ UINT64 CurrentTimer;
+ UINT64 Delta;
+
+ CurrentTimer = GetApicTimerCurrentCount ();
+
+ //
+ // This timer counter counts down. Check for roll over condition.
+ // If CurrentTimer is equal to Timer, it does not mean that roll over
+ // happened.
+ //
+ if (CurrentTimer <= Timer) {
+ Delta = Timer - CurrentTimer;
+ } else {
+ //
+ // Handle one roll-over.
+ //
+ Delta = TimerCycle - (CurrentTimer - Timer) + 1;
+ }
+
+ return (BOOLEAN) (Delta >= TimeoutTicker);
+}
+
|