mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
Use ACPI timer for Duet platform.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@7264 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
4e6a198ccc
commit
9be2c306aa
@ -42,11 +42,15 @@
|
|||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
DuetPkg/DuetPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BaseLib
|
BaseLib
|
||||||
DebugLib
|
DebugLib
|
||||||
UefiBootServicesTableLib
|
HobLib
|
||||||
|
IoLib
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiAcpiDescriptionGuid
|
||||||
|
|
||||||
|
|
||||||
[Protocols]
|
|
||||||
gEfiMetronomeArchProtocolGuid # ALWAYS_CONSUMED
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
/** @file
|
/** @file
|
||||||
Timer Library functions built upon local APIC on IA32/x64.
|
Timer Library functions built upon ACPI on IA32/x64.
|
||||||
|
|
||||||
|
ACPI power management timer is a 24-bit or 32-bit fixed rate free running count-up
|
||||||
|
timer that runs off a 3.579545 MHz clock.
|
||||||
|
When startup, Duet will check the FADT to determine whether the PM timer is a
|
||||||
|
32-bit or 25-bit timer.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2007, Intel Corporation<BR>
|
Copyright (c) 2006 - 2007, Intel Corporation<BR>
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
@ -16,25 +21,93 @@
|
|||||||
#include <Library/TimerLib.h>
|
#include <Library/TimerLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/HobLib.h>
|
||||||
|
#include <Guid/AcpiDescription.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
#include <Library/PciLib.h>
|
||||||
|
|
||||||
#include <Protocol/Metronome.h>
|
EFI_ACPI_DESCRIPTION *gAcpiDesc = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
EFI_METRONOME_ARCH_PROTOCOL *gDuetMetronome = NULL;
|
Internal function to get Acpi information from HOB.
|
||||||
|
|
||||||
EFI_METRONOME_ARCH_PROTOCOL*
|
@return Pointer to ACPI description structure.
|
||||||
GetMetronomeArchProtocol (
|
**/
|
||||||
|
EFI_ACPI_DESCRIPTION*
|
||||||
|
InternalGetApciDescrptionTable (
|
||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (gDuetMetronome == NULL) {
|
EFI_PEI_HOB_POINTERS GuidHob;
|
||||||
gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID**) &gDuetMetronome);
|
|
||||||
|
if (gAcpiDesc != NULL) {
|
||||||
|
return gAcpiDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gDuetMetronome;
|
GuidHob.Raw = GetFirstGuidHob (&gEfiAcpiDescriptionGuid);
|
||||||
|
if (GuidHob.Raw != NULL) {
|
||||||
|
gAcpiDesc = GET_GUID_HOB_DATA (GuidHob.Guid);
|
||||||
|
DEBUG ((EFI_D_INFO, "ACPI Timer: PM_TMR_BLK.RegisterBitWidth = 0x%X\n", gAcpiDesc->PM_TMR_BLK.RegisterBitWidth));
|
||||||
|
DEBUG ((EFI_D_INFO, "ACPI Timer: PM_TMR_BLK.Address = 0x%X\n", gAcpiDesc->PM_TMR_BLK.Address));
|
||||||
|
return gAcpiDesc;
|
||||||
|
} else {
|
||||||
|
DEBUG ((EFI_D_ERROR, "Fail to get Acpi description table from hob\n"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Internal function to read the current tick counter of ACPI.
|
||||||
|
|
||||||
|
@return The tick counter read.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT32
|
||||||
|
InternalAcpiGetTimerTick (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return IoRead32 ((UINTN)gAcpiDesc->PM_TMR_BLK.Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stalls the CPU for at least the given number of ticks.
|
||||||
|
|
||||||
|
Stalls the CPU for at least the given number of ticks. It's invoked by
|
||||||
|
MicroSecondDelay() and NanoSecondDelay().
|
||||||
|
|
||||||
|
@param Delay A period of time to delay in ticks.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
InternalAcpiDelay (
|
||||||
|
IN UINT32 Delay
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Ticks;
|
||||||
|
UINT32 Times;
|
||||||
|
|
||||||
|
Times = Delay >> (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2);
|
||||||
|
Delay &= (1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2)) - 1;
|
||||||
|
do {
|
||||||
|
//
|
||||||
|
// The target timer count is calculated here
|
||||||
|
//
|
||||||
|
Ticks = InternalAcpiGetTimerTick () + Delay;
|
||||||
|
Delay = 1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 2);
|
||||||
|
//
|
||||||
|
// Wait until time out
|
||||||
|
// Delay >= 2^23 (if ACPI provide 24-bit timer) or Delay >= 2^31 (if ACPI
|
||||||
|
// provide 32-bit timer) could not be handled by this function
|
||||||
|
// Timer wrap-arounds are handled correctly by this function
|
||||||
|
//
|
||||||
|
while (((Ticks - InternalAcpiGetTimerTick ()) & (1 << (gAcpiDesc->PM_TMR_BLK.RegisterBitWidth - 1))) == 0) {
|
||||||
|
CpuPause ();
|
||||||
|
}
|
||||||
|
} while (Times-- > 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Stalls the CPU for at least the given number of microseconds.
|
Stalls the CPU for at least the given number of microseconds.
|
||||||
@ -52,36 +125,20 @@ MicroSecondDelay (
|
|||||||
IN UINTN MicroSeconds
|
IN UINTN MicroSeconds
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
gBS->Stall (MicroSeconds);
|
|
||||||
/**
|
|
||||||
EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
|
|
||||||
UINT32 Counter;
|
|
||||||
UINTN Remainder;
|
|
||||||
|
|
||||||
if ((mMetronome = GetMetronomeArchProtocol()) == NULL) {
|
if (InternalGetApciDescrptionTable() == NULL) {
|
||||||
return MicroSeconds;
|
return MicroSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
InternalAcpiDelay (
|
||||||
// Calculate the number of ticks by dividing the number of microseconds by
|
(UINT32)DivU64x32 (
|
||||||
// the TickPeriod.
|
MultU64x32 (
|
||||||
// Calculation is based on 100ns unit.
|
MicroSeconds,
|
||||||
//
|
3579545
|
||||||
Counter = (UINT32) DivU64x32Remainder (
|
),
|
||||||
MicroSeconds * 10,
|
1000000u
|
||||||
mMetronome->TickPeriod,
|
)
|
||||||
&Remainder
|
|
||||||
);
|
);
|
||||||
//
|
|
||||||
// Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
|
|
||||||
// periods, thus attempting to ensure Microseconds of stall time.
|
|
||||||
//
|
|
||||||
if (Remainder != 0) {
|
|
||||||
Counter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMetronome->WaitForTick (mMetronome, Counter);
|
|
||||||
**/
|
|
||||||
return MicroSeconds;
|
return MicroSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,11 +158,20 @@ NanoSecondDelay (
|
|||||||
IN UINTN NanoSeconds
|
IN UINTN NanoSeconds
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
if (InternalGetApciDescrptionTable() == NULL) {
|
||||||
// Duet platform need *not* this interface.
|
return NanoSeconds;
|
||||||
//
|
}
|
||||||
//ASSERT (FALSE);
|
|
||||||
return 0;
|
InternalAcpiDelay (
|
||||||
|
(UINT32)DivU64x32 (
|
||||||
|
MultU64x32 (
|
||||||
|
NanoSeconds,
|
||||||
|
3579545
|
||||||
|
),
|
||||||
|
1000000000u
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return NanoSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,11 +192,11 @@ GetPerformanceCounter (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
if (InternalGetApciDescrptionTable() == NULL) {
|
||||||
// Duet platform need *not* this interface.
|
|
||||||
//
|
|
||||||
//ASSERT (FALSE);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (UINT64)InternalAcpiGetTimerTick ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,9 +229,17 @@ GetPerformanceCounterProperties (
|
|||||||
OUT UINT64 *EndValue OPTIONAL
|
OUT UINT64 *EndValue OPTIONAL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
if (InternalGetApciDescrptionTable() == NULL) {
|
||||||
// Duet platform need *not* this interface.
|
|
||||||
//
|
|
||||||
//ASSERT (FALSE);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StartValue != NULL) {
|
||||||
|
*StartValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EndValue != NULL) {
|
||||||
|
*EndValue = (1 << gAcpiDesc->PM_TMR_BLK.RegisterBitWidth) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 3579545;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user