Newer
Older
AMI-Aptio-BIOS-Reversed / Metronome / Metronome.md
@Ajax Dong Ajax Dong 2 days ago 7 KB Init

Metronome

Function Table

Address Name Description
_mm_pause_w
__rdtsc_w
_enable_w
_disable_w
__getcallerseflags_w
IoRead32
ReadUnaligned64
PciExpressGetAddress
IoWrite16
MetronomeDriverInit
MetronomeWait
MicrosecondDelay
InternalAssert
InternalAssertEfiError
_ModuleEntryPoint
Global data (from .data section at 0xFC0-0x1060)
The EFI_HANDLE for this driver image (populated by UefiBootServicesTableLib).
The EFI_SYSTEM_TABLE pointer (populated by UefiBootServicesTableLib).
The EFI_BOOT_SERVICES pointer (derived from gSystemTable->BootServices).
The EFI_RUNTIME_SERVICES pointer (derived from gSystemTable->RuntimeServices).
Cached DebugLib protocol/PPI interface (initialised lazily).
Cached HOB list pointer (initialised lazily by GetHobList).
PCI Express MMIO base address (read from PCD via GetPcdProtocol).
Cached PCD protocol interface (initialised lazily by GetPcdProtocol).
EFI_METRONOME_ARCH_PROTOCOL instance installed by the driver.
Revision = 0x00010000, Wait = MetronomeWait.
GUID constants (from .rdata section).
gEfiMetronomeArchProtocolGuid const UINT8 gEfiMetronomeArchProtocolGuid[16] = EFI_METRONOME_ARCH_PROTOCOL_GUID;
gEfiPcdMetronomeInternalGuid (the PCD protocol GUID used by DxePcdLib)
The DebugLib singleton protocol GUID (gEfiDebugLibProtocolGuid placeholder)
Thunk / intrinsic wrappers
ASSERT ((Port & 3) == 0);
if ((Port & 3) != 0) {
ASSERT (Buffer != NULL);
if (Buffer == NULL) {
ASSERT ((Address & ~0xFFFFFFF) == 0)
if ((Address & 0xFFFFFFFFF0000000ULL) != 0) {
ASSERT ((Address & 1) == 0);
if (((UINT64)Address & 1) != 0) {
Library initialisation helpers
Save ImageHandle and SystemTable (UefiBootServicesTableLib init).
gImageHandle = ImageHandle;
Initialise HOB list (DxeHobLib).
GetHobList ();
Locate PCD protocol and read PcdPciExpressBaseAddress.
PcdProtocol = (UINT64)GetPcdProtocol ();
Call PcdGet64 (5) via the protocol's Get64 method at offset +32.
mPciExpressBaseAddress = ((UINT64 ()(UINT64))(PcdProtocol + 32))(5);
If PCI Express config space is accessible (PcdPciExpressBaseAddress != 0)
program the PIC via I/O ports.
if ((INT8)PciExpressGetAddress (1024068) >= 0) {
Set bit 7 at the PCI express offset for byte 1024068
Save interrupt state and disable interrupts.
InterruptsEnabled = (__getcallerseflags_w () & 0x200) != 0;
Read the current TSC and calculate the number of ticks corresponding
to 1288 microseconds. The calculation uses the PIT frequency:
Ticks = (PIT_FREQUENCY * Microseconds) / 1000000
The result captures the bottom 24 bits.
StartTSC = IoRead32 (1288) & 0xFFFFFF; // Read PIT counter 2 current value
Spin until the PIT counter has decremented by the delta.
RDTSC_WAIT_MASK handles 22-bit rollover.
Elapsed = StartTSC;
Capture the elapsed TSC value after the spin.
Microseconds = __rdtsc_w ();
Restore interrupt state.
if (InterruptsEnabled) {
Public Metronome protocol entry
Convert Microseconds to PIT ticks:
For large delays (>= 1000000 us == 1 s) we divide first to avoid overflow:
Ticks = 3579545 * (Microseconds / 10) / 100000
if (Microseconds >= MICROSECONDS_PER_SECOND) {
Internal delay implementation
Number of 0x400000-tick chunks
Remainder (< 0x400000)
Wait for the current 0x400000-tick chunk:
target = Delta + (PIT counter current value & 0xFFFFFF)
UINT32 Target = Delta + (IoRead32 (1288) & 0xFFFFFF);
Subsequent iterations wait a full chunk
Spin until the PIT counter passes the target.
The 0x800000 bit handles 24-bit counter rollover.
while (((Target - (UINT32)IoRead32 (1288)) & 0x800000) == 0) {
Library support functions
gSystemTable + 104 = Number of HOB entries
gSystemTable + 112 = Pointer to HOB entry array
HobList = NULL;
Walk the HOB entries looking for a GUID match with the
for (Index = 0; Index < (UINT64 )(gSystemTable + 104); Index++) {
Found -- extract the data pointer at offset +16 of the HOB entry.
HobList = (VOID )((UINT64 )((UINT64 )(gSystemTable + 112) + 24 Index + 16));
ASSERT_EFI_ERROR (EFI_NOT_FOUND)
InternalAssertEfiError (0x80000000LL
ASSERT (mHobList != NULL)
if (mHobList == 0) {
Read the GUID we are looking for (from the .data section at unk_FF0/FF8).
Guid1 = ReadUnaligned64 ((VOID )((UINT8 )&gEfiMetronomeArchProtocolGuid + 0));
Read the GUID from the HOB entry.
EntryGuid1 = ReadUnaligned64 (Entry);
if (Guid1 == EntryGuid1 && Guid2 == EntryGuid2) {
Call BootServices->LocateProtocol(&gPcdMetronomeInternalGuid, NULL, &mPcd)
BootServices at gSystemTable + (BootServices offset) = gBootServices.
LocateProtocol offset within BootServices = 320.
Status = ((UINT64 ()(VOID , UINT64, UINT64 ))(gBootServices + 320))(
ASSERT (mPcd != NULL)
if (mPcd == 0) {
Call BootServices->GetMemoryMap() to determine the number of pages
occupied by this image. For Metronome, this is a self-check.
BootServices offsets: GetMemoryMap at +24, AllocatePages at +32.
PageCount = ((UINT64 ()(UINT64))(gBootServices + 24))(31);
Only proceed if the image fits within 16 pages.
if (PageCount <= 16) {
Call DebugAssert (DebugLib + 8) with (FileName, LineNumber, Description).
Read RTC CMOS status register D (0x0D) via ports 0x70/0x71.
Preserve bit 7 (NMI enable) on the address port.
__outbyte **(RTC_PORT_CMOS_ADDR, RTC_REGISTER_D RTC_NMI_ENABLE_BIT);**
Determine the error mask based on RTC power status.
If CMOS register D > 3 and non-zero, derive the mask from the
if (CmosData > 3) {
Map CmosData to error mask:
CmosData == 1 -> ErrorMask = 0x80000004 (EFI_INVALID_PARAMETER style)
Otherwise -> ErrorMask = 0x80000006 (EFI_UNSUPPORTED style)
if ((CmosData - 1) <= 0xFD) {
If the status matches the error mask, call DebugPrint via the protocol.
if ((ErrorMask & Status) != 0) {
Driver entry point
Perform library and global initialisation.
MetronomeDriverInit (ImageHandle, SystemTable);
Check whether the Metronome Arch Protocol is already installed.
Protocol already installed ASSERT.
InternalAssert (
Install the protocol onto a new handle.
gBootServices + 328 = InstallProtocolInterface
Status = ((EFI_STATUS ()(VOID , VOID , VOID *, UINT64))(gBootServices + 328))(
New handle
Protocol GUID
Protocol interface
Not native (BOOLEAN = FALSE)
ASSERT_EFI_ERROR (Status)
if (EFI_ERROR (Status)) {

Generated by HR650X BIOS Decompilation Project