]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
Vlv2TbltDevicePkg: Remove DxeTcg2PhysicalPresenceLibNull
[mirror_edk2.git] / Vlv2TbltDevicePkg / AcpiPlatform / AcpiPlatformHooks.c
CommitLineData
3cbfba02
DW
1/** @file\r
2\r
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
4 \r\r
5 This program and the accompanying materials are licensed and made available under\r\r
6 the terms and conditions of the BSD License that accompanies this distribution. \r\r
7 The full text of the license may be found at \r\r
8 http://opensource.org/licenses/bsd-license.php. \r\r
9 \r\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r
12 \r\r
13\r
14Module Name:\r
15\r
16 AcpiPlatformHooks.c\r
17\r
18Abstract:\r
19\r
20 ACPI Platform Driver Hooks\r
21\r
22--*/\r
23\r
24//\r
25// Statements that include other files.\r
26//\r
27#include "AcpiPlatform.h"\r
28#include "AcpiPlatformHooks.h"\r
29#include "Platform.h"\r
30\r
31//\r
32// Prototypes of the various hook functions.\r
33//\r
34#include "AcpiPlatformHooksLib.h"\r
35\r
3cbfba02
DW
36extern SYSTEM_CONFIGURATION mSystemConfiguration;\r
37\r
38ENHANCED_SPEEDSTEP_PROTOCOL *mEistProtocol = NULL;\r
39\r
40EFI_CPU_ID_MAP mCpuApicIdAcpiIdMapTable[MAX_CPU_NUM];\r
41\r
42EFI_STATUS\r
43AppendCpuMapTableEntry (\r
44 IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE *AcpiLocalApic\r
45 )\r
46{\r
47 BOOLEAN Added;\r
48 UINTN Index;\r
49\r
50 for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
51 if ((mCpuApicIdAcpiIdMapTable[Index].ApicId == AcpiLocalApic->ApicId) && mCpuApicIdAcpiIdMapTable[Index].Flags) {\r
52 return EFI_SUCCESS;\r
53 }\r
54 }\r
55\r
56 Added = FALSE;\r
57 for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
58 if (!mCpuApicIdAcpiIdMapTable[Index].Flags) {\r
59 mCpuApicIdAcpiIdMapTable[Index].Flags = 1;\r
60 mCpuApicIdAcpiIdMapTable[Index].ApicId = AcpiLocalApic->ApicId;\r
61 mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId = AcpiLocalApic->AcpiProcessorId;\r
62 Added = TRUE;\r
63 break;\r
64 }\r
65 }\r
66\r
67 ASSERT (Added);\r
68 return EFI_SUCCESS;\r
69}\r
70\r
71UINT32\r
72ProcessorId2ApicId (\r
73 UINT32 AcpiProcessorId\r
74 )\r
75{\r
76 UINTN Index;\r
77\r
78 ASSERT (AcpiProcessorId < MAX_CPU_NUM);\r
79 for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
80 if (mCpuApicIdAcpiIdMapTable[Index].Flags && (mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId == AcpiProcessorId)) {\r
81 return mCpuApicIdAcpiIdMapTable[Index].ApicId;\r
82 }\r
83 }\r
84\r
85 return (UINT32) -1;\r
86}\r
87\r
88UINT8\r
89GetProcNumberInPackage (\r
90 IN UINT8 Package\r
91 )\r
92{\r
93 UINTN Index;\r
94 UINT8 Number;\r
95\r
96 Number = 0;\r
97 for (Index = 0; Index < MAX_CPU_NUM; Index++) {\r
98 if (mCpuApicIdAcpiIdMapTable[Index].Flags && (((mCpuApicIdAcpiIdMapTable[Index].ApicId >> 0x04) & 0x01) == Package)) {\r
99 Number++;\r
100 }\r
101 }\r
102\r
103 return Number;\r
104}\r
105\r
106EFI_STATUS\r
107LocateCpuEistProtocol (\r
108 IN UINT32 CpuIndex,\r
109 OUT ENHANCED_SPEEDSTEP_PROTOCOL **EistProtocol\r
110 )\r
111{\r
112 UINTN HandleCount;\r
113 EFI_HANDLE *HandleBuffer;\r
114 ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;\r
115 UINTN Index;\r
116 UINT32 ApicId;\r
117 EFI_STATUS Status;\r
118\r
119 HandleCount = 0;\r
120 gBS->LocateHandleBuffer (\r
121 ByProtocol,\r
122 &gEnhancedSpeedstepProtocolGuid,\r
123 NULL,\r
124 &HandleCount,\r
125 &HandleBuffer\r
126 );\r
127\r
128 Index = 0;\r
129 EistProt = NULL;\r
130 Status = EFI_NOT_FOUND;\r
131 while (Index < HandleCount) {\r
132 gBS->HandleProtocol (\r
133 HandleBuffer[Index],\r
134 &gEnhancedSpeedstepProtocolGuid,\r
135 (VOID **) &EistProt\r
136 );\r
137 //\r
138 // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.\r
139 //\r
140 ApicId = ProcessorId2ApicId (CpuIndex+1);\r
141 if (ApicId == (UINT32) -1) {\r
142 break;\r
143 }\r
144\r
145 if (EistProt->ProcApicId == ApicId) {\r
146 Status = EFI_SUCCESS;\r
147 break;\r
148 }\r
149\r
150 Index++;\r
151 }\r
152\r
153 if (HandleBuffer != NULL) {\r
154 gBS->FreePool (HandleBuffer);\r
155 }\r
156\r
157 if (!EFI_ERROR (Status)) {\r
158 *EistProtocol = EistProt;\r
159 } else {\r
160 *EistProtocol = NULL;\r
161 }\r
162\r
163 return Status;\r
164}\r
165\r
166EFI_STATUS\r
167PlatformHookInit (\r
168 VOID\r
169 )\r
170{\r
171 EFI_STATUS Status;\r
172\r
173 Status = gBS->LocateProtocol (\r
174 &gEnhancedSpeedstepProtocolGuid,\r
175 NULL,\r
176 (VOID **) &mEistProtocol\r
177 );\r
178\r
179 ASSERT_EFI_ERROR (Status);\r
180\r
181 return Status;\r
182}\r
183\r
184/**\r
185 Called for every ACPI table found in the BIOS flash.\r
186 Returns whether a table is active or not. Inactive tables\r
187 are not published in the ACPI table list.\r
188\r
189 This hook can be used to implement optional SSDT tables or\r
190 enabling/disabling specific functionality (e.g. SPCR table)\r
191 based on a setup switch or platform preference. In case of\r
192 optional SSDT tables,the platform flash will include all the\r
193 SSDT tables but will return EFI_SUCCESS only for those tables\r
194 that need to be published.\r
195\r
196 @param[in] *Table Pointer to the active table.\r
197\r
198 @retval EFI_SUCCESS if the table is active.\r
199 @retval EFI_UNSUPPORTED if the table is not active.\r
200\r
201**/\r
202EFI_STATUS\r
203AcpiPlatformHooksIsActiveTable (\r
204 IN OUT EFI_ACPI_COMMON_HEADER *Table\r
205 )\r
206{\r
207 EFI_ACPI_DESCRIPTION_HEADER *TableHeader;\r
208\r
209 TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;\r
210\r
211 if (TableHeader->Signature == EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE) {\r
212\r
213 }\r
214\r
215 if ((mSystemConfiguration.ENDBG2 == 0) && (CompareMem (&TableHeader->OemTableId, "INTLDBG2", 8) == 0)) {\r
216 return EFI_UNSUPPORTED;\r
217 }\r
218 return EFI_SUCCESS;\r
219}\r
220\r
221/**\r
222 Update the GV3 SSDT table.\r
223\r
224 @param[in][out] *TableHeader The table to be set.\r
225\r
226 @retval EFI_SUCCESS Returns Success.\r
227\r
228**/\r
229EFI_STATUS\r
230PatchGv3SsdtTable (\r
231 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader\r
232 )\r
233{\r
3cbfba02
DW
234 UINT8 *CurrPtr;\r
235 UINT8 *SsdtPointer;\r
236 UINT32 Signature;\r
237 UINT32 CpuFixes;\r
238 UINT32 NpssFixes;\r
239 UINT32 SpssFixes;\r
240 UINT32 CpuIndex;\r
241 UINT32 PackageSize;\r
242 UINT32 NewPackageSize;\r
243 UINT32 AdjustSize;\r
244 UINTN EntryIndex;\r
245 UINTN TableIndex;\r
246 EFI_ACPI_NAME_COMMAND *PssTable;\r
247 EFI_PSS_PACKAGE *PssTableItemPtr;\r
248 ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;\r
249 EIST_INFORMATION *EistInfo;\r
250 EFI_ACPI_CPU_PSS_STATE *PssState;\r
251 EFI_ACPI_NAMEPACK_DWORD *NamePtr;\r
252 //\r
253 // Loop through the ASL looking for values that we must fix up.\r
254 //\r
255 NpssFixes = 0;\r
256 SpssFixes = 0;\r
257 CpuFixes = 0;\r
258 CpuIndex = 0;\r
259 CurrPtr = (UINT8 *) TableHeader;\r
260\r
261 EistProt = NULL;\r
262 for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {\r
263 Signature = *(UINT32 *) SsdtPointer;\r
264 switch (Signature) {\r
265\r
266 case SIGNATURE_32 ('_', 'P', 'R', '_'):\r
267 //\r
268 // _CPUX ('0' to '0xF')\r
269 //\r
270 CpuIndex = *(SsdtPointer + 7);\r
271 if (CpuIndex >= '0' && CpuIndex <= '9') {\r
272 CpuIndex -= '0';\r
273 } else {\r
274 if (CpuIndex > '9') {\r
275 CpuIndex -= '7';\r
276 }\r
277 }\r
278\r
279 CpuFixes++;\r
280 LocateCpuEistProtocol (CpuIndex, &EistProt);\r
281 break;\r
282\r
283 case SIGNATURE_32 ('D', 'O', 'M', 'N'):\r
284\r
285 NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);\r
286 if (NamePtr->StartByte != AML_NAME_OP) {\r
287 continue;\r
288 }\r
289\r
290 if (NamePtr->Size != AML_NAME_DWORD_SIZE) {\r
291 continue;\r
292 }\r
293\r
294 NamePtr->Value = 0;\r
295\r
296 if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {\r
297 NamePtr->Value = (mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01;\r
298 }\r
299 break;\r
300\r
301 case SIGNATURE_32 ('N', 'C', 'P', 'U'):\r
302\r
303 NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);\r
304 if (NamePtr->StartByte != AML_NAME_OP) {\r
305 continue;\r
306 }\r
307\r
308 if (NamePtr->Size != AML_NAME_DWORD_SIZE) {\r
309 continue;\r
310 }\r
311\r
312 NamePtr->Value = 0;\r
313 if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {\r
314 NamePtr->Value = GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01);\r
315 }\r
316 break;\r
317\r
318 case SIGNATURE_32 ('N', 'P', 'S', 'S'):\r
319 case SIGNATURE_32 ('S', 'P', 'S', 'S'):\r
320 if (EistProt == NULL) {\r
321 continue;\r
322 }\r
323\r
324 PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);\r
325 if (PssTable->StartByte != AML_NAME_OP) {\r
326 continue;\r
327 }\r
328\r
fe6e53b5 329 EistProt->GetEistTable (EistProt, &EistInfo, (VOID **) &PssState);\r
3cbfba02
DW
330\r
331 AdjustSize = PssTable->NumEntries * sizeof (EFI_PSS_PACKAGE);\r
332 AdjustSize -= EistInfo->NumStates * sizeof (EFI_PSS_PACKAGE);\r
333 PackageSize = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4);\r
334 NewPackageSize = PackageSize - AdjustSize;\r
335 PssTable->Size = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4));\r
336\r
337 //\r
338 // Set most significant two bits of byte zero to 01, meaning two bytes used.\r
339 //\r
340 PssTable->Size |= 0x40;\r
341\r
342 //\r
343 // Set unused table to Noop Code.\r
344 //\r
345 SetMem( (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, AdjustSize, AML_NOOP_OP);\r
346 PssTable->NumEntries = (UINT8) EistInfo->NumStates;\r
347 PssTableItemPtr = (EFI_PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (EFI_ACPI_NAME_COMMAND));\r
348\r
349 //\r
350 // Update the size.\r
351 //\r
352 for (TableIndex = 0; TableIndex < EistInfo->NumStates; TableIndex++) {\r
353 EntryIndex = EistInfo->NumStates - TableIndex - 1;\r
354 PssTableItemPtr->CoreFreq = PssState[EntryIndex].CoreFrequency * PssState[EntryIndex].Control;\r
355 PssTableItemPtr->Power = PssState[EntryIndex].Power * 1000;\r
356 if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {\r
357 PssTableItemPtr->BMLatency = PssState[EntryIndex].BusMasterLatency;\r
358 PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency;\r
359 } else {\r
360 //\r
361 // This method should be supported by SMM PPM Handler.\r
362 //\r
363 PssTableItemPtr->BMLatency = PssState[EntryIndex].BusMasterLatency * 2;\r
364 PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency * 10;\r
365 }\r
366\r
367 PssTableItemPtr->Control = PssState[EntryIndex].Control;\r
368 PssTableItemPtr->Status = PssState[EntryIndex].Status;\r
369 PssTableItemPtr++;\r
370 }\r
371\r
372 if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {\r
373 NpssFixes++;\r
374 } else {\r
375 SpssFixes++;\r
376 }\r
377\r
378 SsdtPointer = (UINT8 *) PssTable + PackageSize;\r
379 break;\r
380 }\r
381 }\r
382\r
383 //\r
384 // N fixes together currently.\r
385 //\r
386 ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);\r
387 ASSERT (SpssFixes == NpssFixes);\r
388 ASSERT (CpuFixes >= SpssFixes);\r
389\r
390 return EFI_SUCCESS;\r
391}\r
392\r
393/**\r
394 Update the DSDT table.\r
395\r
396 @param[in][out] *TableHeader The table to be set.\r
397\r
398 @retval EFI_SUCCESS Returns EFI_SUCCESS.\r
399\r
400**/\r
401EFI_STATUS\r
402PatchDsdtTable (\r
403 IN OUT EFI_ACPI_DESCRIPTION_HEADER *TableHeader\r
404 )\r
405{\r
406\r
407 UINT8 *CurrPtr;\r
408 UINT8 *DsdtPointer;\r
409 UINT32 *Signature;\r
410 UINT8 *EndPtr;\r
411 UINT8 *Operation;\r
412 UINT32 *Address;\r
413 UINT16 *Size;\r
414\r
415 //\r
416 // Fix PCI32 resource "FIX0" -- PSYS system status area\r
417 //\r
418 CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];\r
419 EndPtr = (UINT8*) TableHeader;\r
420 EndPtr = EndPtr + TableHeader->Length;\r
421 while (CurrPtr < (EndPtr-2)) {\r
422 //\r
423 // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space\r
424 // since there are only 3 char "_S3".\r
425 //\r
426 if (mSystemConfiguration.AcpiSuspendState == 0) {\r
427 //\r
428 // For iasl compiler version 20061109.\r
429 //\r
430 if ((CurrPtr[0] == '_') && (CurrPtr[1] == 'S') && (CurrPtr[2] == '3') && (CurrPtr[3] == '_')) {\r
431 break;\r
432 }\r
433 //\r
434 // For iasl compiler version 20040527.\r
435 //\r
436 if ((CurrPtr[0] == '\\') && (CurrPtr[1] == '_') && (CurrPtr[2] == 'S') && (CurrPtr[3] == '3')) {\r
437 break;\r
438 }\r
439 }\r
440 CurrPtr++;\r
441 }\r
442 CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];\r
443 EndPtr = (UINT8*) TableHeader;\r
444 EndPtr = EndPtr + TableHeader->Length;\r
445 while (CurrPtr < (EndPtr-2)) {\r
446 //\r
447 // For mipi dsi port select _DEP.\r
448 //\r
449 if (mSystemConfiguration.MipiDsi== 1) {\r
450 //\r
451 // For iasl compiler version 20061109.\r
452 //\r
453 if ((CurrPtr[0] == 'N') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {\r
454 CurrPtr[0] = '_';\r
455 break;\r
456 }\r
457\r
458 } else {\r
459 if ((CurrPtr[0] == 'P') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {\r
460 CurrPtr[0] = '_';\r
461 break;\r
462 }\r
463\r
464 }\r
465 CurrPtr++;\r
466 }\r
467 //\r
468 // Loop through the ASL looking for values that we must fix up.\r
469 //\r
470 CurrPtr = (UINT8 *) TableHeader;\r
471 for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {\r
472 Signature = (UINT32 *) DsdtPointer;\r
473\r
474 switch (*Signature) {\r
475 //\r
476 // GNVS operation region.\r
477 //\r
478 case (SIGNATURE_32 ('G', 'N', 'V', 'S')):\r
479 //\r
480 // Conditional match. For Region Objects, the Operator will always be the\r
481 // byte immediately before the specific name. Therefore, subtract 1 to check\r
482 // the Operator.\r
483 //\r
484 Operation = DsdtPointer - 1;\r
485 if (*Operation == AML_OPREGION_OP) {\r
486 Address = (UINT32 *) (DsdtPointer + 6);\r
487 *Address = (UINT32) (UINTN) mGlobalNvsArea.Area;\r
488 Size = (UINT16 *) (DsdtPointer + 11);\r
489 *Size = sizeof (EFI_GLOBAL_NVS_AREA);\r
490 }\r
491 break;\r
492 default:\r
493 break;\r
494 }\r
495 }\r
496 return EFI_SUCCESS;\r
497}\r
498\r