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>
61 #include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
64 CHAR16 EfiPlatformCpuInfoVariable
[] = L
"PlatformCpuInfo";
65 CHAR16 gACPIOSFRModelStringVariableName
[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME
;
66 CHAR16 gACPIOSFRRefDataBlockVariableName
[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME
;
67 CHAR16 gACPIOSFRMfgStringVariableName
[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME
;
69 EFI_CPU_IO_PROTOCOL
*mCpuIo
;
70 EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea
;
72 #pragma optimize("", off)
75 EFI_PLATFORM_INFO_HOB
*mPlatformInfo
;
76 EFI_GUID mSystemConfigurationGuid
= SYSTEM_CONFIGURATION_GUID
;
77 SYSTEM_CONFIGURATION mSystemConfiguration
;
78 SYSTEM_CONFIGURATION mSystemConfig
;
80 UINT8 mSmbusRsvdAddresses
[] = PLATFORM_SMBUS_RSVD_ADDRESSES
;
81 UINT8 mNumberSmbusAddress
= sizeof( mSmbusRsvdAddresses
) / sizeof( mSmbusRsvdAddresses
[0] );
84 Locate the first instance of a protocol. If the protocol requested is an
85 FV protocol, then it will return the first FV that contains the ACPI table
88 @param[in] Protocol The protocol to find.
89 @param[in] Instance Return pointer to the first instance of the protocol.
90 @param[in] Type The type of protocol to locate.
92 @retval EFI_SUCCESS The function completed successfully.
93 @retval EFI_NOT_FOUND The protocol could not be located.
94 @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
98 LocateSupportProtocol (
99 IN EFI_GUID
*Protocol
,
105 EFI_HANDLE
*HandleBuffer
;
106 UINTN NumberOfHandles
;
107 EFI_FV_FILETYPE FileType
;
109 EFI_FV_FILE_ATTRIBUTES Attributes
;
118 Status
= gBS
->LocateHandleBuffer (
125 if (EFI_ERROR (Status
)) {
127 // Defined errors at this time are not found and out of resources.
133 // Looking for FV with ACPI storage file.
135 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
137 // Get the protocol on this handle.
138 // This should not fail because of LocateHandleBuffer.
140 Status
= gBS
->HandleProtocol (
145 ASSERT (!EFI_ERROR (Status
));
149 // Not looking for the FV protocol, so find the first instance of the
150 // protocol. There should not be any errors because our handle buffer
151 // should always contain at least one or LocateHandleBuffer would have
152 // returned not found.
158 // See if it has the ACPI storage file.
160 Status
= ((EFI_FIRMWARE_VOLUME_PROTOCOL
*) (*Instance
))->ReadFile (
162 &gEfiAcpiTableStorageGuid
,
171 // If we found it, then we are done.
173 if (!EFI_ERROR (Status
)) {
179 // Our exit status is determined by the success of the previous operations.
180 // If the protocol was found, Instance already points to it.
183 // Free any allocated buffers.
185 gBS
->FreePool (HandleBuffer
);
191 This function will update any runtime platform specific information.
192 This currently includes:
193 Setting OEM table values, ID, table ID, creator ID and creator revision.
194 Enabling the proper processor entries in the APIC tables.
196 @param[in] Table The table to update.
198 @retval EFI_SUCCESS The function completed successfully.
202 PlatformUpdateTables (
203 IN OUT EFI_ACPI_COMMON_HEADER
*Table
206 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
209 ACPI_APIC_STRUCTURE_PTR
*ApicPtr
;
212 EFI_MP_SERVICES_PROTOCOL
*MpService
;
213 UINTN MaximumNumberOfCPUs
;
214 UINTN NumberOfEnabledCPUs
;
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 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
238 EFI_ACPI_3_0_IO_APIC_STRUCTURE
*IOApicType
;
239 EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*APICTableHeader
;
240 EFI_ACPI_WSMT_TABLE
*WsmtTable
;
248 if (Table
->Signature
!= EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
249 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
253 OemIdValue
= mPlatformInfo
->AcpiOemId
;
255 *(UINT32
*)(TableHeader
->OemId
) = (UINT32
)OemIdValue
;
256 *(UINT16
*)(TableHeader
->OemId
+ 4) = *(UINT16
*)(((UINT8
*)&OemIdValue
) + 4);
258 if ((Table
->Signature
!= EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)) {
260 // Update the OEM Table ID.
262 TableHeader
->OemTableId
= mPlatformInfo
->AcpiOemTableId
;
266 // Update the OEM Table ID.
268 TableHeader
->OemRevision
= EFI_ACPI_OEM_REVISION
;
271 // Update the creator ID.
273 TableHeader
->CreatorId
= EFI_ACPI_CREATOR_ID
;
276 // Update the creator revision.
278 TableHeader
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
282 // Complete this function.
285 // Locate the MP services protocol.
288 // Find the MP Protocol. This is an MP platform, so MP protocol must be
291 Status
= gBS
->LocateProtocol (
292 &gEfiMpServiceProtocolGuid
,
296 if (EFI_ERROR (Status
)) {
301 // Determine the number of processors.
303 MpService
->GetNumberOfProcessors (
305 &MaximumNumberOfCPUs
,
309 ASSERT (MaximumNumberOfCPUs
<= MAX_CPU_NUM
&& NumberOfEnabledCPUs
>= 1);
313 // Assign a invalid intial value for update.
316 // Update the processors in the APIC table.
318 switch (Table
->Signature
) {
319 case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE
:
321 // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
323 if (mSystemConfig
.Asf
== 1) {
324 return EFI_UNSUPPORTED
;
326 AsfEntry
= (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*) Table
;
327 TempVal
= (mNumberSmbusAddress
< ASF_ADDR_DEVICE_ARRAY_LENGTH
)? mNumberSmbusAddress
: ASF_ADDR_DEVICE_ARRAY_LENGTH
;
328 for (Index
= 0; Index
< TempVal
; Index
++) {
329 AsfEntry
->AsfAddr
.FixedSmbusAddresses
[Index
] = mSmbusRsvdAddresses
[Index
];
333 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
:
335 Status
= MpService
->WhoAmI (
341 // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
343 APICTableHeader
= (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*)Table
;
344 APICTableHeader
->Flags
|= EFI_ACPI_3_0_PCAT_COMPAT
;
346 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) Table
)[1];
347 CurrPtr
= CurrPtr
+ 8;
350 // Size of Local APIC Address & Flag.
352 EndPtr
= (UINT8
*) Table
;
353 EndPtr
= EndPtr
+ Table
->Length
;
354 while (CurrPtr
< EndPtr
) {
355 ApicPtr
= (ACPI_APIC_STRUCTURE_PTR
*) CurrPtr
;
356 switch (ApicPtr
->AcpiApicCommon
.Type
) {
357 case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC
:
360 // Fix for Ordering of MADT to be maintained as it is in MADT table.
362 // Update processor enabled or disabled and keep the local APIC
363 // order in MADT intact.
365 // Sanity check to make sure proc-id is not arbitrary.
367 DEBUG ((EFI_D_ERROR
, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
368 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
, MaximumNumberOfCPUs
));
369 if(ApicPtr
->AcpiLocalApic
.AcpiProcessorId
> MaximumNumberOfCPUs
) {
370 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
= (UINT8
)MaximumNumberOfCPUs
;
373 ApicPtr
->AcpiLocalApic
.Flags
= 0;
375 for (CurrProcessor
= 0; CurrProcessor
< MaximumNumberOfCPUs
; CurrProcessor
++) {
376 Status
= MpService
->GetProcessorInfo (
382 if (Status
== EFI_SUCCESS
&& ProcessorInfoBuffer
.ProcessorId
== ApicPtr
->AcpiLocalApic
.ApicId
) {
384 // Check to see whether or not a processor (or thread) is enabled.
386 if ((BspIndex
== CurrProcessor
) || ((ProcessorInfoBuffer
.StatusFlag
& PROCESSOR_ENABLED_BIT
) != 0)) {
388 // Go on and check if Hyper Threading is enabled. If HT not enabled
389 // hide this thread from OS by not setting the flag to 1. This is the
390 // software way to disable Hyper Threading. Basically we just hide it
393 ApicPtr
->AcpiLocalApic
.Flags
= EFI_ACPI_1_0_LOCAL_APIC_ENABLED
;
396 if(ProcessorInfoBuffer
.Location
.Thread
!= 0) {
397 ApicPtr
->AcpiLocalApic
.Flags
= 0;
400 AppendCpuMapTableEntry (&(ApicPtr
->AcpiLocalApic
));
407 // If no APIC-ID match, the cpu may not be populated.
411 case EFI_ACPI_3_0_IO_APIC
:
413 IOApicType
= (EFI_ACPI_3_0_IO_APIC_STRUCTURE
*)CurrPtr
;
414 IOApicType
->IoApicId
= 0x02;
416 // IO APIC entries can be patched here.
421 CurrPtr
= CurrPtr
+ ApicPtr
->AcpiApicCommon
.Length
;
425 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
427 Facp
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) Table
;
428 Facp
->Flags
&= (UINT32
)(~(3<<2));
432 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
434 // Patch the memory resource.
436 PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER
*) Table
);
439 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
443 // TBD: Need re-design based on the ValleyTrail platform.
447 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE
:
449 // Adjust HPET Table to correct the Base Address.
451 // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
453 MmioOr8 (R_PCH_PCH_HPET
+ R_PCH_PCH_HPET_GCFG
, B_PCH_PCH_HPET_GCFG_EN
);
456 HpetTbl
= (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*) Table
;
457 HpetTbl
->BaseAddressLower32Bit
.Address
= HPET_BASE_ADDRESS
;
458 HpetTbl
->EventTimerBlockId
= *((UINT32
*)(UINTN
)HPET_BASE_ADDRESS
);
460 HpetCapIdValue
= *(UINT16
*)(UINTN
)(HPET_BASE_ADDRESS
);
461 NumberOfHpets
= HpetCapIdValue
& B_PCH_PCH_HPET_GCID_NT
; // Bits [8:12] contains the number of Hpets
462 HpetBlockID
= EFI_ACPI_EVENT_TIMER_BLOCK_ID
;
464 if((NumberOfHpets
) && (NumberOfHpets
& B_PCH_PCH_HPET_GCID_NT
)) {
465 HpetBlockID
|= (NumberOfHpets
);
467 HpetTbl
->EventTimerBlockId
= HpetBlockID
;
471 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
:
473 // Update MCFG base and end bus number.
475 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].BaseAddress
476 = mPlatformInfo
->PciData
.PciExpressBase
;
477 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].EndBusNumber
478 = (UINT8
)RShiftU64 (mPlatformInfo
->PciData
.PciExpressSize
, 20) - 1;
482 case EFI_ACPI_OSFR_TABLE_SIGNATURE
:
484 // Get size of OSFR variable.
486 OcurMfgStringBufferSize
= 0;
487 Status
= gRT
->GetVariable (
488 gACPIOSFRMfgStringVariableName
,
489 &gACPIOSFRMfgStringVariableGuid
,
491 &OcurMfgStringBufferSize
,
494 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
496 // Variable must not be present on the system.
498 return EFI_UNSUPPORTED
;
502 // Allocate memory for variable data.
504 OcurMfgStringBuffer
= AllocatePool (OcurMfgStringBufferSize
);
505 Status
= gRT
->GetVariable (
506 gACPIOSFRMfgStringVariableName
,
507 &gACPIOSFRMfgStringVariableGuid
,
509 &OcurMfgStringBufferSize
,
512 if (!EFI_ERROR (Status
)) {
513 OcurModelStringBufferSize
= 0;
514 Status
= gRT
->GetVariable (
515 gACPIOSFRModelStringVariableName
,
516 &gACPIOSFRModelStringVariableGuid
,
518 &OcurModelStringBufferSize
,
521 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
523 // Variable must not be present on the system.
525 return EFI_UNSUPPORTED
;
529 // Allocate memory for variable data.
531 OcurModelStringBuffer
= AllocatePool (OcurModelStringBufferSize
);
532 Status
= gRT
->GetVariable (
533 gACPIOSFRModelStringVariableName
,
534 &gACPIOSFRModelStringVariableGuid
,
536 &OcurModelStringBufferSize
,
537 OcurModelStringBuffer
539 if (!EFI_ERROR (Status
)) {
540 OcurRefDataBlockBufferSize
= 0;
541 Status
= gRT
->GetVariable (
542 gACPIOSFRRefDataBlockVariableName
,
543 &gACPIOSFRRefDataBlockVariableGuid
,
545 &OcurRefDataBlockBufferSize
,
548 if (Status
== EFI_BUFFER_TOO_SMALL
) {
550 // Allocate memory for variable data.
552 OcurRefDataBlockBuffer
= AllocatePool (OcurRefDataBlockBufferSize
);
553 Status
= gRT
->GetVariable (
554 gACPIOSFRRefDataBlockVariableName
,
555 &gACPIOSFRRefDataBlockVariableGuid
,
557 &OcurRefDataBlockBufferSize
,
558 OcurRefDataBlockBuffer
561 OsfrTable
= (EFI_ACPI_OSFR_TABLE
*) Table
;
563 // Currently only one object is defined: OCUR_OSFR_TABLE.
565 OsfrTable
->ObjectCount
= 1;
567 // Initialize table length to fixed portion of the ACPI OSFR table.
569 OsfrTable
->Header
.Length
= sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
);
570 *(UINT32
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
)) = \
571 (UINT32
) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + sizeof (UINT32
));
572 pOcurObject
= (EFI_ACPI_OSFR_OCUR_OBJECT
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + \
574 CopyMem (pOcurObject
, &OcurObject
, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
575 pOcurObject
->ManufacturerNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
576 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
577 pOcurObject
->ModelNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
578 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
);
579 if (OcurRefDataBlockBufferSize
> 0) {
580 pOcurObject
->MicrosoftReferenceOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
581 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ OcurModelStringBufferSize
);
583 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
)), OcurMfgStringBuffer
, \
584 OcurMfgStringBufferSize
);
585 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
), \
586 OcurModelStringBuffer
, OcurModelStringBufferSize
);
587 if (OcurRefDataBlockBufferSize
> 0) {
588 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ \
589 OcurModelStringBufferSize
),OcurRefDataBlockBuffer
, OcurRefDataBlockBufferSize
);
591 OsfrTable
->Header
.Length
+= (UINT32
)(OcurMfgStringBufferSize
+ OcurModelStringBufferSize
+ OcurRefDataBlockBufferSize
);
592 OsfrTable
->Header
.Length
+= sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + sizeof (UINT32
);
595 gBS
->FreePool (OcurMfgStringBuffer
);
596 gBS
->FreePool (OcurModelStringBuffer
);
597 gBS
->FreePool (OcurRefDataBlockBuffer
);
601 case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE
:
602 WsmtTable
= (EFI_ACPI_WSMT_TABLE
*) Table
;
604 // Update Microsoft WSMT table Protections flags.
606 WsmtTable
->ProtectionFlags
= ((WsmtTable
->ProtectionFlags
) | (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS
| EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION
));
616 // Update the hardware signature in the FACS structure.
619 // Locate the SPCR table and update based on current settings.
620 // The user may change CR settings via setup or other methods.
621 // The SPCR table must match.
630 GC_TODO: Add function description.
634 Event - GC_TODO: add argument description
635 Context - GC_TODO: add argument description
639 GC_TODO: add return values
651 EFI_ACPI_TABLE_VERSION TableVersion
;
652 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
653 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
654 SYSTEM_CONFIGURATION SetupVarBuffer
;
656 EFI_PLATFORM_CPU_INFO
*PlatformCpuInfoPtr
= NULL
;
657 EFI_PLATFORM_CPU_INFO PlatformCpuInfo
;
658 EFI_PEI_HOB_POINTERS GuidHob
;
667 // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
669 PlatformCpuInfo
.CpuVersion
.FullCpuId
= 0;
672 // Get Platform CPU Info HOB.
674 PlatformCpuInfoPtr
= NULL
;
675 ZeroMem (&PlatformCpuInfo
, sizeof(EFI_PLATFORM_CPU_INFO
));
676 VariableSize
= sizeof(EFI_PLATFORM_CPU_INFO
);
677 Status
= gRT
->GetVariable(
678 EfiPlatformCpuInfoVariable
,
679 &gEfiVlv2VariableGuid
,
684 if (EFI_ERROR(Status
)) {
685 GuidHob
.Raw
= GetHobList ();
686 if (GuidHob
.Raw
!= NULL
) {
687 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformCpuInfoGuid
, GuidHob
.Raw
)) != NULL
) {
688 PlatformCpuInfoPtr
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
693 if ((PlatformCpuInfoPtr
!= NULL
)) {
694 CopyMem(&PlatformCpuInfo
, PlatformCpuInfoPtr
, sizeof(EFI_PLATFORM_CPU_INFO
));
698 // Update the ACPI parameter blocks finally.
700 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
701 Status
= gRT
->GetVariable (
703 &mSystemConfigurationGuid
,
708 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
709 //The setup variable is corrupted
710 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
711 Status
= gRT
->GetVariable(
713 &mSystemConfigurationGuid
,
718 ASSERT_EFI_ERROR (Status
);
722 // Find the AcpiSupport protocol.
724 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
725 ASSERT_EFI_ERROR (Status
);
727 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
730 // Publish ACPI 1.0 or 2.0 Tables.
732 Status
= AcpiSupport
->PublishTables (
736 ASSERT_EFI_ERROR (Status
);
741 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, (VOID
**) &AcpiS3Save
);
742 if (!EFI_ERROR (Status
)) {
743 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
756 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
&& mPlatformInfo
->BoardRev
>= PR1
) {
757 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD PR1\n"));
758 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
760 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
761 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD8\n"));
762 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
768 Entry point for Acpi platform driver.
770 @param[in] ImageHandle A handle for the image that is initializing this driver.
771 @param[in] SystemTable A pointer to the EFI system table.
773 @retval EFI_SUCCESS Driver initialized successfully.
774 @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded.
775 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
780 AcpiPlatformEntryPoint (
781 IN EFI_HANDLE ImageHandle
,
782 IN EFI_SYSTEM_TABLE
*SystemTable
786 EFI_STATUS AcpiStatus
;
787 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
788 EFI_FIRMWARE_VOLUME_PROTOCOL
*FwVol
;
790 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
795 EFI_ACPI_TABLE_VERSION TableVersion
;
799 EFI_PS2_POLICY_PROTOCOL
*Ps2Policy
;
800 EFI_PEI_HOB_POINTERS GuidHob
;
802 EFI_MP_SERVICES_PROTOCOL
*MpService
;
803 UINTN MaximumNumberOfCPUs
;
804 UINTN NumberOfEnabledCPUs
;
805 PCH_STEPPING pchStepping
;
807 mFirstNotify
= FALSE
;
809 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
815 // Update HOB variable for PCI resource information.
816 // Get the HOB list. If it is not present, then ASSERT.
818 GuidHob
.Raw
= GetHobList ();
819 if (GuidHob
.Raw
!= NULL
) {
820 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformInfoGuid
, GuidHob
.Raw
)) != NULL
) {
821 mPlatformInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
826 // Search for the Memory Configuration GUID HOB. If it is not present, then
827 // there's nothing we can do. It may not exist on the update path.
829 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
830 Status
= gRT
->GetVariable(
832 &mSystemConfigurationGuid
,
835 &mSystemConfiguration
837 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
838 //The setup variable is corrupted
839 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
840 Status
= gRT
->GetVariable(
842 &mSystemConfigurationGuid
,
845 &mSystemConfiguration
847 ASSERT_EFI_ERROR (Status
);
851 // Find the AcpiSupport protocol.
853 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
854 ASSERT_EFI_ERROR (Status
);
857 // Locate the firmware volume protocol.
859 Status
= LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid
, (VOID
**) &FwVol
, 1);
860 ASSERT_EFI_ERROR (Status
);
863 // Read the current system configuration variable store.
865 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
866 Status
= gRT
->GetVariable (
868 &gEfiNormalSetupGuid
,
873 if (EFI_ERROR (Status
) || SysCfgSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
874 //The setup variable is corrupted
875 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
876 Status
= gRT
->GetVariable(
878 &gEfiNormalSetupGuid
,
883 ASSERT_EFI_ERROR (Status
);
887 Status
= EFI_SUCCESS
;
891 // TBD: Need re-design based on the ValleyTrail platform.
893 Status
= gBS
->LocateProtocol (
894 &gEfiMpServiceProtocolGuid
,
898 if (EFI_ERROR (Status
)) {
903 // Determine the number of processors.
905 MpService
->GetNumberOfProcessors (
907 &MaximumNumberOfCPUs
,
912 // Allocate and initialize the NVS area for SMM and ASL communication.
914 Status
= gBS
->AllocatePool (
916 sizeof (EFI_GLOBAL_NVS_AREA
),
917 (void **)&mGlobalNvsArea
.Area
919 ASSERT_EFI_ERROR (Status
);
922 sizeof (EFI_GLOBAL_NVS_AREA
),
925 DEBUG((EFI_D_ERROR
, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea
.Area
));
928 // Update global NVS area for ASL and SMM init code to use.
930 mGlobalNvsArea
.Area
->ApicEnable
= 1;
931 mGlobalNvsArea
.Area
->EmaEnable
= 0;
933 mGlobalNvsArea
.Area
->NumberOfBatteries
= 1;
934 mGlobalNvsArea
.Area
->BatteryCapacity0
= 100;
935 mGlobalNvsArea
.Area
->BatteryStatus0
= 84;
936 mGlobalNvsArea
.Area
->OnboardCom
= 1;
937 mGlobalNvsArea
.Area
->IdeMode
= 0;
938 mGlobalNvsArea
.Area
->PowerState
= 0;
940 mGlobalNvsArea
.Area
->LogicalProcessorCount
= (UINT8
)NumberOfEnabledCPUs
;
942 mGlobalNvsArea
.Area
->PassiveThermalTripPoint
= mSystemConfiguration
.PassiveThermalTripPoint
;
943 mGlobalNvsArea
.Area
->PassiveTc1Value
= mSystemConfiguration
.PassiveTc1Value
;
944 mGlobalNvsArea
.Area
->PassiveTc2Value
= mSystemConfiguration
.PassiveTc2Value
;
945 mGlobalNvsArea
.Area
->PassiveTspValue
= mSystemConfiguration
.PassiveTspValue
;
946 mGlobalNvsArea
.Area
->CriticalThermalTripPoint
= mSystemConfiguration
.CriticalThermalTripPoint
;
948 mGlobalNvsArea
.Area
->IgdPanelType
= mSystemConfiguration
.IgdFlatPanel
;
949 mGlobalNvsArea
.Area
->IgdPanelScaling
= mSystemConfiguration
.PanelScaling
;
950 mGlobalNvsArea
.Area
->IgdSciSmiMode
= 0;
951 mGlobalNvsArea
.Area
->IgdTvFormat
= 0;
952 mGlobalNvsArea
.Area
->IgdTvMinor
= 0;
953 mGlobalNvsArea
.Area
->IgdSscConfig
= 1;
954 mGlobalNvsArea
.Area
->IgdBiaConfig
= mSystemConfiguration
.IgdLcdIBia
;
955 mGlobalNvsArea
.Area
->IgdBlcConfig
= mSystemConfiguration
.IgdLcdIGmchBlc
;
956 mGlobalNvsArea
.Area
->IgdDvmtMemSize
= mSystemConfiguration
.IgdDvmt50TotalAlloc
;
957 mGlobalNvsArea
.Area
->IgdPAVP
= mSystemConfiguration
.PavpMode
;
959 mGlobalNvsArea
.Area
->AlsEnable
= mSystemConfiguration
.AlsEnable
;
960 mGlobalNvsArea
.Area
->BacklightControlSupport
= 2;
961 mGlobalNvsArea
.Area
->BrightnessPercentage
= 100;
962 mGlobalNvsArea
.Area
->IgdState
= 1;
963 mGlobalNvsArea
.Area
->LidState
= 1;
965 mGlobalNvsArea
.Area
->DeviceId1
= 0x80000100 ;
966 mGlobalNvsArea
.Area
->DeviceId2
= 0x80000400 ;
967 mGlobalNvsArea
.Area
->DeviceId3
= 0x80000200 ;
968 mGlobalNvsArea
.Area
->DeviceId4
= 0x04;
969 mGlobalNvsArea
.Area
->DeviceId5
= 0x05;
970 mGlobalNvsArea
.Area
->NumberOfValidDeviceId
= 4 ;
971 mGlobalNvsArea
.Area
->CurrentDeviceList
= 0x0F ;
972 mGlobalNvsArea
.Area
->PreviousDeviceList
= 0x0F ;
974 mGlobalNvsArea
.Area
->UartSelection
= mSystemConfiguration
.UartInterface
;
975 mGlobalNvsArea
.Area
->PcuUart1Enable
= mSystemConfiguration
.PcuUart1
;
976 mGlobalNvsArea
.Area
->NativePCIESupport
= 1;
977 mGlobalNvsArea
.Area
->RtcBattery
= mSystemConfiguration
.RtcBattery
;
984 // Update BootMode: 0:ACPI mode; 1:PCI mode
986 mGlobalNvsArea
.Area
->LpssSccMode
= mSystemConfiguration
.LpssPciModeEnabled
;
987 if (mSystemConfiguration
.LpssMipiHsi
== 0) {
988 mGlobalNvsArea
.Area
->MipiHsiAddr
= 0;
989 mGlobalNvsArea
.Area
->MipiHsiLen
= 0;
990 mGlobalNvsArea
.Area
->MipiHsi1Addr
= 0;
991 mGlobalNvsArea
.Area
->MipiHsi1Len
= 0;
997 mGlobalNvsArea
.Area
->PlatformFlavor
= mPlatformInfo
->PlatformFlavor
;
1000 // Update the Platform id
1002 mGlobalNvsArea
.Area
->BoardID
= mPlatformInfo
->BoardId
;
1005 // Update the Board Revision
1007 mGlobalNvsArea
.Area
->FabID
= mPlatformInfo
->BoardRev
;
1010 // Update SOC Stepping
1012 mGlobalNvsArea
.Area
->SocStepping
= (UINT8
)(PchStepping());
1014 mGlobalNvsArea
.Area
->OtgMode
= mSystemConfiguration
.PchUsbOtg
;
1016 pchStepping
= PchStepping();
1017 if (mSystemConfiguration
.UsbAutoMode
== 1) {
1019 // Auto mode is enabled.
1021 if (PchA0
== pchStepping
) {
1023 // For A0, EHCI is enabled as default.
1025 mSystemConfiguration
.PchUsb20
= 1;
1026 mSystemConfiguration
.PchUsb30Mode
= 0;
1027 mSystemConfiguration
.UsbXhciSupport
= 0;
1028 DEBUG ((EFI_D_INFO
, "EHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1031 // For A1 and later, XHCI is enabled as default.
1033 mSystemConfiguration
.PchUsb20
= 0;
1034 mSystemConfiguration
.PchUsb30Mode
= 1;
1035 mSystemConfiguration
.UsbXhciSupport
= 1;
1036 DEBUG ((EFI_D_INFO
, "XHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1040 mGlobalNvsArea
.Area
->XhciMode
= mSystemConfiguration
.PchUsb30Mode
;
1042 mGlobalNvsArea
.Area
->Stepping
= mPlatformInfo
->IchRevision
;
1045 // Override invalid Pre-Boot Driver and XhciMode combination.
1047 if ((mSystemConfiguration
.UsbXhciSupport
== 0) && (mSystemConfiguration
.PchUsb30Mode
== 3)) {
1048 mGlobalNvsArea
.Area
->XhciMode
= 2;
1050 if ((mSystemConfiguration
.UsbXhciSupport
== 1) && (mSystemConfiguration
.PchUsb30Mode
== 2)) {
1051 mGlobalNvsArea
.Area
->XhciMode
= 3;
1054 DEBUG ((EFI_D_ERROR
, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea
.Area
->XhciMode
));
1056 mGlobalNvsArea
.Area
->PmicEnable
= GLOBAL_NVS_DEVICE_DISABLE
;
1057 mGlobalNvsArea
.Area
->BatteryChargingSolution
= GLOBAL_NVS_DEVICE_DISABLE
;
1058 mGlobalNvsArea
.Area
->ISPDevSel
= mSystemConfiguration
.ISPDevSel
;
1059 mGlobalNvsArea
.Area
->LpeEnable
= mSystemConfiguration
.Lpe
;
1060 mGlobalNvsArea
.Area
->LpeAudioReportedByDSDT
= mSystemConfiguration
.LpeAudioReportedByDSDT
;
1062 if (mSystemConfiguration
.ISPEn
== 0) {
1063 mGlobalNvsArea
.Area
->ISPDevSel
= GLOBAL_NVS_DEVICE_DISABLE
;
1066 mGlobalNvsArea
.Area
->WittEnable
= mSystemConfiguration
.WittEnable
;
1067 mGlobalNvsArea
.Area
->UtsEnable
= mSystemConfiguration
.UtsEnable
;
1068 mGlobalNvsArea
.Area
->SarEnable
= mSystemConfiguration
.SAR1
;
1071 mGlobalNvsArea
.Area
->ReservedO
= 1;
1073 SettingI2CTouchAddress();
1074 mGlobalNvsArea
.Area
->IdleReserve
= mSystemConfiguration
.IdleReserve
;
1076 // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1078 // BUGBUG: code was moved into silicon reference code.
1080 if (mSystemConfiguration
.eMMCBootMode
== 1) {
1082 // Auto detect mode.
1084 DEBUG ((EFI_D_ERROR
, "Auto detect mode------------start\n"));
1087 // Silicon Steppings.
1089 switch (PchStepping()) {
1090 case PchA0
: // A0/A1
1092 DEBUG ((EFI_D_ERROR
, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1093 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1094 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1097 case PchB0
: // B0 and later.
1099 DEBUG ((EFI_D_ERROR
, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1100 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1101 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1104 } else if (mSystemConfiguration
.eMMCBootMode
== 2) {
1108 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.41 Configuration\n"));
1109 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1110 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1111 } else if (mSystemConfiguration
.eMMCBootMode
== 3) {
1115 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.5 Configuration\n"));
1116 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1117 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1121 // Disable eMMC controllers.
1123 DEBUG ((EFI_D_ERROR
, "Disable eMMC controllers\n"));
1124 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1125 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1128 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1129 if (mSystemConfiguration
.LpsseMMCEnabled
) {
1130 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1131 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1134 if (mSystemConfiguration
.LpsseMMC45Enabled
) {
1135 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1136 mGlobalNvsArea
.Area
->emmcVersion
= 1;
1139 mGlobalNvsArea
.Area
->SdCardRemovable
= mSystemConfiguration
.SdCardRemovable
;
1144 if ((mSystemConfiguration
.LpssHsuart0FlowControlEnabled
== 1) && \
1145 (mSystemConfiguration
.LpssPwm0Enabled
== 0) && \
1146 (mSystemConfiguration
.LpssPwm1Enabled
== 0)) {
1147 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_ENABLE
;
1148 DEBUG ((EFI_D_ERROR
, "JP1 is set to be MSFT IOT configuration.\n"));
1150 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_DISABLE
;
1151 DEBUG ((EFI_D_ERROR
, "JP1 is not set to be MSFT IOT configuration.\n"));
1155 // SIO related option.
1157 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (void **)&mCpuIo
);
1158 ASSERT_EFI_ERROR (Status
);
1160 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_DISABLE
;
1162 mGlobalNvsArea
.Area
->DockedSioPresent
= GLOBAL_NVS_DEVICE_DISABLE
;
1164 if (mGlobalNvsArea
.Area
->DockedSioPresent
!= GLOBAL_NVS_DEVICE_ENABLE
) {
1166 // Check ID for SIO WPCN381U.
1168 Status
= mCpuIo
->Io
.Read (
1171 WPCN381U_CONFIG_INDEX
,
1175 ASSERT_EFI_ERROR (Status
);
1176 if (PortData
!= 0xFF) {
1178 Status
= mCpuIo
->Io
.Write (
1181 WPCN381U_CONFIG_INDEX
,
1185 ASSERT_EFI_ERROR (Status
);
1186 Status
= mCpuIo
->Io
.Read (
1189 WPCN381U_CONFIG_DATA
,
1193 ASSERT_EFI_ERROR (Status
);
1194 if ((PortData
== WPCN381U_CHIP_ID
) || (PortData
== WDCP376_CHIP_ID
)) {
1195 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_ENABLE
;
1196 mGlobalNvsArea
.Area
->OnboardCom
= GLOBAL_NVS_DEVICE_ENABLE
;
1197 mGlobalNvsArea
.Area
->OnboardComCir
= GLOBAL_NVS_DEVICE_DISABLE
;
1205 // Get Ps2 policy to set. Will be use if present.
1207 Status
= gBS
->LocateProtocol (
1208 &gEfiPs2PolicyProtocolGuid
,
1212 if (!EFI_ERROR (Status
)) {
1213 Status
= Ps2Policy
->Ps2InitHardware (ImageHandle
);
1216 mGlobalNvsArea
.Area
->SDIOMode
= mSystemConfiguration
.LpssSdioMode
;
1219 Status
= gBS
->InstallMultipleProtocolInterfaces (
1221 &gEfiGlobalNvsAreaProtocolGuid
,
1227 // Read tables from the storage file.
1229 while (!EFI_ERROR (Status
)) {
1230 CurrentTable
= NULL
;
1232 Status
= FwVol
->ReadSection (
1234 &gEfiAcpiTableStorageGuid
,
1237 (VOID
**) &CurrentTable
,
1242 if (!EFI_ERROR (Status
)) {
1244 // Allow platform specific code to reject the table or update it.
1246 AcpiStatus
= AcpiPlatformHooksIsActiveTable (CurrentTable
);
1248 if (!EFI_ERROR (AcpiStatus
)) {
1250 // Perform any table specific updates.
1252 AcpiStatus
= PlatformUpdateTables (CurrentTable
);
1253 if (!EFI_ERROR (AcpiStatus
)) {
1258 AcpiStatus
= AcpiSupport
->SetAcpiTable (
1265 ASSERT_EFI_ERROR (AcpiStatus
);
1270 // Increment the instance.
1276 Status
= EfiCreateEventReadyToBootEx (
1296 IoWrite8(0x72, Index
);
1297 Data
= IoRead8 (0x73);
1302 WriteCmosBank1Byte (
1307 IoWrite8 (0x72, Index
);
1308 IoWrite8 (0x73, Data
);
1314 SettingI2CTouchAddress (
1318 if (mSystemConfiguration
.I2CTouchAd
== 0) {
1320 // If setup menu select auto set I2C Touch Address base on board id.
1322 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP
||
1323 mPlatformInfo
->BoardId
== BOARD_ID_BL_STHI
||
1324 mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP_DDR3L
) {
1328 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4B;
1329 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
) {
1333 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1334 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BB_RVP
) {
1335 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1336 } else if (mPlatformInfo
->BoardId
== BOARD_ID_CVH
) {
1337 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1338 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
1342 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1345 mGlobalNvsArea
.Area
->I2CTouchAddress
= mSystemConfiguration
.I2CTouchAd
;
1347 DEBUG((EFI_D_ERROR
, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea
.Area
->I2CTouchAddress
));