3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
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.
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.
20 ACPI Platform Driver Hooks
25 // Statements that include other files.
27 #include "AcpiPlatform.h"
28 #include "AcpiPlatformHooks.h"
32 // Prototypes of the various hook functions.
34 #include "AcpiPlatformHooksLib.h"
36 extern EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea
;
37 extern SYSTEM_CONFIGURATION mSystemConfiguration
;
39 ENHANCED_SPEEDSTEP_PROTOCOL
*mEistProtocol
= NULL
;
41 EFI_CPU_ID_MAP mCpuApicIdAcpiIdMapTable
[MAX_CPU_NUM
];
44 AppendCpuMapTableEntry (
45 IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*AcpiLocalApic
51 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
52 if ((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
== AcpiLocalApic
->ApicId
) && mCpuApicIdAcpiIdMapTable
[Index
].Flags
) {
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
;
74 UINT32 AcpiProcessorId
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
;
90 GetProcNumberInPackage (
98 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
99 if (mCpuApicIdAcpiIdMapTable
[Index
].Flags
&& (((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
>> 0x04) & 0x01) == Package
)) {
108 LocateCpuEistProtocol (
110 OUT ENHANCED_SPEEDSTEP_PROTOCOL
**EistProtocol
114 EFI_HANDLE
*HandleBuffer
;
115 ENHANCED_SPEEDSTEP_PROTOCOL
*EistProt
;
121 gBS
->LocateHandleBuffer (
123 &gEnhancedSpeedstepProtocolGuid
,
131 Status
= EFI_NOT_FOUND
;
132 while (Index
< HandleCount
) {
133 gBS
->HandleProtocol (
135 &gEnhancedSpeedstepProtocolGuid
,
139 // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.
141 ApicId
= ProcessorId2ApicId (CpuIndex
+1);
142 if (ApicId
== (UINT32
) -1) {
146 if (EistProt
->ProcApicId
== ApicId
) {
147 Status
= EFI_SUCCESS
;
154 if (HandleBuffer
!= NULL
) {
155 gBS
->FreePool (HandleBuffer
);
158 if (!EFI_ERROR (Status
)) {
159 *EistProtocol
= EistProt
;
161 *EistProtocol
= NULL
;
174 Status
= gBS
->LocateProtocol (
175 &gEnhancedSpeedstepProtocolGuid
,
177 (VOID
**) &mEistProtocol
180 ASSERT_EFI_ERROR (Status
);
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.
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.
197 @param[in] *Table Pointer to the active table.
199 @retval EFI_SUCCESS if the table is active.
200 @retval EFI_UNSUPPORTED if the table is not active.
204 AcpiPlatformHooksIsActiveTable (
205 IN OUT EFI_ACPI_COMMON_HEADER
*Table
208 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
210 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
212 if (TableHeader
->Signature
== EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE
) {
216 if ((mSystemConfiguration
.ENDBG2
== 0) && (CompareMem (&TableHeader
->OemTableId
, "INTLDBG2", 8) == 0)) {
217 return EFI_UNSUPPORTED
;
223 Update the GV3 SSDT table.
225 @param[in][out] *TableHeader The table to be set.
227 @retval EFI_SUCCESS Returns Success.
232 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
244 UINT32 NewPackageSize
;
248 EFI_ACPI_NAME_COMMAND
*PssTable
;
249 EFI_PSS_PACKAGE
*PssTableItemPtr
;
250 ENHANCED_SPEEDSTEP_PROTOCOL
*EistProt
;
251 EIST_INFORMATION
*EistInfo
;
252 EFI_ACPI_CPU_PSS_STATE
*PssState
;
253 EFI_ACPI_NAMEPACK_DWORD
*NamePtr
;
255 // Loop through the ASL looking for values that we must fix up.
261 CurrPtr
= (UINT8
*) TableHeader
;
264 for (SsdtPointer
= CurrPtr
; SsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); SsdtPointer
++) {
265 Signature
= *(UINT32
*) SsdtPointer
;
268 case SIGNATURE_32 ('_', 'P', 'R', '_'):
270 // _CPUX ('0' to '0xF')
272 CpuIndex
= *(SsdtPointer
+ 7);
273 if (CpuIndex
>= '0' && CpuIndex
<= '9') {
276 if (CpuIndex
> '9') {
282 LocateCpuEistProtocol (CpuIndex
, &EistProt
);
285 case SIGNATURE_32 ('D', 'O', 'M', 'N'):
287 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
288 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
292 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
298 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
299 NamePtr
->Value
= (mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01;
303 case SIGNATURE_32 ('N', 'C', 'P', 'U'):
305 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
306 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
310 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
315 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
316 NamePtr
->Value
= GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01);
320 case SIGNATURE_32 ('N', 'P', 'S', 'S'):
321 case SIGNATURE_32 ('S', 'P', 'S', 'S'):
322 if (EistProt
== NULL
) {
326 PssTable
= ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer
);
327 if (PssTable
->StartByte
!= AML_NAME_OP
) {
331 Status
= EistProt
->GetEistTable (EistProt
, &EistInfo
, (VOID
**) &PssState
);
333 AdjustSize
= PssTable
->NumEntries
* sizeof (EFI_PSS_PACKAGE
);
334 AdjustSize
-= EistInfo
->NumStates
* sizeof (EFI_PSS_PACKAGE
);
335 PackageSize
= (PssTable
->Size
& 0xF) + ((PssTable
->Size
& 0xFF00) >> 4);
336 NewPackageSize
= PackageSize
- AdjustSize
;
337 PssTable
->Size
= (UINT16
) ((NewPackageSize
& 0xF) + ((NewPackageSize
& 0x0FF0) << 4));
340 // Set most significant two bits of byte zero to 01, meaning two bytes used.
342 PssTable
->Size
|= 0x40;
345 // Set unused table to Noop Code.
347 SetMem( (UINT8
*) PssTable
+ NewPackageSize
+ AML_NAME_PREFIX_SIZE
, AdjustSize
, AML_NOOP_OP
);
348 PssTable
->NumEntries
= (UINT8
) EistInfo
->NumStates
;
349 PssTableItemPtr
= (EFI_PSS_PACKAGE
*) ((UINT8
*) PssTable
+ sizeof (EFI_ACPI_NAME_COMMAND
));
354 for (TableIndex
= 0; TableIndex
< EistInfo
->NumStates
; TableIndex
++) {
355 EntryIndex
= EistInfo
->NumStates
- TableIndex
- 1;
356 PssTableItemPtr
->CoreFreq
= PssState
[EntryIndex
].CoreFrequency
* PssState
[EntryIndex
].Control
;
357 PssTableItemPtr
->Power
= PssState
[EntryIndex
].Power
* 1000;
358 if (PssTable
->NameStr
== SIGNATURE_32 ('N', 'P', 'S', 'S')) {
359 PssTableItemPtr
->BMLatency
= PssState
[EntryIndex
].BusMasterLatency
;
360 PssTableItemPtr
->TransLatency
= PssState
[EntryIndex
].TransitionLatency
;
363 // This method should be supported by SMM PPM Handler.
365 PssTableItemPtr
->BMLatency
= PssState
[EntryIndex
].BusMasterLatency
* 2;
366 PssTableItemPtr
->TransLatency
= PssState
[EntryIndex
].TransitionLatency
* 10;
369 PssTableItemPtr
->Control
= PssState
[EntryIndex
].Control
;
370 PssTableItemPtr
->Status
= PssState
[EntryIndex
].Status
;
374 if (PssTable
->NameStr
== SIGNATURE_32 ('N', 'P', 'S', 'S')) {
380 SsdtPointer
= (UINT8
*) PssTable
+ PackageSize
;
386 // N fixes together currently.
388 ASSERT (CpuFixes
== (UINT32
) MAX_CPU_NUM
);
389 ASSERT (SpssFixes
== NpssFixes
);
390 ASSERT (CpuFixes
>= SpssFixes
);
396 Update the DSDT table.
398 @param[in][out] *TableHeader The table to be set.
400 @retval EFI_SUCCESS Returns EFI_SUCCESS.
405 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
418 // Fix PCI32 resource "FIX0" -- PSYS system status area
420 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
421 EndPtr
= (UINT8
*) TableHeader
;
422 EndPtr
= EndPtr
+ TableHeader
->Length
;
423 while (CurrPtr
< (EndPtr
-2)) {
425 // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space
426 // since there are only 3 char "_S3".
428 if (mSystemConfiguration
.AcpiSuspendState
== 0) {
430 // For iasl compiler version 20061109.
432 if ((CurrPtr
[0] == '_') && (CurrPtr
[1] == 'S') && (CurrPtr
[2] == '3') && (CurrPtr
[3] == '_')) {
436 // For iasl compiler version 20040527.
438 if ((CurrPtr
[0] == '\\') && (CurrPtr
[1] == '_') && (CurrPtr
[2] == 'S') && (CurrPtr
[3] == '3')) {
444 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
445 EndPtr
= (UINT8
*) TableHeader
;
446 EndPtr
= EndPtr
+ TableHeader
->Length
;
447 while (CurrPtr
< (EndPtr
-2)) {
449 // For mipi dsi port select _DEP.
451 if (mSystemConfiguration
.MipiDsi
== 1) {
453 // For iasl compiler version 20061109.
455 if ((CurrPtr
[0] == 'N') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
461 if ((CurrPtr
[0] == 'P') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
470 // Loop through the ASL looking for values that we must fix up.
472 CurrPtr
= (UINT8
*) TableHeader
;
473 for (DsdtPointer
= CurrPtr
; DsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); DsdtPointer
++) {
474 Signature
= (UINT32
*) DsdtPointer
;
476 switch (*Signature
) {
478 // GNVS operation region.
480 case (SIGNATURE_32 ('G', 'N', 'V', 'S')):
482 // Conditional match. For Region Objects, the Operator will always be the
483 // byte immediately before the specific name. Therefore, subtract 1 to check
486 Operation
= DsdtPointer
- 1;
487 if (*Operation
== AML_OPREGION_OP
) {
488 Address
= (UINT32
*) (DsdtPointer
+ 6);
489 *Address
= (UINT32
) (UINTN
) mGlobalNvsArea
.Area
;
490 Size
= (UINT16
*) (DsdtPointer
+ 11);
491 *Size
= sizeof (EFI_GLOBAL_NVS_AREA
);