4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Produces the Metronome Architectural Protocol on top of Timer Library.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is a generic implementation of the Metronome Architectural Protocol that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync layers on top of an instance of the Timer Library. The Timer Library provides
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync functions for nanosecond and microsecond delays. This generic implementation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync produces a fixed TickPeriod of 1 100ns unit, and when the WaitForTick() service
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is called, the number of ticks passed in is converted to either nanosecond or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync microsecond units. If the number of ticks is small, then nanoseconds are used.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the number of ticks is large, then microseconds are used. This prevents
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync overflows that could occur for long delays if only nanoseconds were used and also
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync provides the greatest accuracy for small delays.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2008, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchttp://opensource.org/licenses/bsd-license.php
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Metronome.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// Handle for the Metronome Architectural Protocol instance produced by this driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_HANDLE mMetronomeHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// The Metronome Architectural Protocol instance produced by this driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync//
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_METRONOME_ARCH_PROTOCOL mMetronome = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WaitForTick,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 1 // TickPeriod = 1*100 ns units
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Waits for the specified number of ticks.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function implements EFI_METRONOME_ARCH_PROTOCOL.WaitForTick().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The WaitForTick() function waits for the number of ticks specified by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TickNumber from a known time source in the platform. If TickNumber of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ticks are detected, then EFI_SUCCESS is returned. The actual time passed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync between entry of this function and the first tick is between 0 and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TickPeriod 100 nS units. If you want to guarantee that at least TickPeriod
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync time has elapsed, wait for two ticks. This function waits for a hardware
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync event to determine when a tick occurs. It is possible for interrupt
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync processing, or exception processing to interrupt the execution of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WaitForTick() function. Depending on the hardware source for the ticks, it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is possible for a tick to be missed. This function cannot guarantee that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ticks will not be missed. If a timeout occurs waiting for the specified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync number of ticks, then EFI_TIMEOUT is returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param This The EFI_METRONOME_ARCH_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param TickNumber Number of ticks to wait.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The wait for the number of ticks specified by TickNumber
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync succeeded.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_TIMEOUT A timeout occurred waiting for the specified number of ticks.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWaitForTick (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_METRONOME_ARCH_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 TickNumber
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the value of TickNumber, so a 32-bit overflow can be avoided
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // when TickNumber of converted to nanosecond units
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TickNumber < 10000000) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If TickNumber is small, then use NanoSecondDelay()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NanoSecondDelay (TickNumber * 100);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If TickNumber is large, then use MicroSecondDelay()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MicroSecondDelay (TickNumber / 10);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The user Entry Point for module Metronome. The user code starts with this function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the EFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The entry point is executed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Some error occurs when executing this entry point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncInstallMetronome (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_TABLE *SystemTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Make sure the Metronome Architectural Protocol is not already installed in the system
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiMetronomeArchProtocolGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install on a new handle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &mMetronomeHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiMetronomeArchProtocolGuid, &mMetronome,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}