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