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 SYSTEM_CONFIGURATION mSystemConfiguration
;
38 ENHANCED_SPEEDSTEP_PROTOCOL
*mEistProtocol
= NULL
;
40 EFI_CPU_ID_MAP mCpuApicIdAcpiIdMapTable
[MAX_CPU_NUM
];
43 AppendCpuMapTableEntry (
44 IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE
*AcpiLocalApic
50 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
51 if ((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
== AcpiLocalApic
->ApicId
) && mCpuApicIdAcpiIdMapTable
[Index
].Flags
) {
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
;
73 UINT32 AcpiProcessorId
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
;
89 GetProcNumberInPackage (
97 for (Index
= 0; Index
< MAX_CPU_NUM
; Index
++) {
98 if (mCpuApicIdAcpiIdMapTable
[Index
].Flags
&& (((mCpuApicIdAcpiIdMapTable
[Index
].ApicId
>> 0x04) & 0x01) == Package
)) {
107 LocateCpuEistProtocol (
109 OUT ENHANCED_SPEEDSTEP_PROTOCOL
**EistProtocol
113 EFI_HANDLE
*HandleBuffer
;
114 ENHANCED_SPEEDSTEP_PROTOCOL
*EistProt
;
120 gBS
->LocateHandleBuffer (
122 &gEnhancedSpeedstepProtocolGuid
,
130 Status
= EFI_NOT_FOUND
;
131 while (Index
< HandleCount
) {
132 gBS
->HandleProtocol (
134 &gEnhancedSpeedstepProtocolGuid
,
138 // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.
140 ApicId
= ProcessorId2ApicId (CpuIndex
+1);
141 if (ApicId
== (UINT32
) -1) {
145 if (EistProt
->ProcApicId
== ApicId
) {
146 Status
= EFI_SUCCESS
;
153 if (HandleBuffer
!= NULL
) {
154 gBS
->FreePool (HandleBuffer
);
157 if (!EFI_ERROR (Status
)) {
158 *EistProtocol
= EistProt
;
160 *EistProtocol
= NULL
;
173 Status
= gBS
->LocateProtocol (
174 &gEnhancedSpeedstepProtocolGuid
,
176 (VOID
**) &mEistProtocol
179 ASSERT_EFI_ERROR (Status
);
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.
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.
196 @param[in] *Table Pointer to the active table.
198 @retval EFI_SUCCESS if the table is active.
199 @retval EFI_UNSUPPORTED if the table is not active.
203 AcpiPlatformHooksIsActiveTable (
204 IN OUT EFI_ACPI_COMMON_HEADER
*Table
207 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
209 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
211 if (TableHeader
->Signature
== EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE
) {
215 if ((mSystemConfiguration
.ENDBG2
== 0) && (CompareMem (&TableHeader
->OemTableId
, "INTLDBG2", 8) == 0)) {
216 return EFI_UNSUPPORTED
;
222 Update the GV3 SSDT table.
224 @param[in][out] *TableHeader The table to be set.
226 @retval EFI_SUCCESS Returns Success.
231 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
242 UINT32 NewPackageSize
;
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
;
253 // Loop through the ASL looking for values that we must fix up.
259 CurrPtr
= (UINT8
*) TableHeader
;
262 for (SsdtPointer
= CurrPtr
; SsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); SsdtPointer
++) {
263 Signature
= *(UINT32
*) SsdtPointer
;
266 case SIGNATURE_32 ('_', 'P', 'R', '_'):
268 // _CPUX ('0' to '0xF')
270 CpuIndex
= *(SsdtPointer
+ 7);
271 if (CpuIndex
>= '0' && CpuIndex
<= '9') {
274 if (CpuIndex
> '9') {
280 LocateCpuEistProtocol (CpuIndex
, &EistProt
);
283 case SIGNATURE_32 ('D', 'O', 'M', 'N'):
285 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
286 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
290 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
296 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
297 NamePtr
->Value
= (mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01;
301 case SIGNATURE_32 ('N', 'C', 'P', 'U'):
303 NamePtr
= ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer
);
304 if (NamePtr
->StartByte
!= AML_NAME_OP
) {
308 if (NamePtr
->Size
!= AML_NAME_DWORD_SIZE
) {
313 if (mCpuApicIdAcpiIdMapTable
[CpuIndex
].Flags
) {
314 NamePtr
->Value
= GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable
[CpuIndex
].ApicId
>> 0x04) & 0x01);
318 case SIGNATURE_32 ('N', 'P', 'S', 'S'):
319 case SIGNATURE_32 ('S', 'P', 'S', 'S'):
320 if (EistProt
== NULL
) {
324 PssTable
= ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer
);
325 if (PssTable
->StartByte
!= AML_NAME_OP
) {
329 EistProt
->GetEistTable (EistProt
, &EistInfo
, (VOID
**) &PssState
);
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));
338 // Set most significant two bits of byte zero to 01, meaning two bytes used.
340 PssTable
->Size
|= 0x40;
343 // Set unused table to Noop Code.
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
));
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
;
361 // This method should be supported by SMM PPM Handler.
363 PssTableItemPtr
->BMLatency
= PssState
[EntryIndex
].BusMasterLatency
* 2;
364 PssTableItemPtr
->TransLatency
= PssState
[EntryIndex
].TransitionLatency
* 10;
367 PssTableItemPtr
->Control
= PssState
[EntryIndex
].Control
;
368 PssTableItemPtr
->Status
= PssState
[EntryIndex
].Status
;
372 if (PssTable
->NameStr
== SIGNATURE_32 ('N', 'P', 'S', 'S')) {
378 SsdtPointer
= (UINT8
*) PssTable
+ PackageSize
;
384 // N fixes together currently.
386 ASSERT (CpuFixes
== (UINT32
) MAX_CPU_NUM
);
387 ASSERT (SpssFixes
== NpssFixes
);
388 ASSERT (CpuFixes
>= SpssFixes
);
394 Update the DSDT table.
396 @param[in][out] *TableHeader The table to be set.
398 @retval EFI_SUCCESS Returns EFI_SUCCESS.
403 IN OUT EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
416 // Fix PCI32 resource "FIX0" -- PSYS system status area
418 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
419 EndPtr
= (UINT8
*) TableHeader
;
420 EndPtr
= EndPtr
+ TableHeader
->Length
;
421 while (CurrPtr
< (EndPtr
-2)) {
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".
426 if (mSystemConfiguration
.AcpiSuspendState
== 0) {
428 // For iasl compiler version 20061109.
430 if ((CurrPtr
[0] == '_') && (CurrPtr
[1] == 'S') && (CurrPtr
[2] == '3') && (CurrPtr
[3] == '_')) {
434 // For iasl compiler version 20040527.
436 if ((CurrPtr
[0] == '\\') && (CurrPtr
[1] == '_') && (CurrPtr
[2] == 'S') && (CurrPtr
[3] == '3')) {
442 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) TableHeader
)[0];
443 EndPtr
= (UINT8
*) TableHeader
;
444 EndPtr
= EndPtr
+ TableHeader
->Length
;
445 while (CurrPtr
< (EndPtr
-2)) {
447 // For mipi dsi port select _DEP.
449 if (mSystemConfiguration
.MipiDsi
== 1) {
451 // For iasl compiler version 20061109.
453 if ((CurrPtr
[0] == 'N') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
459 if ((CurrPtr
[0] == 'P') && (CurrPtr
[1] == 'D') && (CurrPtr
[2] == 'E') && (CurrPtr
[3] == 'P')) {
468 // Loop through the ASL looking for values that we must fix up.
470 CurrPtr
= (UINT8
*) TableHeader
;
471 for (DsdtPointer
= CurrPtr
; DsdtPointer
<= (CurrPtr
+ ((EFI_ACPI_COMMON_HEADER
*) CurrPtr
)->Length
); DsdtPointer
++) {
472 Signature
= (UINT32
*) DsdtPointer
;
474 switch (*Signature
) {
476 // GNVS operation region.
478 case (SIGNATURE_32 ('G', 'N', 'V', 'S')):
480 // Conditional match. For Region Objects, the Operator will always be the
481 // byte immediately before the specific name. Therefore, subtract 1 to check
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
);