3 Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
25 #include <Protocol/TcgService.h>
26 #include <Protocol/FirmwareVolume2.h>
27 #include "AcpiPlatform.h"
28 #include "AcpiPlatformHooks.h"
29 #include "AcpiPlatformHooksLib.h"
34 #include <Guid/GlobalVariable.h>
35 #include <Guid/SetupVariable.h>
36 #include <Guid/PlatformInfo.h>
37 #include <Protocol/CpuIo.h>
38 #include <Guid/BoardFeatures.h>
39 #include <Protocol/AcpiSupport.h>
40 #include <Protocol/AcpiS3Save.h>
41 #include <Protocol/Ps2Policy.h>
42 #include <Library/CpuIA32.h>
43 #include <SetupMode.h>
44 #include <Guid/AcpiTableStorage.h>
45 #include <Guid/EfiVpdData.h>
46 #include <PchAccess.h>
47 #include <Guid/Vlv2Variable.h>
48 #include <Guid/PlatformCpuInfo.h>
49 #include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
52 CHAR16 EfiPlatformCpuInfoVariable
[] = L
"PlatformCpuInfo";
53 CHAR16 gACPIOSFRModelStringVariableName
[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME
;
54 CHAR16 gACPIOSFRRefDataBlockVariableName
[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME
;
55 CHAR16 gACPIOSFRMfgStringVariableName
[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME
;
57 EFI_CPU_IO_PROTOCOL
*mCpuIo
;
58 EFI_GLOBAL_NVS_AREA_PROTOCOL mGlobalNvsArea
;
60 #pragma optimize("", off)
63 EFI_PLATFORM_INFO_HOB
*mPlatformInfo
;
64 EFI_GUID mSystemConfigurationGuid
= SYSTEM_CONFIGURATION_GUID
;
65 SYSTEM_CONFIGURATION mSystemConfiguration
;
66 SYSTEM_CONFIGURATION mSystemConfig
;
68 UINT8 mSmbusRsvdAddresses
[] = PLATFORM_SMBUS_RSVD_ADDRESSES
;
69 UINT8 mNumberSmbusAddress
= sizeof( mSmbusRsvdAddresses
) / sizeof( mSmbusRsvdAddresses
[0] );
72 Locate the first instance of a protocol. If the protocol requested is an
73 FV protocol, then it will return the first FV that contains the ACPI table
76 @param[in] Protocol The protocol to find.
77 @param[in] Instance Return pointer to the first instance of the protocol.
78 @param[in] Type The type of protocol to locate.
80 @retval EFI_SUCCESS The function completed successfully.
81 @retval EFI_NOT_FOUND The protocol could not be located.
82 @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
86 LocateSupportProtocol (
87 IN EFI_GUID
*Protocol
,
93 EFI_HANDLE
*HandleBuffer
;
94 UINTN NumberOfHandles
;
95 EFI_FV_FILETYPE FileType
;
97 EFI_FV_FILE_ATTRIBUTES Attributes
;
106 Status
= gBS
->LocateHandleBuffer (
113 if (EFI_ERROR (Status
)) {
115 // Defined errors at this time are not found and out of resources.
121 // Looking for FV with ACPI storage file.
123 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
125 // Get the protocol on this handle.
126 // This should not fail because of LocateHandleBuffer.
128 Status
= gBS
->HandleProtocol (
133 ASSERT (!EFI_ERROR (Status
));
137 // Not looking for the FV protocol, so find the first instance of the
138 // protocol. There should not be any errors because our handle buffer
139 // should always contain at least one or LocateHandleBuffer would have
140 // returned not found.
146 // See if it has the ACPI storage file.
148 Status
= ((EFI_FIRMWARE_VOLUME_PROTOCOL
*) (*Instance
))->ReadFile (
150 &gEfiAcpiTableStorageGuid
,
159 // If we found it, then we are done.
161 if (!EFI_ERROR (Status
)) {
167 // Our exit status is determined by the success of the previous operations.
168 // If the protocol was found, Instance already points to it.
171 // Free any allocated buffers.
173 gBS
->FreePool (HandleBuffer
);
179 This function will update any runtime platform specific information.
180 This currently includes:
181 Setting OEM table values, ID, table ID, creator ID and creator revision.
182 Enabling the proper processor entries in the APIC tables.
184 @param[in] Table The table to update.
186 @retval EFI_SUCCESS The function completed successfully.
190 PlatformUpdateTables (
191 IN OUT EFI_ACPI_COMMON_HEADER
*Table
194 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
197 ACPI_APIC_STRUCTURE_PTR
*ApicPtr
;
200 EFI_MP_SERVICES_PROTOCOL
*MpService
;
201 UINTN MaximumNumberOfCPUs
;
202 UINTN NumberOfEnabledCPUs
;
204 EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*AsfEntry
;
205 EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*HpetTbl
;
208 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*Facp
;
209 EFI_ACPI_OSFR_TABLE
*OsfrTable
;
210 EFI_ACPI_OSFR_OCUR_OBJECT
*pOcurObject
;
211 EFI_ACPI_OSFR_OCUR_OBJECT OcurObject
= {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
212 CHAR16
*OcurMfgStringBuffer
= NULL
;
213 CHAR16
*OcurModelStringBuffer
= NULL
;
214 UINT8
*OcurRefDataBlockBuffer
= NULL
;
215 UINTN OcurMfgStringBufferSize
;
216 UINTN OcurModelStringBufferSize
;
217 UINTN OcurRefDataBlockBufferSize
;
218 #if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
219 EFI_ACPI_ASPT_TABLE
*pSpttTable
;
221 UINT16 NumberOfHpets
;
222 UINT16 HpetCapIdValue
;
224 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
226 EFI_ACPI_3_0_IO_APIC_STRUCTURE
*IOApicType
;
227 EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*APICTableHeader
;
228 EFI_ACPI_WSMT_TABLE
*WsmtTable
;
236 if (Table
->Signature
!= EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
237 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
241 OemIdValue
= mPlatformInfo
->AcpiOemId
;
243 *(UINT32
*)(TableHeader
->OemId
) = (UINT32
)OemIdValue
;
244 *(UINT16
*)(TableHeader
->OemId
+ 4) = *(UINT16
*)(((UINT8
*)&OemIdValue
) + 4);
246 if ((Table
->Signature
!= EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)) {
248 // Update the OEM Table ID.
250 TableHeader
->OemTableId
= mPlatformInfo
->AcpiOemTableId
;
254 // Update the OEM Table ID.
256 TableHeader
->OemRevision
= EFI_ACPI_OEM_REVISION
;
259 // Update the creator ID.
261 TableHeader
->CreatorId
= EFI_ACPI_CREATOR_ID
;
264 // Update the creator revision.
266 TableHeader
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
270 // Complete this function.
273 // Locate the MP services protocol.
276 // Find the MP Protocol. This is an MP platform, so MP protocol must be
279 Status
= gBS
->LocateProtocol (
280 &gEfiMpServiceProtocolGuid
,
284 if (EFI_ERROR (Status
)) {
289 // Determine the number of processors.
291 MpService
->GetNumberOfProcessors (
293 &MaximumNumberOfCPUs
,
297 ASSERT (MaximumNumberOfCPUs
<= MAX_CPU_NUM
&& NumberOfEnabledCPUs
>= 1);
301 // Assign a invalid intial value for update.
304 // Update the processors in the APIC table.
306 switch (Table
->Signature
) {
307 case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE
:
309 // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
311 if (mSystemConfig
.Asf
== 1) {
312 return EFI_UNSUPPORTED
;
314 AsfEntry
= (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*) Table
;
315 TempVal
= (mNumberSmbusAddress
< ASF_ADDR_DEVICE_ARRAY_LENGTH
)? mNumberSmbusAddress
: ASF_ADDR_DEVICE_ARRAY_LENGTH
;
316 for (Index
= 0; Index
< TempVal
; Index
++) {
317 AsfEntry
->AsfAddr
.FixedSmbusAddresses
[Index
] = mSmbusRsvdAddresses
[Index
];
321 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
:
323 Status
= MpService
->WhoAmI (
329 // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
331 APICTableHeader
= (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*)Table
;
332 APICTableHeader
->Flags
|= EFI_ACPI_3_0_PCAT_COMPAT
;
334 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) Table
)[1];
335 CurrPtr
= CurrPtr
+ 8;
338 // Size of Local APIC Address & Flag.
340 EndPtr
= (UINT8
*) Table
;
341 EndPtr
= EndPtr
+ Table
->Length
;
342 while (CurrPtr
< EndPtr
) {
343 ApicPtr
= (ACPI_APIC_STRUCTURE_PTR
*) CurrPtr
;
344 switch (ApicPtr
->AcpiApicCommon
.Type
) {
345 case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC
:
348 // Fix for Ordering of MADT to be maintained as it is in MADT table.
350 // Update processor enabled or disabled and keep the local APIC
351 // order in MADT intact.
353 // Sanity check to make sure proc-id is not arbitrary.
355 DEBUG ((EFI_D_ERROR
, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
356 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
, MaximumNumberOfCPUs
));
357 if(ApicPtr
->AcpiLocalApic
.AcpiProcessorId
> MaximumNumberOfCPUs
) {
358 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
= (UINT8
)MaximumNumberOfCPUs
;
361 ApicPtr
->AcpiLocalApic
.Flags
= 0;
363 for (CurrProcessor
= 0; CurrProcessor
< MaximumNumberOfCPUs
; CurrProcessor
++) {
364 Status
= MpService
->GetProcessorInfo (
370 if (Status
== EFI_SUCCESS
&& ProcessorInfoBuffer
.ProcessorId
== ApicPtr
->AcpiLocalApic
.ApicId
) {
372 // Check to see whether or not a processor (or thread) is enabled.
374 if ((BspIndex
== CurrProcessor
) || ((ProcessorInfoBuffer
.StatusFlag
& PROCESSOR_ENABLED_BIT
) != 0)) {
376 // Go on and check if Hyper Threading is enabled. If HT not enabled
377 // hide this thread from OS by not setting the flag to 1. This is the
378 // software way to disable Hyper Threading. Basically we just hide it
381 ApicPtr
->AcpiLocalApic
.Flags
= EFI_ACPI_1_0_LOCAL_APIC_ENABLED
;
384 if(ProcessorInfoBuffer
.Location
.Thread
!= 0) {
385 ApicPtr
->AcpiLocalApic
.Flags
= 0;
388 AppendCpuMapTableEntry (&(ApicPtr
->AcpiLocalApic
));
395 // If no APIC-ID match, the cpu may not be populated.
399 case EFI_ACPI_3_0_IO_APIC
:
401 IOApicType
= (EFI_ACPI_3_0_IO_APIC_STRUCTURE
*)CurrPtr
;
402 IOApicType
->IoApicId
= 0x02;
404 // IO APIC entries can be patched here.
409 CurrPtr
= CurrPtr
+ ApicPtr
->AcpiApicCommon
.Length
;
413 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
415 Facp
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) Table
;
416 Facp
->Flags
&= (UINT32
)(~(3<<2));
420 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
422 // Patch the memory resource.
424 PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER
*) Table
);
427 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
431 // TBD: Need re-design based on the ValleyTrail platform.
435 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE
:
437 // Adjust HPET Table to correct the Base Address.
439 // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
441 MmioOr8 (R_PCH_PCH_HPET
+ R_PCH_PCH_HPET_GCFG
, B_PCH_PCH_HPET_GCFG_EN
);
444 HpetTbl
= (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*) Table
;
445 HpetTbl
->BaseAddressLower32Bit
.Address
= HPET_BASE_ADDRESS
;
446 HpetTbl
->EventTimerBlockId
= *((UINT32
*)(UINTN
)HPET_BASE_ADDRESS
);
448 HpetCapIdValue
= *(UINT16
*)(UINTN
)(HPET_BASE_ADDRESS
);
449 NumberOfHpets
= HpetCapIdValue
& B_PCH_PCH_HPET_GCID_NT
; // Bits [8:12] contains the number of Hpets
450 HpetBlockID
= EFI_ACPI_EVENT_TIMER_BLOCK_ID
;
452 if((NumberOfHpets
) && (NumberOfHpets
& B_PCH_PCH_HPET_GCID_NT
)) {
453 HpetBlockID
|= (NumberOfHpets
);
455 HpetTbl
->EventTimerBlockId
= HpetBlockID
;
459 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
:
461 // Update MCFG base and end bus number.
463 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].BaseAddress
464 = mPlatformInfo
->PciData
.PciExpressBase
;
465 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].EndBusNumber
466 = (UINT8
)RShiftU64 (mPlatformInfo
->PciData
.PciExpressSize
, 20) - 1;
470 case EFI_ACPI_OSFR_TABLE_SIGNATURE
:
472 // Get size of OSFR variable.
474 OcurMfgStringBufferSize
= 0;
475 Status
= gRT
->GetVariable (
476 gACPIOSFRMfgStringVariableName
,
477 &gACPIOSFRMfgStringVariableGuid
,
479 &OcurMfgStringBufferSize
,
482 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
484 // Variable must not be present on the system.
486 return EFI_UNSUPPORTED
;
490 // Allocate memory for variable data.
492 OcurMfgStringBuffer
= AllocatePool (OcurMfgStringBufferSize
);
493 Status
= gRT
->GetVariable (
494 gACPIOSFRMfgStringVariableName
,
495 &gACPIOSFRMfgStringVariableGuid
,
497 &OcurMfgStringBufferSize
,
500 if (!EFI_ERROR (Status
)) {
501 OcurModelStringBufferSize
= 0;
502 Status
= gRT
->GetVariable (
503 gACPIOSFRModelStringVariableName
,
504 &gACPIOSFRModelStringVariableGuid
,
506 &OcurModelStringBufferSize
,
509 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
511 // Variable must not be present on the system.
513 return EFI_UNSUPPORTED
;
517 // Allocate memory for variable data.
519 OcurModelStringBuffer
= AllocatePool (OcurModelStringBufferSize
);
520 Status
= gRT
->GetVariable (
521 gACPIOSFRModelStringVariableName
,
522 &gACPIOSFRModelStringVariableGuid
,
524 &OcurModelStringBufferSize
,
525 OcurModelStringBuffer
527 if (!EFI_ERROR (Status
)) {
528 OcurRefDataBlockBufferSize
= 0;
529 Status
= gRT
->GetVariable (
530 gACPIOSFRRefDataBlockVariableName
,
531 &gACPIOSFRRefDataBlockVariableGuid
,
533 &OcurRefDataBlockBufferSize
,
536 if (Status
== EFI_BUFFER_TOO_SMALL
) {
538 // Allocate memory for variable data.
540 OcurRefDataBlockBuffer
= AllocatePool (OcurRefDataBlockBufferSize
);
541 Status
= gRT
->GetVariable (
542 gACPIOSFRRefDataBlockVariableName
,
543 &gACPIOSFRRefDataBlockVariableGuid
,
545 &OcurRefDataBlockBufferSize
,
546 OcurRefDataBlockBuffer
549 OsfrTable
= (EFI_ACPI_OSFR_TABLE
*) Table
;
551 // Currently only one object is defined: OCUR_OSFR_TABLE.
553 OsfrTable
->ObjectCount
= 1;
555 // Initialize table length to fixed portion of the ACPI OSFR table.
557 OsfrTable
->Header
.Length
= sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
);
558 *(UINT32
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
)) = \
559 (UINT32
) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + sizeof (UINT32
));
560 pOcurObject
= (EFI_ACPI_OSFR_OCUR_OBJECT
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + \
562 CopyMem (pOcurObject
, &OcurObject
, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
563 pOcurObject
->ManufacturerNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
564 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
565 pOcurObject
->ModelNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
566 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
);
567 if (OcurRefDataBlockBufferSize
> 0) {
568 pOcurObject
->MicrosoftReferenceOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
569 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ OcurModelStringBufferSize
);
571 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
)), OcurMfgStringBuffer
, \
572 OcurMfgStringBufferSize
);
573 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
), \
574 OcurModelStringBuffer
, OcurModelStringBufferSize
);
575 if (OcurRefDataBlockBufferSize
> 0) {
576 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ \
577 OcurModelStringBufferSize
),OcurRefDataBlockBuffer
, OcurRefDataBlockBufferSize
);
579 OsfrTable
->Header
.Length
+= (UINT32
)(OcurMfgStringBufferSize
+ OcurModelStringBufferSize
+ OcurRefDataBlockBufferSize
);
580 OsfrTable
->Header
.Length
+= sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + sizeof (UINT32
);
583 gBS
->FreePool (OcurMfgStringBuffer
);
584 gBS
->FreePool (OcurModelStringBuffer
);
585 gBS
->FreePool (OcurRefDataBlockBuffer
);
589 case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE
:
590 WsmtTable
= (EFI_ACPI_WSMT_TABLE
*) Table
;
592 // Update Microsoft WSMT table Protections flags.
594 WsmtTable
->ProtectionFlags
= ((WsmtTable
->ProtectionFlags
) | (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS
| EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION
));
604 // Update the hardware signature in the FACS structure.
607 // Locate the SPCR table and update based on current settings.
608 // The user may change CR settings via setup or other methods.
609 // The SPCR table must match.
618 GC_TODO: Add function description.
622 Event - GC_TODO: add argument description
623 Context - GC_TODO: add argument description
627 GC_TODO: add return values
639 EFI_ACPI_TABLE_VERSION TableVersion
;
640 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
641 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
642 SYSTEM_CONFIGURATION SetupVarBuffer
;
644 EFI_PLATFORM_CPU_INFO
*PlatformCpuInfoPtr
= NULL
;
645 EFI_PLATFORM_CPU_INFO PlatformCpuInfo
;
646 EFI_PEI_HOB_POINTERS GuidHob
;
655 // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
657 PlatformCpuInfo
.CpuVersion
.FullCpuId
= 0;
660 // Get Platform CPU Info HOB.
662 PlatformCpuInfoPtr
= NULL
;
663 ZeroMem (&PlatformCpuInfo
, sizeof(EFI_PLATFORM_CPU_INFO
));
664 VariableSize
= sizeof(EFI_PLATFORM_CPU_INFO
);
665 Status
= gRT
->GetVariable(
666 EfiPlatformCpuInfoVariable
,
667 &gEfiVlv2VariableGuid
,
672 if (EFI_ERROR(Status
)) {
673 GuidHob
.Raw
= GetHobList ();
674 if (GuidHob
.Raw
!= NULL
) {
675 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformCpuInfoGuid
, GuidHob
.Raw
)) != NULL
) {
676 PlatformCpuInfoPtr
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
681 if ((PlatformCpuInfoPtr
!= NULL
)) {
682 CopyMem(&PlatformCpuInfo
, PlatformCpuInfoPtr
, sizeof(EFI_PLATFORM_CPU_INFO
));
686 // Update the ACPI parameter blocks finally.
688 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
689 Status
= gRT
->GetVariable (
691 &mSystemConfigurationGuid
,
696 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
697 //The setup variable is corrupted
698 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
699 Status
= gRT
->GetVariable(
701 &mSystemConfigurationGuid
,
706 ASSERT_EFI_ERROR (Status
);
710 // Find the AcpiSupport protocol.
712 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
713 ASSERT_EFI_ERROR (Status
);
715 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
718 // Publish ACPI 1.0 or 2.0 Tables.
720 Status
= AcpiSupport
->PublishTables (
724 ASSERT_EFI_ERROR (Status
);
729 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, (VOID
**) &AcpiS3Save
);
730 if (!EFI_ERROR (Status
)) {
731 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
744 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
&& mPlatformInfo
->BoardRev
>= PR1
) {
745 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD PR1\n"));
746 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
748 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
749 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD8\n"));
750 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
756 Entry point for Acpi platform driver.
758 @param[in] ImageHandle A handle for the image that is initializing this driver.
759 @param[in] SystemTable A pointer to the EFI system table.
761 @retval EFI_SUCCESS Driver initialized successfully.
762 @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded.
763 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
768 AcpiPlatformEntryPoint (
769 IN EFI_HANDLE ImageHandle
,
770 IN EFI_SYSTEM_TABLE
*SystemTable
774 EFI_STATUS AcpiStatus
;
775 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
776 EFI_FIRMWARE_VOLUME2_PROTOCOL
*FwVol
;
778 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
783 EFI_ACPI_TABLE_VERSION TableVersion
;
787 EFI_PS2_POLICY_PROTOCOL
*Ps2Policy
;
788 EFI_PEI_HOB_POINTERS GuidHob
;
790 EFI_MP_SERVICES_PROTOCOL
*MpService
;
791 UINTN MaximumNumberOfCPUs
;
792 UINTN NumberOfEnabledCPUs
;
793 PCH_STEPPING pchStepping
;
795 mFirstNotify
= FALSE
;
797 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
803 // Update HOB variable for PCI resource information.
804 // Get the HOB list. If it is not present, then ASSERT.
806 GuidHob
.Raw
= GetHobList ();
807 if (GuidHob
.Raw
!= NULL
) {
808 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformInfoGuid
, GuidHob
.Raw
)) != NULL
) {
809 mPlatformInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
814 // Search for the Memory Configuration GUID HOB. If it is not present, then
815 // there's nothing we can do. It may not exist on the update path.
817 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
818 Status
= gRT
->GetVariable(
820 &mSystemConfigurationGuid
,
823 &mSystemConfiguration
825 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
826 //The setup variable is corrupted
827 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
828 Status
= gRT
->GetVariable(
830 &mSystemConfigurationGuid
,
833 &mSystemConfiguration
835 ASSERT_EFI_ERROR (Status
);
839 // Find the AcpiSupport protocol.
841 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
842 ASSERT_EFI_ERROR (Status
);
845 // Locate the firmware volume protocol.
847 Status
= LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid
, (VOID
**) &FwVol
, 1);
848 ASSERT_EFI_ERROR (Status
);
851 // Read the current system configuration variable store.
853 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
854 Status
= gRT
->GetVariable (
856 &gEfiNormalSetupGuid
,
861 if (EFI_ERROR (Status
) || SysCfgSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
862 //The setup variable is corrupted
863 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
864 Status
= gRT
->GetVariable(
866 &gEfiNormalSetupGuid
,
871 ASSERT_EFI_ERROR (Status
);
875 Status
= EFI_SUCCESS
;
879 // TBD: Need re-design based on the ValleyTrail platform.
881 Status
= gBS
->LocateProtocol (
882 &gEfiMpServiceProtocolGuid
,
886 if (EFI_ERROR (Status
)) {
891 // Determine the number of processors.
893 MpService
->GetNumberOfProcessors (
895 &MaximumNumberOfCPUs
,
900 // Allocate and initialize the NVS area for SMM and ASL communication.
902 Status
= gBS
->AllocatePool (
904 sizeof (EFI_GLOBAL_NVS_AREA
),
905 (void **)&mGlobalNvsArea
.Area
907 ASSERT_EFI_ERROR (Status
);
910 sizeof (EFI_GLOBAL_NVS_AREA
),
913 DEBUG((EFI_D_ERROR
, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea
.Area
));
916 // Update global NVS area for ASL and SMM init code to use.
918 mGlobalNvsArea
.Area
->ApicEnable
= 1;
919 mGlobalNvsArea
.Area
->EmaEnable
= 0;
921 mGlobalNvsArea
.Area
->NumberOfBatteries
= 1;
922 mGlobalNvsArea
.Area
->BatteryCapacity0
= 100;
923 mGlobalNvsArea
.Area
->BatteryStatus0
= 84;
924 mGlobalNvsArea
.Area
->OnboardCom
= 1;
925 mGlobalNvsArea
.Area
->IdeMode
= 0;
926 mGlobalNvsArea
.Area
->PowerState
= 0;
928 mGlobalNvsArea
.Area
->LogicalProcessorCount
= (UINT8
)NumberOfEnabledCPUs
;
930 mGlobalNvsArea
.Area
->PassiveThermalTripPoint
= mSystemConfiguration
.PassiveThermalTripPoint
;
931 mGlobalNvsArea
.Area
->PassiveTc1Value
= mSystemConfiguration
.PassiveTc1Value
;
932 mGlobalNvsArea
.Area
->PassiveTc2Value
= mSystemConfiguration
.PassiveTc2Value
;
933 mGlobalNvsArea
.Area
->PassiveTspValue
= mSystemConfiguration
.PassiveTspValue
;
934 mGlobalNvsArea
.Area
->CriticalThermalTripPoint
= mSystemConfiguration
.CriticalThermalTripPoint
;
936 mGlobalNvsArea
.Area
->IgdPanelType
= mSystemConfiguration
.IgdFlatPanel
;
937 mGlobalNvsArea
.Area
->IgdPanelScaling
= mSystemConfiguration
.PanelScaling
;
938 mGlobalNvsArea
.Area
->IgdSciSmiMode
= 0;
939 mGlobalNvsArea
.Area
->IgdTvFormat
= 0;
940 mGlobalNvsArea
.Area
->IgdTvMinor
= 0;
941 mGlobalNvsArea
.Area
->IgdSscConfig
= 1;
942 mGlobalNvsArea
.Area
->IgdBiaConfig
= mSystemConfiguration
.IgdLcdIBia
;
943 mGlobalNvsArea
.Area
->IgdBlcConfig
= mSystemConfiguration
.IgdLcdIGmchBlc
;
944 mGlobalNvsArea
.Area
->IgdDvmtMemSize
= mSystemConfiguration
.IgdDvmt50TotalAlloc
;
945 mGlobalNvsArea
.Area
->IgdPAVP
= mSystemConfiguration
.PavpMode
;
947 mGlobalNvsArea
.Area
->AlsEnable
= mSystemConfiguration
.AlsEnable
;
948 mGlobalNvsArea
.Area
->BacklightControlSupport
= 2;
949 mGlobalNvsArea
.Area
->BrightnessPercentage
= 100;
950 mGlobalNvsArea
.Area
->IgdState
= 1;
951 mGlobalNvsArea
.Area
->LidState
= 1;
953 mGlobalNvsArea
.Area
->DeviceId1
= 0x80000100 ;
954 mGlobalNvsArea
.Area
->DeviceId2
= 0x80000400 ;
955 mGlobalNvsArea
.Area
->DeviceId3
= 0x80000200 ;
956 mGlobalNvsArea
.Area
->DeviceId4
= 0x04;
957 mGlobalNvsArea
.Area
->DeviceId5
= 0x05;
958 mGlobalNvsArea
.Area
->NumberOfValidDeviceId
= 4 ;
959 mGlobalNvsArea
.Area
->CurrentDeviceList
= 0x0F ;
960 mGlobalNvsArea
.Area
->PreviousDeviceList
= 0x0F ;
962 mGlobalNvsArea
.Area
->UartSelection
= mSystemConfiguration
.UartInterface
;
963 mGlobalNvsArea
.Area
->PcuUart1Enable
= mSystemConfiguration
.PcuUart1
;
964 mGlobalNvsArea
.Area
->NativePCIESupport
= 1;
965 mGlobalNvsArea
.Area
->RtcBattery
= mSystemConfiguration
.RtcBattery
;
972 // Update BootMode: 0:ACPI mode; 1:PCI mode
974 mGlobalNvsArea
.Area
->LpssSccMode
= mSystemConfiguration
.LpssPciModeEnabled
;
975 if (mSystemConfiguration
.LpssMipiHsi
== 0) {
976 mGlobalNvsArea
.Area
->MipiHsiAddr
= 0;
977 mGlobalNvsArea
.Area
->MipiHsiLen
= 0;
978 mGlobalNvsArea
.Area
->MipiHsi1Addr
= 0;
979 mGlobalNvsArea
.Area
->MipiHsi1Len
= 0;
985 mGlobalNvsArea
.Area
->PlatformFlavor
= mPlatformInfo
->PlatformFlavor
;
988 // Update the Platform id
990 mGlobalNvsArea
.Area
->BoardID
= mPlatformInfo
->BoardId
;
993 // Update the Board Revision
995 mGlobalNvsArea
.Area
->FabID
= mPlatformInfo
->BoardRev
;
998 // Update SOC Stepping
1000 mGlobalNvsArea
.Area
->SocStepping
= (UINT8
)(PchStepping());
1002 mGlobalNvsArea
.Area
->OtgMode
= mSystemConfiguration
.PchUsbOtg
;
1004 pchStepping
= PchStepping();
1005 if (mSystemConfiguration
.UsbAutoMode
== 1) {
1007 // Auto mode is enabled.
1009 if (PchA0
== pchStepping
) {
1011 // For A0, EHCI is enabled as default.
1013 mSystemConfiguration
.PchUsb20
= 1;
1014 mSystemConfiguration
.PchUsb30Mode
= 0;
1015 mSystemConfiguration
.UsbXhciSupport
= 0;
1016 DEBUG ((EFI_D_INFO
, "EHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1019 // For A1 and later, XHCI is enabled as default.
1021 mSystemConfiguration
.PchUsb20
= 0;
1022 mSystemConfiguration
.PchUsb30Mode
= 1;
1023 mSystemConfiguration
.UsbXhciSupport
= 1;
1024 DEBUG ((EFI_D_INFO
, "XHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1028 mGlobalNvsArea
.Area
->XhciMode
= mSystemConfiguration
.PchUsb30Mode
;
1030 mGlobalNvsArea
.Area
->Stepping
= mPlatformInfo
->IchRevision
;
1033 // Override invalid Pre-Boot Driver and XhciMode combination.
1035 if ((mSystemConfiguration
.UsbXhciSupport
== 0) && (mSystemConfiguration
.PchUsb30Mode
== 3)) {
1036 mGlobalNvsArea
.Area
->XhciMode
= 2;
1038 if ((mSystemConfiguration
.UsbXhciSupport
== 1) && (mSystemConfiguration
.PchUsb30Mode
== 2)) {
1039 mGlobalNvsArea
.Area
->XhciMode
= 3;
1042 DEBUG ((EFI_D_ERROR
, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea
.Area
->XhciMode
));
1044 mGlobalNvsArea
.Area
->PmicEnable
= GLOBAL_NVS_DEVICE_DISABLE
;
1045 mGlobalNvsArea
.Area
->BatteryChargingSolution
= GLOBAL_NVS_DEVICE_DISABLE
;
1046 mGlobalNvsArea
.Area
->ISPDevSel
= mSystemConfiguration
.ISPDevSel
;
1047 mGlobalNvsArea
.Area
->LpeEnable
= mSystemConfiguration
.Lpe
;
1048 mGlobalNvsArea
.Area
->LpeAudioReportedByDSDT
= mSystemConfiguration
.LpeAudioReportedByDSDT
;
1050 if (mSystemConfiguration
.ISPEn
== 0) {
1051 mGlobalNvsArea
.Area
->ISPDevSel
= GLOBAL_NVS_DEVICE_DISABLE
;
1054 mGlobalNvsArea
.Area
->WittEnable
= mSystemConfiguration
.WittEnable
;
1055 mGlobalNvsArea
.Area
->UtsEnable
= mSystemConfiguration
.UtsEnable
;
1056 mGlobalNvsArea
.Area
->SarEnable
= mSystemConfiguration
.SAR1
;
1059 mGlobalNvsArea
.Area
->ReservedO
= 1;
1061 SettingI2CTouchAddress();
1062 mGlobalNvsArea
.Area
->IdleReserve
= mSystemConfiguration
.IdleReserve
;
1064 // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1066 // BUGBUG: code was moved into silicon reference code.
1068 if (mSystemConfiguration
.eMMCBootMode
== 1) {
1070 // Auto detect mode.
1072 DEBUG ((EFI_D_ERROR
, "Auto detect mode------------start\n"));
1075 // Silicon Steppings.
1077 switch (PchStepping()) {
1078 case PchA0
: // A0/A1
1080 DEBUG ((EFI_D_ERROR
, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1081 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1082 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1085 case PchB0
: // B0 and later.
1087 DEBUG ((EFI_D_ERROR
, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1088 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1089 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1092 } else if (mSystemConfiguration
.eMMCBootMode
== 2) {
1096 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.41 Configuration\n"));
1097 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1098 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1099 } else if (mSystemConfiguration
.eMMCBootMode
== 3) {
1103 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.5 Configuration\n"));
1104 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1105 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1109 // Disable eMMC controllers.
1111 DEBUG ((EFI_D_ERROR
, "Disable eMMC controllers\n"));
1112 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1113 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1116 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1117 if (mSystemConfiguration
.LpsseMMCEnabled
) {
1118 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1119 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1122 if (mSystemConfiguration
.LpsseMMC45Enabled
) {
1123 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1124 mGlobalNvsArea
.Area
->emmcVersion
= 1;
1127 mGlobalNvsArea
.Area
->SdCardRemovable
= mSystemConfiguration
.SdCardRemovable
;
1132 if ((mSystemConfiguration
.LpssHsuart0FlowControlEnabled
== 1) && \
1133 (mSystemConfiguration
.LpssPwm0Enabled
== 0) && \
1134 (mSystemConfiguration
.LpssPwm1Enabled
== 0)) {
1135 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_ENABLE
;
1136 DEBUG ((EFI_D_ERROR
, "JP1 is set to be MSFT IOT configuration.\n"));
1138 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_DISABLE
;
1139 DEBUG ((EFI_D_ERROR
, "JP1 is not set to be MSFT IOT configuration.\n"));
1143 // SIO related option.
1145 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (void **)&mCpuIo
);
1146 ASSERT_EFI_ERROR (Status
);
1148 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_DISABLE
;
1150 mGlobalNvsArea
.Area
->DockedSioPresent
= GLOBAL_NVS_DEVICE_DISABLE
;
1152 if (mGlobalNvsArea
.Area
->DockedSioPresent
!= GLOBAL_NVS_DEVICE_ENABLE
) {
1154 // Check ID for SIO WPCN381U.
1156 Status
= mCpuIo
->Io
.Read (
1159 WPCN381U_CONFIG_INDEX
,
1163 ASSERT_EFI_ERROR (Status
);
1164 if (PortData
!= 0xFF) {
1166 Status
= mCpuIo
->Io
.Write (
1169 WPCN381U_CONFIG_INDEX
,
1173 ASSERT_EFI_ERROR (Status
);
1174 Status
= mCpuIo
->Io
.Read (
1177 WPCN381U_CONFIG_DATA
,
1181 ASSERT_EFI_ERROR (Status
);
1182 if ((PortData
== WPCN381U_CHIP_ID
) || (PortData
== WDCP376_CHIP_ID
)) {
1183 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_ENABLE
;
1184 mGlobalNvsArea
.Area
->OnboardCom
= GLOBAL_NVS_DEVICE_ENABLE
;
1185 mGlobalNvsArea
.Area
->OnboardComCir
= GLOBAL_NVS_DEVICE_DISABLE
;
1193 // Get Ps2 policy to set. Will be use if present.
1195 Status
= gBS
->LocateProtocol (
1196 &gEfiPs2PolicyProtocolGuid
,
1200 if (!EFI_ERROR (Status
)) {
1201 Status
= Ps2Policy
->Ps2InitHardware (ImageHandle
);
1204 mGlobalNvsArea
.Area
->SDIOMode
= mSystemConfiguration
.LpssSdioMode
;
1207 Status
= gBS
->InstallMultipleProtocolInterfaces (
1209 &gEfiGlobalNvsAreaProtocolGuid
,
1215 // Read tables from the storage file.
1217 while (!EFI_ERROR (Status
)) {
1218 CurrentTable
= NULL
;
1220 Status
= FwVol
->ReadSection (
1222 &gEfiAcpiTableStorageGuid
,
1225 (VOID
**) &CurrentTable
,
1230 if (!EFI_ERROR (Status
)) {
1232 // Allow platform specific code to reject the table or update it.
1234 AcpiStatus
= AcpiPlatformHooksIsActiveTable (CurrentTable
);
1236 if (!EFI_ERROR (AcpiStatus
)) {
1238 // Perform any table specific updates.
1240 AcpiStatus
= PlatformUpdateTables (CurrentTable
);
1241 if (!EFI_ERROR (AcpiStatus
)) {
1246 AcpiStatus
= AcpiSupport
->SetAcpiTable (
1253 ASSERT_EFI_ERROR (AcpiStatus
);
1258 // Increment the instance.
1264 Status
= EfiCreateEventReadyToBootEx (
1284 IoWrite8(0x72, Index
);
1285 Data
= IoRead8 (0x73);
1290 WriteCmosBank1Byte (
1295 IoWrite8 (0x72, Index
);
1296 IoWrite8 (0x73, Data
);
1302 SettingI2CTouchAddress (
1306 if (mSystemConfiguration
.I2CTouchAd
== 0) {
1308 // If setup menu select auto set I2C Touch Address base on board id.
1310 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP
||
1311 mPlatformInfo
->BoardId
== BOARD_ID_BL_STHI
||
1312 mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP_DDR3L
) {
1316 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4B;
1317 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
) {
1321 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1322 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BB_RVP
) {
1323 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1324 } else if (mPlatformInfo
->BoardId
== BOARD_ID_CVH
) {
1325 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1326 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
1330 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1333 mGlobalNvsArea
.Area
->I2CTouchAddress
= mSystemConfiguration
.I2CTouchAd
;
1335 DEBUG((EFI_D_ERROR
, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea
.Area
->I2CTouchAddress
));