summaryrefslogtreecommitdiff
path: root/Core/MdeModulePkg/Universal/Metronome/Metronome.c
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-22 15:55:38 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:14:37 +0800
commit7f05fa00f73038b425002566d3afe6c3ade2ccdb (patch)
tree297e208d4ade33a8bb3d5d20f72c53e0d134e003 /Core/MdeModulePkg/Universal/Metronome/Metronome.c
parented2ecce34b3830562c4239093a41ba92d76d5f31 (diff)
downloadedk2-platforms-7f05fa00f73038b425002566d3afe6c3ade2ccdb.tar.xz
MdeModulePkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Core/MdeModulePkg/Universal/Metronome/Metronome.c')
-rw-r--r--Core/MdeModulePkg/Universal/Metronome/Metronome.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/Core/MdeModulePkg/Universal/Metronome/Metronome.c b/Core/MdeModulePkg/Universal/Metronome/Metronome.c
new file mode 100644
index 0000000000..c3dc0b875a
--- /dev/null
+++ b/Core/MdeModulePkg/Universal/Metronome/Metronome.c
@@ -0,0 +1,125 @@
+/** @file
+ Produces the Metronome Architectural Protocol on top of Timer Library.
+
+ This is a generic implementation of the Metronome Architectural Protocol that
+ layers on top of an instance of the Timer Library. The Timer Library provides
+ functions for nanosecond and microsecond delays. This generic implementation
+ produces a fixed TickPeriod of 1 100ns unit, and when the WaitForTick() service
+ is called, the number of ticks passed in is converted to either nanosecond or
+ microsecond units. If the number of ticks is small, then nanoseconds are used.
+ If the number of ticks is large, then microseconds are used. This prevents
+ overflows that could occur for long delays if only nanoseconds were used and also
+ provides the greatest accuracy for small delays.
+
+Copyright (c) 2008, 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 "Metronome.h"
+
+//
+// Handle for the Metronome Architectural Protocol instance produced by this driver
+//
+EFI_HANDLE mMetronomeHandle = NULL;
+
+//
+// The Metronome Architectural Protocol instance produced by this driver
+//
+EFI_METRONOME_ARCH_PROTOCOL mMetronome = {
+ WaitForTick,
+ 1 // TickPeriod = 1*100 ns units
+};
+
+/**
+ Waits for the specified number of ticks.
+
+ This function implements EFI_METRONOME_ARCH_PROTOCOL.WaitForTick().
+ The WaitForTick() function waits for the number of ticks specified by
+ TickNumber from a known time source in the platform. If TickNumber of
+ ticks are detected, then EFI_SUCCESS is returned. The actual time passed
+ between entry of this function and the first tick is between 0 and
+ TickPeriod 100 nS units. If you want to guarantee that at least TickPeriod
+ time has elapsed, wait for two ticks. This function waits for a hardware
+ event to determine when a tick occurs. It is possible for interrupt
+ processing, or exception processing to interrupt the execution of the
+ WaitForTick() function. Depending on the hardware source for the ticks, it
+ is possible for a tick to be missed. This function cannot guarantee that
+ ticks will not be missed. If a timeout occurs waiting for the specified
+ number of ticks, then EFI_TIMEOUT is returned.
+
+ @param This The EFI_METRONOME_ARCH_PROTOCOL instance.
+ @param TickNumber Number of ticks to wait.
+
+ @retval EFI_SUCCESS The wait for the number of ticks specified by TickNumber
+ succeeded.
+ @retval EFI_TIMEOUT A timeout occurred waiting for the specified number of ticks.
+
+**/
+EFI_STATUS
+EFIAPI
+WaitForTick (
+ IN EFI_METRONOME_ARCH_PROTOCOL *This,
+ IN UINT32 TickNumber
+ )
+{
+ //
+ // Check the value of TickNumber, so a 32-bit overflow can be avoided
+ // when TickNumber of converted to nanosecond units
+ //
+ if (TickNumber < 10000000) {
+ //
+ // If TickNumber is small, then use NanoSecondDelay()
+ //
+ NanoSecondDelay (TickNumber * 100);
+ } else {
+ //
+ // If TickNumber is large, then use MicroSecondDelay()
+ //
+ MicroSecondDelay (TickNumber / 10);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ The user Entry Point for module Metronome. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallMetronome (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Make sure the Metronome Architectural Protocol is not already installed in the system
+ //
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMetronomeArchProtocolGuid);
+
+ //
+ // Install on a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mMetronomeHandle,
+ &gEfiMetronomeArchProtocolGuid, &mMetronome,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}