UEFI News and Commentary

Sunday, September 08, 2013

UEFI 2.4 Review, Part 11: Timestamp Protocol

This article is the eleventh in a series looking at the changes introduced in the UEFI 2.4 specification. This time we take a look at the time stamp protocol (EFI_TIMESTAMP_PROTOCOL) in chapter 34.

Timestamp counters are common on various CPU architectures. So common, in fact, that many features have come to rely on them, such as ACPI's Firmware Performance Data Table (FPDT, chapter 5.2.23). On the x86 processors, the RDTSC instruction returns the current value. But, in various incarnations, this value has to be manipulated based on the number of cores, power-state, etc. So how to get a reliable number? Or, for that matter, how does this map on to ARM's generic timer?

I recently ran into this while trying to build the UEFI shell. There were recent changes to add the DP command, which displays the FPDT contents, to the UEFI shell. But this command had a dependency on the TimerLib, which was fixed at build time for a specific hardware implementation. That means that if the shell was run on another system, with a slightly different timer implementation, the DP command would not work or, worse, return the wrong value.

Whenever there is a hardware dependency like this, UEFI likes to abstract the hardware capability behind a protocol. In this case the EFI_TIMESTAMP_PROTOCOL was modeled after the TimerLib. It has two functions: GetTimeStamp() and GetProperties().

GetTimeStamp() simply returns the current time stamp value. There are a few restrictions though: the frequency of the time stamp must remain constant, regardless of power management state and the time stamp value may roll over. This latter is very important, especially for time stamp counters with fewer bits, since they can roll over in a few seconds.

GetProperties() returns the frequency (in Hz) of the time stamp counter, and the maximum value. This allows the caller to convert differences between time stamp counter values into actual time. It also allows for it to check for overflows. This is importance, since some implementations use the ACPI timer instead of an integrated CPU time stamp counter, and some implementations of the ACPI timer are only 24- or 32-bits in size.

With this new protocol, UEFI 2.4 allows utilities to track performance of a system in a way which spans the wide variety of system and CPU architectures supported.


Estelle said...
This comment has been removed by the author.
Estelle said...

How do you use those functions? I declared a EFI_TIMESTAMP_PROTOCOL pointer (gTimestamp) and used it like gTimestamp->GetTimestamp() but my code hangs. I tried to gBS->LocateProtocol(&gEfiTimestampProtocolGuid, NULL, (VOID**)&gTimestamp) but then it doesn't compile because of an unresolved external symbol (gEfiTimestampProtocolGuid). I included Protocol/Timestamp.h so I'm not sure what I'mm doing wrong... Could you provide an example of how to use these timestamp functions please?