/** Get SMI handler profile database. **/ VOID GetSmiHandlerProfileDatabase( VOID ) { EFI_STATUS Status; UINTN CommSize; UINT8 *CommBuffer; EFI_SMM_COMMUNICATE_HEADER *CommHeader; SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *CommGetInfo; SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *CommGetData; EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; UINTN MinimalSizeNeeded; EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; UINT32 Index; EFI_MEMORY_DESCRIPTOR *Entry; VOID *Buffer; UINTN Size; UINTN Offset; Status = gBS->LocateProtocol(&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication); if (EFI_ERROR(Status)) { Print(L"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status); return ; } MinimalSizeNeeded = EFI_PAGE_SIZE; Status = EfiGetSystemConfigurationTable( &gEdkiiPiSmmCommunicationRegionTableGuid, (VOID **)&PiSmmCommunicationRegionTable ); if (EFI_ERROR(Status)) { Print(L"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status); return ; } ASSERT(PiSmmCommunicationRegionTable != NULL); Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1); Size = 0; for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { if (Entry->Type == EfiConventionalMemory) { Size = EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages); if (Size >= MinimalSizeNeeded) { break; } } Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize); } ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries); CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart; // // Get Size // CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid)); CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO); CommGetInfo = (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetInfo->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_INFO; CommGetInfo->Header.DataLength = sizeof(*CommGetInfo); CommGetInfo->Header.ReturnStatus = (UINT64)-1; CommGetInfo->DataSize = 0; CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize); if (EFI_ERROR(Status)) { Print(L"SmiHandlerProfile: SmmCommunication - %r\n", Status); return ; } if (CommGetInfo->Header.ReturnStatus != 0) { Print(L"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo->Header.ReturnStatus); return ; } mSmiHandlerProfileDatabaseSize = (UINTN)CommGetInfo->DataSize; // // Get Data // mSmiHandlerProfileDatabase = AllocateZeroPool(mSmiHandlerProfileDatabaseSize); if (mSmiHandlerProfileDatabase == NULL) { Status = EFI_OUT_OF_RESOURCES; Print(L"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize, Status); return ; } CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0]; CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid)); CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET); CommGetData = (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetData->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET; CommGetData->Header.DataLength = sizeof(*CommGetData); CommGetData->Header.ReturnStatus = (UINT64)-1; CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength; Buffer = (UINT8 *)CommHeader + CommSize; Size -= CommSize; CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer; CommGetData->DataOffset = 0; while (CommGetData->DataOffset < mSmiHandlerProfileDatabaseSize) { Offset = (UINTN)CommGetData->DataOffset; if (Size <= (mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset)) { CommGetData->DataSize = (UINT64)Size; } else { CommGetData->DataSize = (UINT64)(mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset); } Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize); ASSERT_EFI_ERROR(Status); if (CommGetData->Header.ReturnStatus != 0) { FreePool(mSmiHandlerProfileDatabase); mSmiHandlerProfileDatabase = NULL; Print(L"SmiHandlerProfile: GetData - 0x%x\n", CommGetData->Header.ReturnStatus); return ; } CopyMem((UINT8 *)mSmiHandlerProfileDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize); } DEBUG ((DEBUG_INFO, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize)); return ; }
/** Get and dump SMRAM profile data. @return EFI_SUCCESS Get the SMRAM profile data successfully. @return other Fail to get the SMRAM profile data. **/ EFI_STATUS GetSmramProfileData ( VOID ) { EFI_STATUS Status; UINTN CommSize; UINT8 *CommBuffer; EFI_SMM_COMMUNICATE_HEADER *CommHeader; SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo; SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *CommGetProfileData; UINT64 ProfileSize; PHYSICAL_ADDRESS ProfileBuffer; EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status)); return Status; } CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA); CommBuffer = AllocateZeroPool (CommSize); if (CommBuffer == NULL) { Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize, Status); return Status; } // // Get Size // CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO); CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO; CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo); CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1; CommGetProfileInfo->ProfileSize = 0; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); if (EFI_ERROR (Status)) { FreePool (CommBuffer); DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status)); return Status; } if (CommGetProfileInfo->Header.ReturnStatus != 0) { Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus); return EFI_SUCCESS; } ProfileSize = CommGetProfileInfo->ProfileSize; // // Get Data // ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool ((UINTN) ProfileSize); if (ProfileBuffer == 0) { FreePool (CommBuffer); Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN) ProfileSize, Status); return Status; } CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA); CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA; CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData); CommGetProfileData->Header.ReturnStatus = (UINT64)-1; CommGetProfileData->ProfileSize = ProfileSize; CommGetProfileData->ProfileBuffer = ProfileBuffer; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (CommGetProfileData->Header.ReturnStatus != 0) { FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer); FreePool (CommBuffer); Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus); return EFI_SUCCESS; } Print (L"SmramProfileSize - 0x%x\n", CommGetProfileData->ProfileSize); Print (L"======= SmramProfile begin =======\n"); DumpMemoryProfile (CommGetProfileData->ProfileBuffer, CommGetProfileData->ProfileSize); Print (L"======= SmramProfile end =======\n\n\n"); FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer); FreePool (CommBuffer); return EFI_SUCCESS; }
/** Get and dump SMRAM profile data. @return EFI_SUCCESS Get the SMRAM profile data successfully. @return other Fail to get the SMRAM profile data. **/ EFI_STATUS GetSmramProfileData ( VOID ) { EFI_STATUS Status; UINTN CommSize; UINT8 *CommBuffer; EFI_SMM_COMMUNICATE_HEADER *CommHeader; SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo; SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData; UINTN ProfileSize; VOID *ProfileBuffer; EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication; UINTN MinimalSizeNeeded; EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; UINT32 Index; EFI_MEMORY_DESCRIPTOR *Entry; VOID *Buffer; UINTN Size; UINTN Offset; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status)); return Status; } MinimalSizeNeeded = sizeof (EFI_GUID) + sizeof (UINTN) + MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO), sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)); MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT), MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO), MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO), MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR), MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY), sizeof (MEMORY_PROFILE_MEMORY_RANGE)))))); Status = EfiGetSystemConfigurationTable ( &gEdkiiPiSmmCommunicationRegionTableGuid, (VOID **) &PiSmmCommunicationRegionTable ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status)); return Status; } ASSERT (PiSmmCommunicationRegionTable != NULL); Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1); Size = 0; for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { if (Entry->Type == EfiConventionalMemory) { Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages); if (Size >= MinimalSizeNeeded) { break; } } Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize); } ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries); CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart; // // Get Size // CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO); CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO; CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo); CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1; CommGetProfileInfo->ProfileSize = 0; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status)); return Status; } if (CommGetProfileInfo->Header.ReturnStatus != 0) { Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus); return EFI_SUCCESS; } ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize; // // Get Data // ProfileBuffer = AllocateZeroPool (ProfileSize); if (ProfileBuffer == 0) { Status = EFI_OUT_OF_RESOURCES; Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status); return Status; } CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0]; CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid)); CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET); CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)]; CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET; CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData); CommGetProfileData->Header.ReturnStatus = (UINT64)-1; CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength; Buffer = (UINT8 *) CommHeader + CommSize; Size -= CommSize; CommGetProfileData->ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) Buffer; CommGetProfileData->ProfileOffset = 0; while (CommGetProfileData->ProfileOffset < ProfileSize) { Offset = (UINTN) CommGetProfileData->ProfileOffset; if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) { CommGetProfileData->ProfileSize = (UINT64) Size; } else { CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset); } Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (CommGetProfileData->Header.ReturnStatus != 0) { FreePool (ProfileBuffer); Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus); return EFI_SUCCESS; } CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize); } Print (L"SmramProfileSize - 0x%x\n", ProfileSize); Print (L"======= SmramProfile begin =======\n"); DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize); Print (L"======= SmramProfile end =======\n\n\n"); FreePool (ProfileBuffer); return EFI_SUCCESS; }
/** Install ACPI Firmware Performance Data Table (FPDT). @return Status code. **/ EFI_STATUS InstallFirmwarePerformanceDataTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; UINTN Size; UINT8 *SmmBootRecordCommBuffer; EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; SMM_BOOT_RECORD_COMMUNICATE *SmmCommData; UINTN CommSize; UINTN BootPerformanceDataSize; UINT8 *BootPerformanceData; EFI_SMM_COMMUNICATION_PROTOCOL *Communication; FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable; // // Get AcpiTable Protocol. // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol); if (EFI_ERROR (Status)) { return Status; } // // Collect boot records from SMM drivers. // SmmBootRecordCommBuffer = NULL; SmmCommData = NULL; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication); if (!EFI_ERROR (Status)) { // // Initialize communicate buffer // SmmBootRecordCommBuffer = AllocateZeroPool (SMM_BOOT_RECORD_COMM_SIZE); ASSERT (SmmBootRecordCommBuffer != NULL); SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)SmmBootRecordCommBuffer; SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)SmmCommBufferHeader->Data; ZeroMem((UINT8*)SmmCommData, sizeof(SMM_BOOT_RECORD_COMMUNICATE)); CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gEfiFirmwarePerformanceGuid); SmmCommBufferHeader->MessageLength = sizeof(SMM_BOOT_RECORD_COMMUNICATE); CommSize = SMM_BOOT_RECORD_COMM_SIZE; // // Get the size of boot records. // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE; SmmCommData->BootRecordData = NULL; Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (!EFI_ERROR (SmmCommData->ReturnStatus) && SmmCommData->BootRecordSize != 0) { // // Get all boot records // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA; SmmCommData->BootRecordData = AllocateZeroPool(SmmCommData->BootRecordSize); ASSERT (SmmCommData->BootRecordData != NULL); Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(SmmCommData->ReturnStatus); } } // // Prepare memory for Boot Performance table. // Boot Performance table includes BasicBoot record, and one or more appended Boot Records. // BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); if (SmmCommData != NULL) { BootPerformanceDataSize += SmmCommData->BootRecordSize; } // // Try to allocate the same runtime buffer as last time boot. // ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable)); Size = sizeof (PerformanceVariable); Status = gRT->GetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, NULL, &Size, &PerformanceVariable ); if (!EFI_ERROR (Status)) { Status = gBS->AllocatePages ( AllocateAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES (BootPerformanceDataSize), &PerformanceVariable.BootPerformanceTablePointer ); if (!EFI_ERROR (Status)) { mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.BootPerformanceTablePointer; } } if (mAcpiBootPerformanceTable == NULL) { // // Fail to allocate at specified address, continue to allocate at any address. // mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) FpdtAllocateReservedMemoryBelow4G (BootPerformanceDataSize); } DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable)); if (mAcpiBootPerformanceTable == NULL) { if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { FreePool (SmmCommData->BootRecordData); } if (SmmBootRecordCommBuffer != NULL) { FreePool (SmmBootRecordCommBuffer); } if (mAcpiS3PerformanceTable != NULL) { FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))); } return EFI_OUT_OF_RESOURCES; } // // Prepare Boot Performance Table. // BootPerformanceData = (UINT8 *) mAcpiBootPerformanceTable; // // Fill Basic Boot record to Boot Performance Table. // CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate)); BootPerformanceData = BootPerformanceData + mAcpiBootPerformanceTable->Header.Length; // // Fill Boot records from boot drivers. // CopyMem (BootPerformanceData, mBootRecordBuffer, mBootRecordSize); mAcpiBootPerformanceTable->Header.Length += mBootRecordSize; BootPerformanceData = BootPerformanceData + mBootRecordSize; if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { // // Fill Boot records from SMM drivers. // CopyMem (BootPerformanceData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize); FreePool (SmmCommData->BootRecordData); mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmCommData->BootRecordSize); BootPerformanceData = BootPerformanceData + SmmCommData->BootRecordSize; } if (SmmBootRecordCommBuffer != NULL) { FreePool (SmmBootRecordCommBuffer); } // // Save Boot Performance Table address to Variable for use in S4 resume. // PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable; // // Update Boot Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable; // // Save S3 Performance Table address to Variable for use in S4 resume. // PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable; // // Update S3 Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable; // // Save Runtime Performance Table pointers to Variable. // Status = gRT->SetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof (PerformanceVariable), &PerformanceVariable ); ASSERT_EFI_ERROR (Status); // // Publish Firmware Performance Data Table. // FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length); Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length, &mFirmwarePerformanceTableTemplateKey ); if (EFI_ERROR (Status)) { FreePages (mAcpiBootPerformanceTable, EFI_SIZE_TO_PAGES (BootPerformanceDataSize)); if (mAcpiS3PerformanceTable != NULL) { FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))); } mAcpiBootPerformanceTable = NULL; mAcpiS3PerformanceTable = NULL; return Status; } // // Free temp Boot record, and update Boot Record to point to Basic Boot performance table. // if (mBootRecordBuffer != NULL) { FreePool (mBootRecordBuffer); } mBootRecordBuffer = (UINT8 *) mAcpiBootPerformanceTable; mBootRecordSize = mAcpiBootPerformanceTable->Header.Length; mBootRecordMaxSize = mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); return EFI_SUCCESS; }