2009-12-06 02:57:05 +01:00
|
|
|
/** @file
|
|
|
|
|
2010-04-29 14:40:51 +02:00
|
|
|
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
2013-03-12 01:38:15 +01:00
|
|
|
Copyright (c) 2013, ARM Ltd. All rights reserved.
|
|
|
|
|
2019-04-04 01:03:38 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
2009-12-06 02:57:05 +01:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <PiDxe.h>
|
|
|
|
|
|
|
|
#include <Library/BaseLib.h>
|
|
|
|
#include <Library/DebugLib.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
|
#include <Library/UefiLib.h>
|
|
|
|
#include <Library/PcdLib.h>
|
|
|
|
#include <Library/TimerLib.h>
|
|
|
|
|
|
|
|
#include <Protocol/Metronome.h>
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
WaitForTick (
|
|
|
|
IN EFI_METRONOME_ARCH_PROTOCOL *This,
|
|
|
|
IN UINT32 TickNumber
|
2013-03-12 01:38:15 +01:00
|
|
|
);
|
2009-12-06 02:57:05 +01:00
|
|
|
|
|
|
|
/**
|
2011-08-08 20:29:14 +02:00
|
|
|
Interface structure for the Metronome Architectural Protocol.
|
2009-12-06 02:57:05 +01:00
|
|
|
|
|
|
|
@par Protocol Description:
|
|
|
|
This protocol provides access to a known time source in the platform to the
|
2013-03-12 01:38:15 +01:00
|
|
|
core. The core uses this known time source to produce core services that
|
|
|
|
require calibrated delays.
|
2009-12-06 02:57:05 +01:00
|
|
|
|
|
|
|
@param WaitForTick
|
2013-03-12 01:38:15 +01:00
|
|
|
Waits for a specified number of ticks from a known time source
|
|
|
|
in the platform. 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
|
2009-12-06 02:57:05 +01:00
|
|
|
has elapsed, wait for two ticks.
|
|
|
|
|
|
|
|
@param TickPeriod
|
2013-03-12 01:38:15 +01:00
|
|
|
The period of platform's known time source in 100 nS units.
|
|
|
|
This value on any platform must be at least 10 uS, and must not
|
|
|
|
exceed 200 uS. The value in this field is a constant that must
|
|
|
|
not be modified after the Metronome architectural protocol is
|
2009-12-06 02:57:05 +01:00
|
|
|
installed. All consumers must treat this as a read-only field.
|
|
|
|
|
|
|
|
**/
|
2021-12-05 23:53:56 +01:00
|
|
|
EFI_METRONOME_ARCH_PROTOCOL gMetronome = {
|
2009-12-06 02:57:05 +01:00
|
|
|
WaitForTick,
|
2012-07-04 22:13:48 +02:00
|
|
|
FixedPcdGet32 (PcdMetronomeTickPeriod)
|
2009-12-06 02:57:05 +01:00
|
|
|
};
|
|
|
|
|
2013-03-12 01:38:15 +01:00
|
|
|
/**
|
|
|
|
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
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Compute how long to stall the CPU.
|
|
|
|
// gMetronome.TickPeriod is in 100 ns units so it needs to be divided by 10
|
|
|
|
// to get it in microseconds units.
|
|
|
|
//
|
|
|
|
MicroSecondDelay (TickNumber * gMetronome.TickPeriod / 10);
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2009-12-06 02:57:05 +01:00
|
|
|
EFI_HANDLE gMetronomeHandle = NULL;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Initialize the state information for the CPU Architectural Protocol
|
|
|
|
|
|
|
|
@param ImageHandle of the loaded driver
|
|
|
|
@param SystemTable Pointer to the System Table
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Protocol registered
|
|
|
|
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
|
|
|
@retval EFI_DEVICE_ERROR Hardware problems
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
2019-09-17 13:05:09 +02:00
|
|
|
EFIAPI
|
2009-12-06 02:57:05 +01:00
|
|
|
MetronomeInitialize (
|
2021-12-05 23:53:56 +01:00
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
2009-12-06 02:57:05 +01:00
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
2013-03-12 01:38:15 +01:00
|
|
|
|
2009-12-06 02:57:05 +01:00
|
|
|
//
|
|
|
|
// Do any hardware init required to make WaitForTick () to work here.
|
|
|
|
//
|
|
|
|
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
|
|
&gMetronomeHandle,
|
2021-12-05 23:53:56 +01:00
|
|
|
&gEfiMetronomeArchProtocolGuid,
|
|
|
|
&gMetronome,
|
2009-12-06 02:57:05 +01:00
|
|
|
NULL
|
|
|
|
);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|