audk/ArmPlatformPkg
Laszlo Ersek ab879e4cb3 ArmVirtualizationQemu: ask the hardware for the timer frequency
Roughly, there are two ways to "measure ticks" in UEFI:

- the SetTimer() boot service, which sets up a one-shot or periodic event
  callback, and takes the interval length in units of 100ns,

- the Stall() boot service, which stalls the caller (but does not yield
  the CPU) for the interval specified. The interval is taken as a number
  of microseconds.

If the platform in question also follows the PI (Platform Init)
specification, then it is recommended to implement the above UEFI services
on top of the following DXE Architectural Protocols (described in PI
Volume 2):

- Timer Architectural Protocol:

  "Used to set up a periodic timer interrupt using a platform specific
  timer, and a processor-specific interrupt vector. This protocol enables
  the use of the SetTimer() Boot Service. [...]"

- Metronome Architectural Protocol:

  "Used to wait for ticks from a known time source in a platform. This
  protocol may be used to implement a simple version of the Stall() Boot
  Service. [...]"

Edk2 in general, and ArmVirtualizationQemu in particular, follow the above
pattern.

SetTimer() works correctly. The underlying Timer Architectural Protocol is
provided by "ArmPkg/Drivers/TimerDxe", and that driver calls the internal
function ArmGenericTimerGetTimerFreq() to retrieve the timer frequency.
Ultimately it boils down to reading the CNTFRQ_EL0 register.

The correct behavior of SetTimer() can be observed for example:
- in the grub-efi countdown ("grub-core/kern/arm/efi/init.c"),
- in the Intel BDS front page countdown
  ("IntelFrameworkModulePkg/Universal/BdsDxe/FrontPage.c").

However, Stall() doesn't work correctly. The underlying Metronome
Architectural Protocol is provided by "EmbeddedPkg/MetronomeDxe", which
further delegates the job to the TimerLib library class. That in turn is
resolved to the "ArmPkg/Library/ArmArchTimerLib" instance, which
(finally!) takes the timer frequency from "PcdArmArchTimerFreqInHz".

In ArmVirtualizationQemu we currently specify 100MHz for this PCD. Alas,
that's incorect for:
- both QEMU/TCG (which emulates 62.5MHz, see GTIMER_SCALE in
  "target-arm/internals.h"),
- and KVM (where the host's virtualized timer can tick at 50 MHz, for
  example).

Set the PCD to 0, asking ArmArchTimerLib to interrogate CNTFRQ_EL0 as
well.

The change can be tested with eg. the following callers of Stall():
- the UEFI Shell's countdown -- before it runs "startup.nsh" -- relies on
  Stall(),
- the UEFI shell command "stall" also uses Stall(). (Time it with a
  stopwatch.)

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Olivier Martin <Olivier.martin@arm.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16692 6f19259b-4bc3-4df7-8a09-765794883524
2015-02-02 12:01:58 +00:00
..
ArmJunoPkg ArmPlatformPkg/ArmJunoPkg/AcpiTables: Updated with new ACPI 5.1 Tables & Definitions 2015-01-23 16:07:38 +00:00
ArmRealViewEbPkg ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit. 2014-11-11 00:43:03 +00:00
ArmVExpressPkg ArmPlatformPkg/ArmJunoPkg: Added ACPI support 2015-01-23 16:01:11 +00:00
ArmVirtualizationPkg ArmVirtualizationQemu: ask the hardware for the timer frequency 2015-02-02 12:01:58 +00:00
Bds ArmPlatformPkg/Bds: Signal when the variable 'Fdt' has been updated 2015-01-06 15:54:12 +00:00
Documentation ArmPlatformPkg/Documentation: Removed BaseTools-Pending-Patches.patch 2014-10-29 18:55:29 +00:00
Drivers ArmPlatformPkg: detect correct pl011 fifo depth 2015-01-23 16:10:00 +00:00
FileSystem/BootMonFs ArmPlatformPkg: Fixed builds after some ShellPkg libraries have moved 2015-01-13 18:58:00 +00:00
Include ArmPlatformPkg: detect correct pl011 fifo depth 2015-01-23 16:10:00 +00:00
Library ArmPlatformPkg: fix undefined reference to memcpy 2014-11-12 10:01:41 +00:00
MemoryInitPei ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit. 2014-11-11 00:43:03 +00:00
PlatformPei ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit. 2014-11-11 00:43:03 +00:00
PrePeiCore ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit. 2014-11-11 00:43:03 +00:00
PrePi ArmPkg,ArmPlatformPkg: Allow dynamic PCDs for memory base and size 2014-09-09 16:11:30 +00:00
Scripts ArmPlatformPkg/Scripts: Update the profiling script to work on AArch64 with the latest DS-5 2014-08-19 13:36:00 +00:00
Sec ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit. 2014-11-11 00:43:03 +00:00
ArmPlatformPkg-2ndstage.dsc ARM Packages: Added support for GCC stack protector 2014-08-20 18:01:50 +00:00
ArmPlatformPkg-2ndstage.fdf ARM Packages: Removed malicious trailing spaces 2014-08-20 11:38:45 +00:00
ArmPlatformPkg.dec ArmPlatformPkg/Bds: Signal when the variable 'Fdt' has been updated 2015-01-06 15:54:12 +00:00
ArmPlatformPkg.dsc ArmPlatformPkg: separate PlatformPei and PlatformPeiLib 2014-09-16 00:56:50 +00:00
ArmPlatformPkg.fdf ARM Packages: Removed malicious trailing spaces 2014-08-20 11:38:45 +00:00
Contributions.txt EDK II Contributions.txt: Update patch format information 2014-10-31 22:05:50 +00:00
License.txt EDK II Packages: Added License.txt files 2012-04-12 16:40:32 +00:00