| 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