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