]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / FirmwarePerformanceDataTablePei / FirmwarePerformancePei.c
CommitLineData
0284e90c
LG
1/** @file\r
2 This module updates S3 Resume Performance Record in ACPI Firmware Performance\r
c1acb0f9 3 Data Table in S3 resume boot mode.\r
0284e90c
LG
4\r
5 This module register report status code listener to collect performance data\r
6 for S3 Resume Performance Record on S3 resume boot path.\r
7\r
2040e6c5 8 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 9 SPDX-License-Identifier: BSD-2-Clause-Patent\r
0284e90c
LG
10\r
11**/\r
12\r
13#include <PiPei.h>\r
14\r
0284e90c 15#include <Ppi/ReportStatusCodeHandler.h>\r
2040e6c5 16#include <Ppi/ReadOnlyVariable2.h>\r
0284e90c
LG
17\r
18#include <Guid/FirmwarePerformance.h>\r
2040e6c5
DB
19#include <Guid/Performance.h>\r
20#include <Guid/ExtendedFirmwarePerformance.h>\r
0284e90c
LG
21\r
22#include <Library/PeiServicesLib.h>\r
23#include <Library/BaseLib.h>\r
24#include <Library/DebugLib.h>\r
25#include <Library/TimerLib.h>\r
26#include <Library/BaseMemoryLib.h>\r
27#include <Library/LockBoxLib.h>\r
0284e90c 28#include <Library/PcdLib.h>\r
2040e6c5 29#include <Library/HobLib.h>\r
0284e90c
LG
30\r
31/**\r
32 Report status code listener for PEI. This is used to record the performance\r
33 data for S3 FullResume in FPDT.\r
34\r
35 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
36 @param[in] CodeType Indicates the type of status code being reported.\r
37 @param[in] Value Describes the current status of a hardware or software entity.\r
38 This included information about the class and subclass that is used to\r
39 classify the entity as well as an operation.\r
40 @param[in] Instance The enumeration of a hardware or software entity within\r
41 the system. Valid instance numbers start with 1.\r
42 @param[in] CallerId This optional parameter may be used to identify the caller.\r
43 This parameter allows the status code driver to apply different rules to\r
44 different callers.\r
45 @param[in] Data This optional parameter may be used to pass additional data.\r
46\r
47 @retval EFI_SUCCESS Status code is what we expected.\r
48 @retval EFI_UNSUPPORTED Status code not supported.\r
49\r
50**/\r
51EFI_STATUS\r
52EFIAPI\r
53FpdtStatusCodeListenerPei (\r
1436aea4
MK
54 IN CONST EFI_PEI_SERVICES **PeiServices,\r
55 IN EFI_STATUS_CODE_TYPE CodeType,\r
56 IN EFI_STATUS_CODE_VALUE Value,\r
57 IN UINT32 Instance,\r
58 IN CONST EFI_GUID *CallerId,\r
59 IN CONST EFI_STATUS_CODE_DATA *Data\r
0284e90c
LG
60 )\r
61{\r
62 EFI_STATUS Status;\r
63 UINT64 CurrentTime;\r
0284e90c 64 UINTN VarSize;\r
db91c620 65 EFI_PHYSICAL_ADDRESS S3PerformanceTablePointer;\r
0284e90c
LG
66 S3_PERFORMANCE_TABLE *AcpiS3PerformanceTable;\r
67 EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD *AcpiS3ResumeRecord;\r
68 UINT64 S3ResumeTotal;\r
69 EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD S3SuspendRecord;\r
70 EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD *AcpiS3SuspendRecord;\r
2040e6c5
DB
71 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;\r
72 UINT8 *BootPerformanceTable;\r
73 FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;\r
74 EFI_HOB_GUID_TYPE *GuidHob;\r
75 FPDT_PEI_EXT_PERF_HEADER *PeiPerformanceLogHeader;\r
76 UINT8 *FirmwarePerformanceData;\r
77 UINT8 *FirmwarePerformanceTablePtr;\r
0284e90c
LG
78\r
79 //\r
80 // Check whether status code is what we are interested in.\r
81 //\r
82 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) ||\r
1436aea4
MK
83 (Value != (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE)))\r
84 {\r
0284e90c
LG
85 return EFI_UNSUPPORTED;\r
86 }\r
87\r
88 //\r
89 // Retrieve current time as early as possible.\r
90 //\r
91 CurrentTime = GetTimeInNanoSecond (GetPerformanceCounter ());\r
92\r
0284e90c
LG
93 //\r
94 // Update S3 Resume Performance Record.\r
95 //\r
db91c620 96 S3PerformanceTablePointer = 0;\r
1436aea4
MK
97 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
98 Status = RestoreLockBox (&gFirmwarePerformanceS3PointerGuid, &S3PerformanceTablePointer, &VarSize);\r
db91c620 99 ASSERT_EFI_ERROR (Status);\r
0284e90c 100\r
1436aea4 101 AcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *)(UINTN)S3PerformanceTablePointer;\r
0284e90c 102 ASSERT (AcpiS3PerformanceTable != NULL);\r
db91c620 103 if (AcpiS3PerformanceTable->Header.Signature != EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE) {\r
87000d77 104 DEBUG ((DEBUG_ERROR, "FPDT S3 performance data in ACPI memory get corrupted\n"));\r
db91c620
SZ
105 return EFI_ABORTED;\r
106 }\r
1436aea4
MK
107\r
108 AcpiS3ResumeRecord = &AcpiS3PerformanceTable->S3Resume;\r
0284e90c
LG
109 AcpiS3ResumeRecord->FullResume = CurrentTime;\r
110 //\r
111 // Calculate average S3 resume time.\r
112 //\r
113 S3ResumeTotal = MultU64x32 (AcpiS3ResumeRecord->AverageResume, AcpiS3ResumeRecord->ResumeCount);\r
114 AcpiS3ResumeRecord->ResumeCount++;\r
115 AcpiS3ResumeRecord->AverageResume = DivU64x32 (S3ResumeTotal + AcpiS3ResumeRecord->FullResume, AcpiS3ResumeRecord->ResumeCount);\r
116\r
87000d77
MK
117 DEBUG ((DEBUG_INFO, "FPDT: S3 Resume Performance - ResumeCount = %d\n", AcpiS3ResumeRecord->ResumeCount));\r
118 DEBUG ((DEBUG_INFO, "FPDT: S3 Resume Performance - FullResume = %ld\n", AcpiS3ResumeRecord->FullResume));\r
119 DEBUG ((DEBUG_INFO, "FPDT: S3 Resume Performance - AverageResume = %ld\n", AcpiS3ResumeRecord->AverageResume));\r
0284e90c
LG
120\r
121 //\r
122 // Update S3 Suspend Performance Record.\r
123 //\r
124 AcpiS3SuspendRecord = &AcpiS3PerformanceTable->S3Suspend;\r
1436aea4 125 VarSize = sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD);\r
0284e90c
LG
126 ZeroMem (&S3SuspendRecord, sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD));\r
127 Status = RestoreLockBox (\r
128 &gEfiFirmwarePerformanceGuid,\r
129 &S3SuspendRecord,\r
130 &VarSize\r
131 );\r
132 ASSERT_EFI_ERROR (Status);\r
133\r
134 AcpiS3SuspendRecord->SuspendStart = S3SuspendRecord.SuspendStart;\r
135 AcpiS3SuspendRecord->SuspendEnd = S3SuspendRecord.SuspendEnd;\r
136\r
87000d77
MK
137 DEBUG ((DEBUG_INFO, "FPDT: S3 Suspend Performance - SuspendStart = %ld\n", AcpiS3SuspendRecord->SuspendStart));\r
138 DEBUG ((DEBUG_INFO, "FPDT: S3 Suspend Performance - SuspendEnd = %ld\n", AcpiS3SuspendRecord->SuspendEnd));\r
0284e90c 139\r
2040e6c5
DB
140 Status = PeiServicesLocatePpi (\r
141 &gEfiPeiReadOnlyVariable2PpiGuid,\r
142 0,\r
143 NULL,\r
1436aea4 144 (VOID **)&VariableServices\r
2040e6c5
DB
145 );\r
146 ASSERT_EFI_ERROR (Status);\r
147\r
148 //\r
149 // Update S3 boot records into the basic boot performance table.\r
150 //\r
151 VarSize = sizeof (PerformanceVariable);\r
1436aea4
MK
152 Status = VariableServices->GetVariable (\r
153 VariableServices,\r
154 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,\r
155 &gEfiFirmwarePerformanceGuid,\r
156 NULL,\r
157 &VarSize,\r
158 &PerformanceVariable\r
159 );\r
2040e6c5
DB
160 if (EFI_ERROR (Status)) {\r
161 return Status;\r
162 }\r
1436aea4
MK
163\r
164 BootPerformanceTable = (UINT8 *)(UINTN)PerformanceVariable.BootPerformanceTablePointer;\r
2040e6c5
DB
165\r
166 //\r
167 // Dump PEI boot records\r
168 //\r
169 FirmwarePerformanceTablePtr = (BootPerformanceTable + sizeof (BOOT_PERFORMANCE_TABLE));\r
1436aea4 170 GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);\r
2040e6c5
DB
171 while (GuidHob != NULL) {\r
172 FirmwarePerformanceData = GET_GUID_HOB_DATA (GuidHob);\r
1436aea4 173 PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)FirmwarePerformanceData;\r
2040e6c5
DB
174\r
175 CopyMem (FirmwarePerformanceTablePtr, FirmwarePerformanceData + sizeof (FPDT_PEI_EXT_PERF_HEADER), (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries));\r
176\r
177 GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));\r
178\r
179 FirmwarePerformanceTablePtr += (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries);\r
180 }\r
181\r
182 //\r
183 // Update Table length.\r
184 //\r
1436aea4 185 ((BOOT_PERFORMANCE_TABLE *)BootPerformanceTable)->Header.Length = (UINT32)((UINTN)FirmwarePerformanceTablePtr - (UINTN)BootPerformanceTable);\r
2040e6c5 186\r
0284e90c
LG
187 return EFI_SUCCESS;\r
188}\r
189\r
190/**\r
191 Main entry for Firmware Performance Data Table PEIM.\r
192\r
193 This routine is to register report status code listener for FPDT.\r
194\r
195 @param[in] FileHandle Handle of the file being invoked.\r
196 @param[in] PeiServices Pointer to PEI Services table.\r
197\r
198 @retval EFI_SUCCESS Report status code listener is registered successfully.\r
199\r
200**/\r
201EFI_STATUS\r
202EFIAPI\r
203FirmwarePerformancePeiEntryPoint (\r
204 IN EFI_PEI_FILE_HANDLE FileHandle,\r
205 IN CONST EFI_PEI_SERVICES **PeiServices\r
206 )\r
207{\r
208 EFI_STATUS Status;\r
0284e90c 209 EFI_PEI_RSC_HANDLER_PPI *RscHandler;\r
0284e90c 210\r
04f4c2d6 211 if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {\r
0284e90c 212 //\r
04f4c2d6 213 // S3 resume - register status code listener for OS wake vector.\r
0284e90c
LG
214 //\r
215 Status = PeiServicesLocatePpi (\r
04f4c2d6 216 &gEfiPeiRscHandlerPpiGuid,\r
0284e90c
LG
217 0,\r
218 NULL,\r
1436aea4 219 (VOID **)&RscHandler\r
0284e90c 220 );\r
04f4c2d6
HW
221 ASSERT_EFI_ERROR (Status);\r
222\r
223 Status = RscHandler->Register (FpdtStatusCodeListenerPei);\r
224 ASSERT_EFI_ERROR (Status);\r
225 }\r
226\r
0284e90c
LG
227 return EFI_SUCCESS;\r
228}\r