3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
15 ACPI Platform Driver Hooks
20 // Statements that include other files.
22 #include "AcpiPlatform.h"
23 #include "AcpiPlatformHooks.h"
27 // Prototypes of the various hook functions.
29 #include "AcpiPlatformHooksLib.h"
31 extern SYSTEM_CONFIGURATION mSystemConfiguration
;
33 ENHANCED_SPEEDSTEP_PROTOCOL
*mEistProtocol
= NULL
;
35 EFI_CPU_ID_MAP mCpuApicIdAcpiIdMapTable
[MAX_CPU_NUM
];
38 AppendCpuMapTableEntry (
39 IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*AcpiLocalApic
45 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
46 if ((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
== AcpiLocalApic
->ApicId
) && mCpuApicIdAcpiIdMapTable
[Index
].Flags
) {
52 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
53 if (!mCpuApicIdAcpiIdMapTable
[Index
].Flags
) {
54 mCpuApicIdAcpiIdMapTable
[Index
].Flags
= 1;
55 mCpuApicIdAcpiIdMapTable
[Index
].ApicId
= AcpiLocalApic
->ApicId
;
56 mCpuApicIdAcpiIdMapTable
[Index
].AcpiProcessorId
= AcpiLocalApic
->AcpiProcessorId
;
68 UINT32 AcpiProcessorId
73 ASSERT (AcpiProcessorId
< MAX_CPU_NUM
);
74 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
75 if (mCpuApicIdAcpiIdMapTable
[Index
].Flags
&& (mCpuApicIdAcpiIdMapTable
[Index
].AcpiProcessorId
== AcpiProcessorId
)) {
76 return mCpuApicIdAcpiIdMapTable
[Index
].ApicId
;
84 GetProcNumberInPackage (
92 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
93 if (mCpuApicIdAcpiIdMapTable
[Index
].Flags
&& (((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
>> 0x04) & 0x01) == Package
)) {
102 LocateCpuEistProtocol (
104 OUT ENHANCED_SPEEDSTEP_PROTOCOL
**EistProtocol
108 EFI_HANDLE
*HandleBuffer
;
109 ENHANCED_SPEEDSTEP_PROTOCOL
*EistProt
;
115 gBS
->LocateHandleBuffer (
117 &gEnhancedSpeedstepProtocolGuid
,
125 Status
= EFI_NOT_FOUND
;
126 while (Index
< HandleCount
) {
127 gBS
->HandleProtocol (
129 &gEnhancedSpeedstepProtocolGuid
,
133 // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.
135 ApicId
= ProcessorId2ApicId (CpuIndex
+1);
136 if (ApicId
== (UINT32
) -1) {
140 if (EistProt
->ProcApicId
== ApicId
) {
141 Status
= EFI_SUCCESS
;
148 if (HandleBuffer
!= NULL
) {
149 gBS
->FreePool (HandleBuffer
);
152 if (!EFI_ERROR (Status
)) {
153 *EistProtocol
= EistProt
;
155 *EistProtocol
= NULL
;
168 Status
= gBS
->LocateProtocol (
169 &gEnhancedSpeedstepProtocolGuid
,
171 (VOID
**) &mEistProtocol
174 ASSERT_EFI_ERROR (Status
);
180 Called for every ACPI table found in the BIOS flash.
181 Returns whether a table is active or not. Inactive tables
182 are not published in the ACPI table list.
184 This hook can be used to implement optional SSDT tables or
185 enabling/disabling specific functionality (e.g. SPCR table)
186 based on a setup switch or platform preference. In case of
187 optional SSDT tables,the platform flash will include all the
188 SSDT tables but will return EFI_SUCCESS only for those tables
189 that need to be published.
191 @param[in] *Table Pointer to the active table.
193 @retval EFI_SUCCESS if the table is active.
194 @retval EFI_UNSUPPORTED if the table is not active.
198 AcpiPlatformHooksIsActiveTable (
199 IN OUT EFI_ACPI_COMMON_HEADER
*Table
202 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
204 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
206 if (TableHeader
->Signature
== EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE
) {
210 if ((mSystemConfiguration
.ENDBG2
== 0) && (CompareMem (&TableHeader
->OemTableId
, "INTLDBG2", 8) == 0)) {
211 return EFI_UNSUPPORTED
;
217 Update the GV3 SSDT table.
219 @param[in][out] *TableHeader The table to be set.
221 @retval EFI_SUCCESS Returns Success.
226 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
237 UINT32 NewPackageSize
;
241 EFI_ACPI_NAME_COMMAND
*PssTable
;
242 EFI_PSS_PACKAGE
*PssTableItemPtr
;
243 ENHANCED_SPEEDSTEP_PROTOCOL
*EistProt
;
244 EIST_INFORMATION
*EistInfo
;
245 EFI_ACPI_CPU_PSS_STATE
*PssState
;
246 EFI_ACPI_NAMEPACK_DWORD
*NamePtr
;
248 // Loop through the ASL looking for values that we must fix up.
254 CurrPtr
= (UINT8
*) TableHeader
;
257 for (SsdtPointer
= CurrPtr
; SsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); SsdtPointer
++) {
258 Signature
= *(UINT32
*) SsdtPointer
;
261 case SIGNATURE_32 ('_', 'P', 'R', '_'):
263 // _CPUX ('0' to '0xF')
265 CpuIndex
= *(SsdtPointer
+ 7);
266 if (CpuIndex
>= '0' && CpuIndex
<= '9') {
269 if (CpuIndex
> '9') {
275 LocateCpuEistProtocol (CpuIndex
, &EistProt
);
278 case SIGNATURE_32 ('D', 'O', 'M', 'N'):
280 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
281 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
285 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
291 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
292 NamePtr
->Value
= (mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01;
296 case SIGNATURE_32 ('N', 'C', 'P', 'U'):
298 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
299 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
303 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
308 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
309 NamePtr
->Value
= GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01);
313 case SIGNATURE_32 ('N', 'P', 'S', 'S'):
314 case SIGNATURE_32 ('S', 'P', 'S', 'S'):
315 if (EistProt
== NULL
) {
319 PssTable
= ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer
);
320 if (PssTable
->StartByte
!= AML_NAME_OP
) {
324 EistProt
->GetEistTable (EistProt
, &EistInfo
, (VOID
**) &PssState
);
326 AdjustSize
= PssTable
->NumEntries
* sizeof (EFI_PSS_PACKAGE
);
327 AdjustSize
-= EistInfo
->NumStates
* sizeof (EFI_PSS_PACKAGE
);
328 PackageSize
= (PssTable
->Size
& 0xF) + ((PssTable
->Size
& 0xFF00) >> 4);
329 NewPackageSize
= PackageSize
- AdjustSize
;
330 PssTable
->Size
= (UINT16
) ((NewPackageSize
& 0xF) + ((NewPackageSize
& 0x0FF0) << 4));
333 // Set most significant two bits of byte zero to 01, meaning two bytes used.
335 PssTable
->Size
|= 0x40;
338 // Set unused table to Noop Code.
340 SetMem( (UINT8
*) PssTable
+ NewPackageSize
+ AML_NAME_PREFIX_SIZE
, AdjustSize
, AML_NOOP_OP
);
341 PssTable
->NumEntries
= (UINT8
) EistInfo
->NumStates
;
342 PssTableItemPtr
= (EFI_PSS_PACKAGE
*) ((UINT8
*) PssTable
+ sizeof (EFI_ACPI_NAME_COMMAND
));
347 for (TableIndex
= 0; TableIndex
< EistInfo
->NumStates
; TableIndex
++) {
348 EntryIndex
= EistInfo
->NumStates
- TableIndex
- 1;
349 PssTableItemPtr
->CoreFreq
= PssState
[EntryIndex
].CoreFrequency
* PssState
[EntryIndex
].Control
;
350 PssTableItemPtr
->Power
= PssState
[EntryIndex
].Power
* 1000;
351 if (PssTable
->NameStr
== SIGNATURE_32 ('N', 'P', 'S', 'S')) {
352 PssTableItemPtr
->BMLatency
= PssState
[EntryIndex
].BusMasterLatency
;
353 PssTableItemPtr
->TransLatency
= PssState
[EntryIndex
].TransitionLatency
;
356 // This method should be supported by SMM PPM Handler.
358 PssTableItemPtr
->BMLatency
= PssState
[EntryIndex
].BusMasterLatency
* 2;
359 PssTableItemPtr
->TransLatency
= PssState
[EntryIndex
].TransitionLatency
* 10;
362 PssTableItemPtr
->Control
= PssState
[EntryIndex
].Control
;
363 PssTableItemPtr
->Status
= PssState
[EntryIndex
].Status
;
367 if (PssTable
->NameStr
== SIGNATURE_32 ('N', 'P', 'S', 'S')) {
373 SsdtPointer
= (UINT8
*) PssTable
+ PackageSize
;
379 // N fixes together currently.
381 ASSERT (CpuFixes
== (UINT32
) MAX_CPU_NUM
);
382 ASSERT (SpssFixes
== NpssFixes
);
383 ASSERT (CpuFixes
>= SpssFixes
);
389 Update the DSDT table.
391 @param[in][out] *TableHeader The table to be set.
393 @retval EFI_SUCCESS Returns EFI_SUCCESS.
398 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
411 // Fix PCI32 resource "FIX0" -- PSYS system status area
413 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
414 EndPtr
= (UINT8
*) TableHeader
;
415 EndPtr
= EndPtr
+ TableHeader
->Length
;
416 while (CurrPtr
< (EndPtr
-2)) {
418 // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space
419 // since there are only 3 char "_S3".
421 if (mSystemConfiguration
.AcpiSuspendState
== 0) {
423 // For iasl compiler version 20061109.
425 if ((CurrPtr
[0] == '_') && (CurrPtr
[1] == 'S') && (CurrPtr
[2] == '3') && (CurrPtr
[3] == '_')) {
429 // For iasl compiler version 20040527.
431 if ((CurrPtr
[0] == '\\') && (CurrPtr
[1] == '_') && (CurrPtr
[2] == 'S') && (CurrPtr
[3] == '3')) {
437 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
438 EndPtr
= (UINT8
*) TableHeader
;
439 EndPtr
= EndPtr
+ TableHeader
->Length
;
440 while (CurrPtr
< (EndPtr
-2)) {
442 // For mipi dsi port select _DEP.
444 if (mSystemConfiguration
.MipiDsi
== 1) {
446 // For iasl compiler version 20061109.
448 if ((CurrPtr
[0] == 'N') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
454 if ((CurrPtr
[0] == 'P') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
463 // Loop through the ASL looking for values that we must fix up.
465 CurrPtr
= (UINT8
*) TableHeader
;
466 for (DsdtPointer
= CurrPtr
; DsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); DsdtPointer
++) {
467 Signature
= (UINT32
*) DsdtPointer
;
469 switch (*Signature
) {
471 // GNVS operation region.
473 case (SIGNATURE_32 ('G', 'N', 'V', 'S')):
475 // Conditional match. For Region Objects, the Operator will always be the
476 // byte immediately before the specific name. Therefore, subtract 1 to check
479 Operation
= DsdtPointer
- 1;
480 if (*Operation
== AML_OPREGION_OP
) {
481 Address
= (UINT32
*) (DsdtPointer
+ 6);
482 *Address
= (UINT32
) (UINTN
) mGlobalNvsArea
.Area
;
483 Size
= (UINT16
*) (DsdtPointer
+ 11);
484 *Size
= sizeof (EFI_GLOBAL_NVS_AREA
);