Inits mem log. @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. **/
| 96 | |
| 97 | **/ |
| 98 | EFI_STATUS |
| 99 | EFIAPI |
| 100 | MemLogInit ( |
| 101 | VOID |
| 102 | ) |
| 103 | { |
| 104 | EFI_STATUS Status; |
| 105 | UINT32 TimerAddr = 0; |
| 106 | UINT64 Tsc0, Tsc1; |
| 107 | UINT32 AcpiTick0, AcpiTick1, AcpiTicksDelta, AcpiTicksTarget; |
| 108 | CHAR8 InitError[50]; |
| 109 | |
| 110 | if (mMemLog != NULL) { |
| 111 | return EFI_SUCCESS; |
| 112 | } |
| 113 | |
| 114 | // |
| 115 | // Try to use existing MEM_LOG |
| 116 | // |
| 117 | Status = gBS->LocateProtocol (&mMemLogProtocolGuid, NULL, (VOID **) &mMemLog); |
| 118 | if (Status == EFI_SUCCESS && mMemLog != NULL) { |
| 119 | // |
| 120 | // We are inited with existing MEM_LOG |
| 121 | // |
| 122 | return EFI_SUCCESS; |
| 123 | } |
| 124 | |
| 125 | // |
| 126 | // Set up and publish new MEM_LOG |
| 127 | // |
| 128 | mMemLog = AllocateZeroPool( sizeof (MEM_LOG) ); |
| 129 | if (mMemLog == NULL) { |
| 130 | return EFI_OUT_OF_RESOURCES; |
| 131 | } |
| 132 | mMemLog->BufferSize = MEM_LOG_INITIAL_SIZE; |
| 133 | mMemLog->Buffer = AllocateZeroPool(MEM_LOG_INITIAL_SIZE); |
| 134 | mMemLog->Cursor = mMemLog->Buffer; |
| 135 | mMemLog->Callback = NULL; |
| 136 | |
| 137 | // |
| 138 | // Calibrate TSC for timings |
| 139 | // |
| 140 | InitError[0]='\0'; |
| 141 | |
| 142 | // We will try to calibrate TSC frequency according to the ACPI Power Management Timer. |
| 143 | // The ACPI PM Timer is running at a universal known frequency of 3579545Hz. |
| 144 | // So, we wait 357954 clocks of the ACPI timer (100ms), and compare with how much TSC advanced. |
| 145 | // This seems to provide a much more accurate calibration than using gBS->Stall(), especially on UEFI machines, and is important as this value is used later to calculate FSBFrequency. |
| 146 | |
| 147 | // Check if we can use the timer - we need to be on Intel ICH, get ACPI PM Timer Address from PCI, and check that it's sane |
| 148 | if ((PciRead16 (PCI_ICH_LPC_ADDRESS (0))) != 0x8086) { // Intel ICH device was not found |
| 149 | AsciiSPrint(InitError, sizeof(InitError), "Intel ICH device was not found."); |
| 150 | } else if ((PciRead8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNT)) & B_ICH_LPC_ACPI_CNT_ACPI_EN) == 0) { // Check for TSC at LPC (default location) |
| 151 | /* if ((PciRead8 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_CNT)) & B_ICH_SMBUS_ACPI_CNT_ACPI_EN) != 0) { // Check for TSC at SMBUS (Skylake specific) |
| 152 | TimerAddr = (PciRead16 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_BASE)) & B_ICH_SMBUS_ACPI_BASE_BAR) + R_ACPI_PM1_TMR; |
| 153 | } else { */ |
| 154 | AsciiSPrint(InitError, sizeof(InitError), "ACPI I/O space is not enabled."); |
| 155 | // } |
no test coverage detected