3 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
8 the terms and conditions of the BSD License that accompanies this distribution.
10 The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php.
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
37 #include <Protocol/TcgService.h>
38 #include <Protocol/FirmwareVolume.h>
39 #include "AcpiPlatform.h"
40 #include "AcpiPlatformHooks.h"
41 #include "AcpiPlatformHooksLib.h"
46 #include <Guid/GlobalVariable.h>
47 #include <Guid/SetupVariable.h>
48 #include <Guid/PlatformInfo.h>
49 #include <Protocol/CpuIo.h>
50 #include <Guid/BoardFeatures.h>
51 #include <Protocol/AcpiSupport.h>
52 #include <Protocol/AcpiS3Save.h>
53 #include <Protocol/Ps2Policy.h>
54 #include <Library/CpuIA32.h>
55 #include <SetupMode.h>
56 #include <Guid/AcpiTableStorage.h>
57 #include <Guid/EfiVpdData.h>
58 #include <PchAccess.h>
59 #include <Guid/Vlv2Variable.h>
60 #include <Guid/PlatformCpuInfo.h>
63 CHAR16 EfiPlatformCpuInfoVariable
[] = L
"PlatformCpuInfo";
64 CHAR16 gACPIOSFRModelStringVariableName
[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME
;
65 CHAR16 gACPIOSFRRefDataBlockVariableName
[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME
;
66 CHAR16 gACPIOSFRMfgStringVariableName
[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME
;
68 EFI_CPU_IO_PROTOCOL
*mCpuIo
;
70 #pragma optimize("", off)
73 EFI_PLATFORM_INFO_HOB
*mPlatformInfo
;
74 EFI_GUID mSystemConfigurationGuid
= SYSTEM_CONFIGURATION_GUID
;
75 SYSTEM_CONFIGURATION mSystemConfiguration
;
76 SYSTEM_CONFIGURATION mSystemConfig
;
78 UINT8 mSmbusRsvdAddresses
[] = PLATFORM_SMBUS_RSVD_ADDRESSES
;
79 UINT8 mNumberSmbusAddress
= sizeof( mSmbusRsvdAddresses
) / sizeof( mSmbusRsvdAddresses
[0] );
82 Locate the first instance of a protocol. If the protocol requested is an
83 FV protocol, then it will return the first FV that contains the ACPI table
86 @param[in] Protocol The protocol to find.
87 @param[in] Instance Return pointer to the first instance of the protocol.
88 @param[in] Type The type of protocol to locate.
90 @retval EFI_SUCCESS The function completed successfully.
91 @retval EFI_NOT_FOUND The protocol could not be located.
92 @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
96 LocateSupportProtocol (
97 IN EFI_GUID
*Protocol
,
103 EFI_HANDLE
*HandleBuffer
;
104 UINTN NumberOfHandles
;
105 EFI_FV_FILETYPE FileType
;
107 EFI_FV_FILE_ATTRIBUTES Attributes
;
116 Status
= gBS
->LocateHandleBuffer (
123 if (EFI_ERROR (Status
)) {
125 // Defined errors at this time are not found and out of resources.
131 // Looking for FV with ACPI storage file.
133 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
135 // Get the protocol on this handle.
136 // This should not fail because of LocateHandleBuffer.
138 Status
= gBS
->HandleProtocol (
143 ASSERT (!EFI_ERROR (Status
));
147 // Not looking for the FV protocol, so find the first instance of the
148 // protocol. There should not be any errors because our handle buffer
149 // should always contain at least one or LocateHandleBuffer would have
150 // returned not found.
156 // See if it has the ACPI storage file.
158 Status
= ((EFI_FIRMWARE_VOLUME_PROTOCOL
*) (*Instance
))->ReadFile (
160 &gEfiAcpiTableStorageGuid
,
169 // If we found it, then we are done.
171 if (!EFI_ERROR (Status
)) {
177 // Our exit status is determined by the success of the previous operations.
178 // If the protocol was found, Instance already points to it.
181 // Free any allocated buffers.
183 gBS
->FreePool (HandleBuffer
);
189 This function will update any runtime platform specific information.
190 This currently includes:
191 Setting OEM table values, ID, table ID, creator ID and creator revision.
192 Enabling the proper processor entries in the APIC tables.
194 @param[in] Table The table to update.
196 @retval EFI_SUCCESS The function completed successfully.
200 PlatformUpdateTables (
201 IN OUT EFI_ACPI_COMMON_HEADER
*Table
204 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
207 ACPI_APIC_STRUCTURE_PTR
*ApicPtr
;
210 EFI_MP_SERVICES_PROTOCOL
*MpService
;
211 UINTN MaximumNumberOfCPUs
;
212 UINTN NumberOfEnabledCPUs
;
214 ACPI_APIC_STRUCTURE_PTR
*ProcessorLocalApicEntry
;
216 EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*AsfEntry
;
217 EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*HpetTbl
;
220 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*Facp
;
221 EFI_ACPI_OSFR_TABLE
*OsfrTable
;
222 EFI_ACPI_OSFR_OCUR_OBJECT
*pOcurObject
;
223 EFI_ACPI_OSFR_OCUR_OBJECT OcurObject
= {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
224 CHAR16
*OcurMfgStringBuffer
= NULL
;
225 CHAR16
*OcurModelStringBuffer
= NULL
;
226 UINT8
*OcurRefDataBlockBuffer
= NULL
;
227 UINTN OcurMfgStringBufferSize
;
228 UINTN OcurModelStringBufferSize
;
229 UINTN OcurRefDataBlockBufferSize
;
230 #if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
231 EFI_ACPI_ASPT_TABLE
*pSpttTable
;
233 UINT16 NumberOfHpets
;
234 UINT16 HpetCapIdValue
;
236 UINTN LocalApicCounter
;
237 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
239 EFI_ACPI_3_0_IO_APIC_STRUCTURE
*IOApicType
;
240 EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*APICTableHeader
;
245 LocalApicCounter
= 0;
247 ProcessorLocalApicEntry
= NULL
;
250 if (Table
->Signature
!= EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
251 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
255 OemIdValue
= mPlatformInfo
->AcpiOemId
;
257 *(UINT32
*)(TableHeader
->OemId
) = (UINT32
)OemIdValue
;
258 *(UINT16
*)(TableHeader
->OemId
+ 4) = *(UINT16
*)(((UINT8
*)&OemIdValue
) + 4);
260 if ((Table
->Signature
!= EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)) {
262 // Update the OEM Table ID.
264 TableHeader
->OemTableId
= mPlatformInfo
->AcpiOemTableId
;
268 // Update the OEM Table ID.
270 TableHeader
->OemRevision
= EFI_ACPI_OEM_REVISION
;
273 // Update the creator ID.
275 TableHeader
->CreatorId
= EFI_ACPI_CREATOR_ID
;
278 // Update the creator revision.
280 TableHeader
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
284 // Complete this function.
287 // Locate the MP services protocol.
290 // Find the MP Protocol. This is an MP platform, so MP protocol must be
293 Status
= gBS
->LocateProtocol (
294 &gEfiMpServiceProtocolGuid
,
298 if (EFI_ERROR (Status
)) {
303 // Determine the number of processors.
305 MpService
->GetNumberOfProcessors (
307 &MaximumNumberOfCPUs
,
311 ASSERT (MaximumNumberOfCPUs
<= MAX_CPU_NUM
&& NumberOfEnabledCPUs
>= 1);
315 // Assign a invalid intial value for update.
318 // Update the processors in the APIC table.
320 switch (Table
->Signature
) {
321 case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE
:
323 // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
325 if (mSystemConfig
.Asf
== 1) {
326 return EFI_UNSUPPORTED
;
328 AsfEntry
= (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*) Table
;
329 TempVal
= (mNumberSmbusAddress
< ASF_ADDR_DEVICE_ARRAY_LENGTH
)? mNumberSmbusAddress
: ASF_ADDR_DEVICE_ARRAY_LENGTH
;
330 for (Index
= 0; Index
< TempVal
; Index
++) {
331 AsfEntry
->AsfAddr
.FixedSmbusAddresses
[Index
] = mSmbusRsvdAddresses
[Index
];
335 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
:
337 Status
= MpService
->WhoAmI (
343 // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
345 APICTableHeader
= (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*)Table
;
346 APICTableHeader
->Flags
|= EFI_ACPI_3_0_PCAT_COMPAT
;
348 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) Table
)[1];
349 CurrPtr
= CurrPtr
+ 8;
352 // Size of Local APIC Address & Flag.
354 EndPtr
= (UINT8
*) Table
;
355 EndPtr
= EndPtr
+ Table
->Length
;
356 while (CurrPtr
< EndPtr
) {
357 ApicPtr
= (ACPI_APIC_STRUCTURE_PTR
*) CurrPtr
;
358 switch (ApicPtr
->AcpiApicCommon
.Type
) {
359 case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC
:
362 // Fix for Ordering of MADT to be maintained as it is in MADT table.
364 // Update processor enabled or disabled and keep the local APIC
365 // order in MADT intact.
367 // Sanity check to make sure proc-id is not arbitrary.
369 DEBUG ((EFI_D_ERROR
, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
370 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
, MaximumNumberOfCPUs
));
371 if(ApicPtr
->AcpiLocalApic
.AcpiProcessorId
> MaximumNumberOfCPUs
) {
372 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
= (UINT8
)MaximumNumberOfCPUs
;
376 ApicPtr
->AcpiLocalApic
.Flags
= 0;
378 for (CurrProcessor
= 0; CurrProcessor
< MaximumNumberOfCPUs
; CurrProcessor
++) {
379 Status
= MpService
->GetProcessorInfo (
385 if (Status
== EFI_SUCCESS
&& ProcessorInfoBuffer
.ProcessorId
== ApicPtr
->AcpiLocalApic
.ApicId
) {
387 // Check to see whether or not a processor (or thread) is enabled.
389 if ((BspIndex
== CurrProcessor
) || ((ProcessorInfoBuffer
.StatusFlag
& PROCESSOR_ENABLED_BIT
) != 0)) {
391 // Go on and check if Hyper Threading is enabled. If HT not enabled
392 // hide this thread from OS by not setting the flag to 1. This is the
393 // software way to disable Hyper Threading. Basically we just hide it
396 ApicPtr
->AcpiLocalApic
.Flags
= EFI_ACPI_1_0_LOCAL_APIC_ENABLED
;
399 if(ProcessorInfoBuffer
.Location
.Thread
!= 0) {
400 ApicPtr
->AcpiLocalApic
.Flags
= 0;
403 AppendCpuMapTableEntry (&(ApicPtr
->AcpiLocalApic
));
410 // If no APIC-ID match, the cpu may not be populated.
414 case EFI_ACPI_3_0_IO_APIC
:
416 IOApicType
= (EFI_ACPI_3_0_IO_APIC_STRUCTURE
*)CurrPtr
;
417 IOApicType
->IoApicId
= 0x02;
419 // IO APIC entries can be patched here.
424 CurrPtr
= CurrPtr
+ ApicPtr
->AcpiApicCommon
.Length
;
428 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
430 Facp
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) Table
;
431 Facp
->Flags
&= (UINT32
)(~(3<<2));
435 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
437 // Patch the memory resource.
439 PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER
*) Table
);
442 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
446 // TBD: Need re-design based on the ValleyTrail platform.
450 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE
:
452 // Adjust HPET Table to correct the Base Address.
454 // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
456 MmioOr8 (R_PCH_PCH_HPET
+ R_PCH_PCH_HPET_GCFG
, B_PCH_PCH_HPET_GCFG_EN
);
459 HpetTbl
= (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*) Table
;
460 HpetTbl
->BaseAddressLower32Bit
.Address
= HPET_BASE_ADDRESS
;
461 HpetTbl
->EventTimerBlockId
= *((UINT32
*)(UINTN
)HPET_BASE_ADDRESS
);
463 HpetCapIdValue
= *(UINT16
*)(UINTN
)(HPET_BASE_ADDRESS
);
464 NumberOfHpets
= HpetCapIdValue
& B_PCH_PCH_HPET_GCID_NT
; // Bits [8:12] contains the number of Hpets
465 HpetBlockID
= EFI_ACPI_EVENT_TIMER_BLOCK_ID
;
467 if((NumberOfHpets
) && (NumberOfHpets
& B_PCH_PCH_HPET_GCID_NT
)) {
468 HpetBlockID
|= (NumberOfHpets
);
470 HpetTbl
->EventTimerBlockId
= HpetBlockID
;
474 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
:
476 // Update MCFG base and end bus number.
478 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].BaseAddress
479 = mPlatformInfo
->PciData
.PciExpressBase
;
480 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].EndBusNumber
481 = (UINT8
)RShiftU64 (mPlatformInfo
->PciData
.PciExpressSize
, 20) - 1;
485 case EFI_ACPI_OSFR_TABLE_SIGNATURE
:
487 // Get size of OSFR variable.
489 OcurMfgStringBufferSize
= 0;
490 Status
= gRT
->GetVariable (
491 gACPIOSFRMfgStringVariableName
,
492 &gACPIOSFRMfgStringVariableGuid
,
494 &OcurMfgStringBufferSize
,
497 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
499 // Variable must not be present on the system.
501 return EFI_UNSUPPORTED
;
505 // Allocate memory for variable data.
507 OcurMfgStringBuffer
= AllocatePool (OcurMfgStringBufferSize
);
508 Status
= gRT
->GetVariable (
509 gACPIOSFRMfgStringVariableName
,
510 &gACPIOSFRMfgStringVariableGuid
,
512 &OcurMfgStringBufferSize
,
515 if (!EFI_ERROR (Status
)) {
516 OcurModelStringBufferSize
= 0;
517 Status
= gRT
->GetVariable (
518 gACPIOSFRModelStringVariableName
,
519 &gACPIOSFRModelStringVariableGuid
,
521 &OcurModelStringBufferSize
,
524 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
526 // Variable must not be present on the system.
528 return EFI_UNSUPPORTED
;
532 // Allocate memory for variable data.
534 OcurModelStringBuffer
= AllocatePool (OcurModelStringBufferSize
);
535 Status
= gRT
->GetVariable (
536 gACPIOSFRModelStringVariableName
,
537 &gACPIOSFRModelStringVariableGuid
,
539 &OcurModelStringBufferSize
,
540 OcurModelStringBuffer
542 if (!EFI_ERROR (Status
)) {
543 OcurRefDataBlockBufferSize
= 0;
544 Status
= gRT
->GetVariable (
545 gACPIOSFRRefDataBlockVariableName
,
546 &gACPIOSFRRefDataBlockVariableGuid
,
548 &OcurRefDataBlockBufferSize
,
551 if (Status
== EFI_BUFFER_TOO_SMALL
) {
553 // Allocate memory for variable data.
555 OcurRefDataBlockBuffer
= AllocatePool (OcurRefDataBlockBufferSize
);
556 Status
= gRT
->GetVariable (
557 gACPIOSFRRefDataBlockVariableName
,
558 &gACPIOSFRRefDataBlockVariableGuid
,
560 &OcurRefDataBlockBufferSize
,
561 OcurRefDataBlockBuffer
564 OsfrTable
= (EFI_ACPI_OSFR_TABLE
*) Table
;
566 // Currently only one object is defined: OCUR_OSFR_TABLE.
568 OsfrTable
->ObjectCount
= 1;
570 // Initialize table length to fixed portion of the ACPI OSFR table.
572 OsfrTable
->Header
.Length
= sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
);
573 *(UINT32
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
)) = \
574 (UINT32
) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + sizeof (UINT32
));
575 pOcurObject
= (EFI_ACPI_OSFR_OCUR_OBJECT
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + \
577 CopyMem (pOcurObject
, &OcurObject
, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
578 pOcurObject
->ManufacturerNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
579 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
580 pOcurObject
->ModelNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
581 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
);
582 if (OcurRefDataBlockBufferSize
> 0) {
583 pOcurObject
->MicrosoftReferenceOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
584 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ OcurModelStringBufferSize
);
586 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
)), OcurMfgStringBuffer
, \
587 OcurMfgStringBufferSize
);
588 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
), \
589 OcurModelStringBuffer
, OcurModelStringBufferSize
);
590 if (OcurRefDataBlockBufferSize
> 0) {
591 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ \
592 OcurModelStringBufferSize
),OcurRefDataBlockBuffer
, OcurRefDataBlockBufferSize
);
594 OsfrTable
->Header
.Length
+= (UINT32
)(OcurMfgStringBufferSize
+ OcurModelStringBufferSize
+ OcurRefDataBlockBufferSize
);
595 OsfrTable
->Header
.Length
+= sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + sizeof (UINT32
);
598 gBS
->FreePool (OcurMfgStringBuffer
);
599 gBS
->FreePool (OcurModelStringBuffer
);
600 gBS
->FreePool (OcurRefDataBlockBuffer
);
608 // Update the hardware signature in the FACS structure.
611 // Locate the SPCR table and update based on current settings.
612 // The user may change CR settings via setup or other methods.
613 // The SPCR table must match.
622 GC_TODO: Add function description.
626 Event - GC_TODO: add argument description
627 Context - GC_TODO: add argument description
631 GC_TODO: add return values
643 EFI_ACPI_TABLE_VERSION TableVersion
;
644 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
645 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
646 SYSTEM_CONFIGURATION SetupVarBuffer
;
648 EFI_PLATFORM_CPU_INFO
*PlatformCpuInfoPtr
= NULL
;
649 EFI_PLATFORM_CPU_INFO PlatformCpuInfo
;
650 EFI_PEI_HOB_POINTERS GuidHob
;
659 // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
661 PlatformCpuInfo
.CpuVersion
.FullCpuId
= 0;
664 // Get Platform CPU Info HOB.
666 PlatformCpuInfoPtr
= NULL
;
667 ZeroMem (&PlatformCpuInfo
, sizeof(EFI_PLATFORM_CPU_INFO
));
668 VariableSize
= sizeof(EFI_PLATFORM_CPU_INFO
);
669 Status
= gRT
->GetVariable(
670 EfiPlatformCpuInfoVariable
,
671 &gEfiVlv2VariableGuid
,
676 if (EFI_ERROR(Status
)) {
677 GuidHob
.Raw
= GetHobList ();
678 if (GuidHob
.Raw
!= NULL
) {
679 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformCpuInfoGuid
, GuidHob
.Raw
)) != NULL
) {
680 PlatformCpuInfoPtr
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
685 if ((PlatformCpuInfoPtr
!= NULL
)) {
686 CopyMem(&PlatformCpuInfo
, PlatformCpuInfoPtr
, sizeof(EFI_PLATFORM_CPU_INFO
));
690 // Update the ACPI parameter blocks finally.
692 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
693 Status
= gRT
->GetVariable (
695 &mSystemConfigurationGuid
,
700 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
701 //The setup variable is corrupted
702 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
703 Status
= gRT
->GetVariable(
705 &mSystemConfigurationGuid
,
710 ASSERT_EFI_ERROR (Status
);
714 // Find the AcpiSupport protocol.
716 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
717 ASSERT_EFI_ERROR (Status
);
719 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
722 // Publish ACPI 1.0 or 2.0 Tables.
724 Status
= AcpiSupport
->PublishTables (
728 ASSERT_EFI_ERROR (Status
);
733 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, (VOID
**) &AcpiS3Save
);
734 if (!EFI_ERROR (Status
)) {
735 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
748 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
&& mPlatformInfo
->BoardRev
>= PR1
) {
749 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD PR1\n"));
750 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
752 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
753 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD8\n"));
754 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
760 Entry point for Acpi platform driver.
762 @param[in] ImageHandle A handle for the image that is initializing this driver.
763 @param[in] SystemTable A pointer to the EFI system table.
765 @retval EFI_SUCCESS Driver initialized successfully.
766 @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded.
767 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
772 AcpiPlatformEntryPoint (
773 IN EFI_HANDLE ImageHandle
,
774 IN EFI_SYSTEM_TABLE
*SystemTable
778 EFI_STATUS AcpiStatus
;
779 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
780 EFI_FIRMWARE_VOLUME_PROTOCOL
*FwVol
;
782 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
787 EFI_ACPI_TABLE_VERSION TableVersion
;
791 EFI_PS2_POLICY_PROTOCOL
*Ps2Policy
;
792 EFI_PEI_HOB_POINTERS GuidHob
;
794 EFI_MP_SERVICES_PROTOCOL
*MpService
;
795 UINTN MaximumNumberOfCPUs
;
796 UINTN NumberOfEnabledCPUs
;
798 PCH_STEPPING pchStepping
;
800 mFirstNotify
= FALSE
;
802 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
809 // Update HOB variable for PCI resource information.
810 // Get the HOB list. If it is not present, then ASSERT.
812 GuidHob
.Raw
= GetHobList ();
813 if (GuidHob
.Raw
!= NULL
) {
814 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformInfoGuid
, GuidHob
.Raw
)) != NULL
) {
815 mPlatformInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
820 // Search for the Memory Configuration GUID HOB. If it is not present, then
821 // there's nothing we can do. It may not exist on the update path.
823 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
824 Status
= gRT
->GetVariable(
826 &mSystemConfigurationGuid
,
829 &mSystemConfiguration
831 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
832 //The setup variable is corrupted
833 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
834 Status
= gRT
->GetVariable(
836 &mSystemConfigurationGuid
,
839 &mSystemConfiguration
841 ASSERT_EFI_ERROR (Status
);
845 // Find the AcpiSupport protocol.
847 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
848 ASSERT_EFI_ERROR (Status
);
851 // Locate the firmware volume protocol.
853 Status
= LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid
, (VOID
**) &FwVol
, 1);
854 ASSERT_EFI_ERROR (Status
);
857 // Read the current system configuration variable store.
859 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
860 Status
= gRT
->GetVariable (
862 &gEfiNormalSetupGuid
,
867 if (EFI_ERROR (Status
) || SysCfgSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
868 //The setup variable is corrupted
869 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
870 Status
= gRT
->GetVariable(
872 &gEfiNormalSetupGuid
,
877 ASSERT_EFI_ERROR (Status
);
881 Status
= EFI_SUCCESS
;
885 // TBD: Need re-design based on the ValleyTrail platform.
887 Status
= gBS
->LocateProtocol (
888 &gEfiMpServiceProtocolGuid
,
892 if (EFI_ERROR (Status
)) {
897 // Determine the number of processors.
899 MpService
->GetNumberOfProcessors (
901 &MaximumNumberOfCPUs
,
906 // Allocate and initialize the NVS area for SMM and ASL communication.
908 Status
= gBS
->AllocatePool (
910 sizeof (EFI_GLOBAL_NVS_AREA
),
911 (void **)&mGlobalNvsArea
.Area
913 ASSERT_EFI_ERROR (Status
);
916 sizeof (EFI_GLOBAL_NVS_AREA
),
919 DEBUG((EFI_D_ERROR
, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea
.Area
));
922 // Update global NVS area for ASL and SMM init code to use.
924 mGlobalNvsArea
.Area
->ApicEnable
= 1;
925 mGlobalNvsArea
.Area
->EmaEnable
= 0;
927 mGlobalNvsArea
.Area
->NumberOfBatteries
= 1;
928 mGlobalNvsArea
.Area
->BatteryCapacity0
= 100;
929 mGlobalNvsArea
.Area
->BatteryStatus0
= 84;
930 mGlobalNvsArea
.Area
->OnboardCom
= 1;
931 mGlobalNvsArea
.Area
->IdeMode
= 0;
932 mGlobalNvsArea
.Area
->PowerState
= 0;
934 mGlobalNvsArea
.Area
->LogicalProcessorCount
= (UINT8
)NumberOfEnabledCPUs
;
936 mGlobalNvsArea
.Area
->PassiveThermalTripPoint
= mSystemConfiguration
.PassiveThermalTripPoint
;
937 mGlobalNvsArea
.Area
->PassiveTc1Value
= mSystemConfiguration
.PassiveTc1Value
;
938 mGlobalNvsArea
.Area
->PassiveTc2Value
= mSystemConfiguration
.PassiveTc2Value
;
939 mGlobalNvsArea
.Area
->PassiveTspValue
= mSystemConfiguration
.PassiveTspValue
;
940 mGlobalNvsArea
.Area
->CriticalThermalTripPoint
= mSystemConfiguration
.CriticalThermalTripPoint
;
942 mGlobalNvsArea
.Area
->IgdPanelType
= mSystemConfiguration
.IgdFlatPanel
;
943 mGlobalNvsArea
.Area
->IgdPanelScaling
= mSystemConfiguration
.PanelScaling
;
944 mGlobalNvsArea
.Area
->IgdSciSmiMode
= 0;
945 mGlobalNvsArea
.Area
->IgdTvFormat
= 0;
946 mGlobalNvsArea
.Area
->IgdTvMinor
= 0;
947 mGlobalNvsArea
.Area
->IgdSscConfig
= 1;
948 mGlobalNvsArea
.Area
->IgdBiaConfig
= mSystemConfiguration
.IgdLcdIBia
;
949 mGlobalNvsArea
.Area
->IgdBlcConfig
= mSystemConfiguration
.IgdLcdIGmchBlc
;
950 mGlobalNvsArea
.Area
->IgdDvmtMemSize
= mSystemConfiguration
.IgdDvmt50TotalAlloc
;
951 mGlobalNvsArea
.Area
->IgdPAVP
= mSystemConfiguration
.PavpMode
;
953 mGlobalNvsArea
.Area
->AlsEnable
= mSystemConfiguration
.AlsEnable
;
954 mGlobalNvsArea
.Area
->BacklightControlSupport
= 2;
955 mGlobalNvsArea
.Area
->BrightnessPercentage
= 100;
956 mGlobalNvsArea
.Area
->IgdState
= 1;
957 mGlobalNvsArea
.Area
->LidState
= 1;
959 mGlobalNvsArea
.Area
->DeviceId1
= 0x80000100 ;
960 mGlobalNvsArea
.Area
->DeviceId2
= 0x80000400 ;
961 mGlobalNvsArea
.Area
->DeviceId3
= 0x80000200 ;
962 mGlobalNvsArea
.Area
->DeviceId4
= 0x04;
963 mGlobalNvsArea
.Area
->DeviceId5
= 0x05;
964 mGlobalNvsArea
.Area
->NumberOfValidDeviceId
= 4 ;
965 mGlobalNvsArea
.Area
->CurrentDeviceList
= 0x0F ;
966 mGlobalNvsArea
.Area
->PreviousDeviceList
= 0x0F ;
968 mGlobalNvsArea
.Area
->UartSelection
= mSystemConfiguration
.UartInterface
;
969 mGlobalNvsArea
.Area
->PcuUart1Enable
= mSystemConfiguration
.PcuUart1
;
970 mGlobalNvsArea
.Area
->NativePCIESupport
= 1;
971 mGlobalNvsArea
.Area
->RtcBattery
= mSystemConfiguration
.RtcBattery
;
978 // Update BootMode: 0:ACPI mode; 1:PCI mode
980 mGlobalNvsArea
.Area
->LpssSccMode
= mSystemConfiguration
.LpssPciModeEnabled
;
981 if (mSystemConfiguration
.LpssMipiHsi
== 0) {
982 mGlobalNvsArea
.Area
->MipiHsiAddr
= 0;
983 mGlobalNvsArea
.Area
->MipiHsiLen
= 0;
984 mGlobalNvsArea
.Area
->MipiHsi1Addr
= 0;
985 mGlobalNvsArea
.Area
->MipiHsi1Len
= 0;
991 mGlobalNvsArea
.Area
->PlatformFlavor
= mPlatformInfo
->PlatformFlavor
;
994 // Update the Platform id
996 mGlobalNvsArea
.Area
->BoardID
= mPlatformInfo
->BoardId
;
999 // Update the Board Revision
1001 mGlobalNvsArea
.Area
->FabID
= mPlatformInfo
->BoardRev
;
1004 // Update SOC Stepping
1006 mGlobalNvsArea
.Area
->SocStepping
= (UINT8
)(PchStepping());
1008 mGlobalNvsArea
.Area
->OtgMode
= mSystemConfiguration
.PchUsbOtg
;
1010 pchStepping
= PchStepping();
1011 if (mSystemConfiguration
.UsbAutoMode
== 1) {
1013 // Auto mode is enabled.
1015 if (PchA0
== pchStepping
) {
1017 // For A0, EHCI is enabled as default.
1019 mSystemConfiguration
.PchUsb20
= 1;
1020 mSystemConfiguration
.PchUsb30Mode
= 0;
1021 mSystemConfiguration
.UsbXhciSupport
= 0;
1022 DEBUG ((EFI_D_INFO
, "EHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1025 // For A1 and later, XHCI is enabled as default.
1027 mSystemConfiguration
.PchUsb20
= 0;
1028 mSystemConfiguration
.PchUsb30Mode
= 1;
1029 mSystemConfiguration
.UsbXhciSupport
= 1;
1030 DEBUG ((EFI_D_INFO
, "XHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1034 mGlobalNvsArea
.Area
->XhciMode
= mSystemConfiguration
.PchUsb30Mode
;
1036 mGlobalNvsArea
.Area
->Stepping
= mPlatformInfo
->IchRevision
;
1039 // Override invalid Pre-Boot Driver and XhciMode combination.
1041 if ((mSystemConfiguration
.UsbXhciSupport
== 0) && (mSystemConfiguration
.PchUsb30Mode
== 3)) {
1042 mGlobalNvsArea
.Area
->XhciMode
= 2;
1044 if ((mSystemConfiguration
.UsbXhciSupport
== 1) && (mSystemConfiguration
.PchUsb30Mode
== 2)) {
1045 mGlobalNvsArea
.Area
->XhciMode
= 3;
1048 DEBUG ((EFI_D_ERROR
, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea
.Area
->XhciMode
));
1050 mGlobalNvsArea
.Area
->PmicEnable
= GLOBAL_NVS_DEVICE_DISABLE
;
1051 mGlobalNvsArea
.Area
->BatteryChargingSolution
= GLOBAL_NVS_DEVICE_DISABLE
;
1052 mGlobalNvsArea
.Area
->ISPDevSel
= mSystemConfiguration
.ISPDevSel
;
1053 mGlobalNvsArea
.Area
->LpeEnable
= mSystemConfiguration
.Lpe
;
1054 mGlobalNvsArea
.Area
->LpeAudioReportedByDSDT
= mSystemConfiguration
.LpeAudioReportedByDSDT
;
1056 if (mSystemConfiguration
.ISPEn
== 0) {
1057 mGlobalNvsArea
.Area
->ISPDevSel
= GLOBAL_NVS_DEVICE_DISABLE
;
1060 mGlobalNvsArea
.Area
->WittEnable
= mSystemConfiguration
.WittEnable
;
1061 mGlobalNvsArea
.Area
->UtsEnable
= mSystemConfiguration
.UtsEnable
;
1062 mGlobalNvsArea
.Area
->SarEnable
= mSystemConfiguration
.SAR1
;
1065 mGlobalNvsArea
.Area
->ReservedO
= 1;
1067 SettingI2CTouchAddress();
1068 mGlobalNvsArea
.Area
->IdleReserve
= mSystemConfiguration
.IdleReserve
;
1070 // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1072 // BUGBUG: code was moved into silicon reference code.
1074 if (mSystemConfiguration
.eMMCBootMode
== 1) {
1076 // Auto detect mode.
1078 DEBUG ((EFI_D_ERROR
, "Auto detect mode------------start\n"));
1081 // Silicon Steppings.
1083 switch (PchStepping()) {
1084 case PchA0
: // A0/A1
1086 DEBUG ((EFI_D_ERROR
, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1087 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1088 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1091 case PchB0
: // B0 and later.
1093 DEBUG ((EFI_D_ERROR
, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1094 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1095 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1098 } else if (mSystemConfiguration
.eMMCBootMode
== 2) {
1102 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.41 Configuration\n"));
1103 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1104 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1105 } else if (mSystemConfiguration
.eMMCBootMode
== 3) {
1109 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.5 Configuration\n"));
1110 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1111 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1115 // Disable eMMC controllers.
1117 DEBUG ((EFI_D_ERROR
, "Disable eMMC controllers\n"));
1118 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1119 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1122 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1123 if (mSystemConfiguration
.LpsseMMCEnabled
) {
1124 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1125 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1128 if (mSystemConfiguration
.LpsseMMC45Enabled
) {
1129 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1130 mGlobalNvsArea
.Area
->emmcVersion
= 1;
1133 mGlobalNvsArea
.Area
->SdCardRemovable
= mSystemConfiguration
.SdCardRemovable
;
1138 if ((mSystemConfiguration
.LpssHsuart0FlowControlEnabled
== 1) && \
1139 (mSystemConfiguration
.LpssPwm0Enabled
== 0) && \
1140 (mSystemConfiguration
.LpssPwm1Enabled
== 0)) {
1141 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_ENABLE
;
1142 DEBUG ((EFI_D_ERROR
, "JP1 is set to be MSFT IOT configuration.\n"));
1144 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_DISABLE
;
1145 DEBUG ((EFI_D_ERROR
, "JP1 is not set to be MSFT IOT configuration.\n"));
1149 // SIO related option.
1151 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (void **)&mCpuIo
);
1152 ASSERT_EFI_ERROR (Status
);
1154 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_DISABLE
;
1156 mGlobalNvsArea
.Area
->DockedSioPresent
= GLOBAL_NVS_DEVICE_DISABLE
;
1158 if (mGlobalNvsArea
.Area
->DockedSioPresent
!= GLOBAL_NVS_DEVICE_ENABLE
) {
1160 // Check ID for SIO WPCN381U.
1162 Status
= mCpuIo
->Io
.Read (
1165 WPCN381U_CONFIG_INDEX
,
1169 ASSERT_EFI_ERROR (Status
);
1170 if (PortData
!= 0xFF) {
1172 Status
= mCpuIo
->Io
.Write (
1175 WPCN381U_CONFIG_INDEX
,
1179 ASSERT_EFI_ERROR (Status
);
1180 Status
= mCpuIo
->Io
.Read (
1183 WPCN381U_CONFIG_DATA
,
1187 ASSERT_EFI_ERROR (Status
);
1188 if ((PortData
== WPCN381U_CHIP_ID
) || (PortData
== WDCP376_CHIP_ID
)) {
1189 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_ENABLE
;
1190 mGlobalNvsArea
.Area
->OnboardCom
= GLOBAL_NVS_DEVICE_ENABLE
;
1191 mGlobalNvsArea
.Area
->OnboardComCir
= GLOBAL_NVS_DEVICE_DISABLE
;
1199 // Get Ps2 policy to set. Will be use if present.
1201 Status
= gBS
->LocateProtocol (
1202 &gEfiPs2PolicyProtocolGuid
,
1206 if (!EFI_ERROR (Status
)) {
1207 Status
= Ps2Policy
->Ps2InitHardware (ImageHandle
);
1210 mGlobalNvsArea
.Area
->SDIOMode
= mSystemConfiguration
.LpssSdioMode
;
1213 Status
= gBS
->InstallMultipleProtocolInterfaces (
1215 &gEfiGlobalNvsAreaProtocolGuid
,
1221 // Read tables from the storage file.
1223 while (!EFI_ERROR (Status
)) {
1224 CurrentTable
= NULL
;
1226 Status
= FwVol
->ReadSection (
1228 &gEfiAcpiTableStorageGuid
,
1231 (VOID
**) &CurrentTable
,
1236 if (!EFI_ERROR (Status
)) {
1238 // Allow platform specific code to reject the table or update it.
1240 AcpiStatus
= AcpiPlatformHooksIsActiveTable (CurrentTable
);
1242 if (!EFI_ERROR (AcpiStatus
)) {
1244 // Perform any table specific updates.
1246 AcpiStatus
= PlatformUpdateTables (CurrentTable
);
1247 if (!EFI_ERROR (AcpiStatus
)) {
1252 AcpiStatus
= AcpiSupport
->SetAcpiTable (
1259 ASSERT_EFI_ERROR (AcpiStatus
);
1264 // Increment the instance.
1270 Status
= EfiCreateEventReadyToBootEx (
1290 IoWrite8(0x72, Index
);
1291 Data
= IoRead8 (0x73);
1296 WriteCmosBank1Byte (
1301 IoWrite8 (0x72, Index
);
1302 IoWrite8 (0x73, Data
);
1308 SettingI2CTouchAddress (
1312 if (mSystemConfiguration
.I2CTouchAd
== 0) {
1314 // If setup menu select auto set I2C Touch Address base on board id.
1316 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP
||
1317 mPlatformInfo
->BoardId
== BOARD_ID_BL_STHI
||
1318 mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP_DDR3L
) {
1322 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4B;
1323 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
) {
1327 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1328 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BB_RVP
) {
1329 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1330 } else if (mPlatformInfo
->BoardId
== BOARD_ID_CVH
) {
1331 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1332 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
1336 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1339 mGlobalNvsArea
.Area
->I2CTouchAddress
= mSystemConfiguration
.I2CTouchAd
;
1341 DEBUG((EFI_D_ERROR
, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea
.Area
->I2CTouchAddress
));