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