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
;
71 #pragma optimize("", off)
74 EFI_PLATFORM_INFO_HOB
*mPlatformInfo
;
75 EFI_GUID mSystemConfigurationGuid
= SYSTEM_CONFIGURATION_GUID
;
76 SYSTEM_CONFIGURATION mSystemConfiguration
;
77 SYSTEM_CONFIGURATION mSystemConfig
;
79 UINT8 mSmbusRsvdAddresses
[] = PLATFORM_SMBUS_RSVD_ADDRESSES
;
80 UINT8 mNumberSmbusAddress
= sizeof( mSmbusRsvdAddresses
) / sizeof( mSmbusRsvdAddresses
[0] );
83 Locate the first instance of a protocol. If the protocol requested is an
84 FV protocol, then it will return the first FV that contains the ACPI table
87 @param[in] Protocol The protocol to find.
88 @param[in] Instance Return pointer to the first instance of the protocol.
89 @param[in] Type The type of protocol to locate.
91 @retval EFI_SUCCESS The function completed successfully.
92 @retval EFI_NOT_FOUND The protocol could not be located.
93 @retval EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
97 LocateSupportProtocol (
98 IN EFI_GUID
*Protocol
,
104 EFI_HANDLE
*HandleBuffer
;
105 UINTN NumberOfHandles
;
106 EFI_FV_FILETYPE FileType
;
108 EFI_FV_FILE_ATTRIBUTES Attributes
;
117 Status
= gBS
->LocateHandleBuffer (
124 if (EFI_ERROR (Status
)) {
126 // Defined errors at this time are not found and out of resources.
132 // Looking for FV with ACPI storage file.
134 for (Index
= 0; Index
< NumberOfHandles
; Index
++) {
136 // Get the protocol on this handle.
137 // This should not fail because of LocateHandleBuffer.
139 Status
= gBS
->HandleProtocol (
144 ASSERT (!EFI_ERROR (Status
));
148 // Not looking for the FV protocol, so find the first instance of the
149 // protocol. There should not be any errors because our handle buffer
150 // should always contain at least one or LocateHandleBuffer would have
151 // returned not found.
157 // See if it has the ACPI storage file.
159 Status
= ((EFI_FIRMWARE_VOLUME_PROTOCOL
*) (*Instance
))->ReadFile (
161 &gEfiAcpiTableStorageGuid
,
170 // If we found it, then we are done.
172 if (!EFI_ERROR (Status
)) {
178 // Our exit status is determined by the success of the previous operations.
179 // If the protocol was found, Instance already points to it.
182 // Free any allocated buffers.
184 gBS
->FreePool (HandleBuffer
);
190 This function will update any runtime platform specific information.
191 This currently includes:
192 Setting OEM table values, ID, table ID, creator ID and creator revision.
193 Enabling the proper processor entries in the APIC tables.
195 @param[in] Table The table to update.
197 @retval EFI_SUCCESS The function completed successfully.
201 PlatformUpdateTables (
202 IN OUT EFI_ACPI_COMMON_HEADER
*Table
205 EFI_ACPI_DESCRIPTION_HEADER
*TableHeader
;
208 ACPI_APIC_STRUCTURE_PTR
*ApicPtr
;
211 EFI_MP_SERVICES_PROTOCOL
*MpService
;
212 UINTN MaximumNumberOfCPUs
;
213 UINTN NumberOfEnabledCPUs
;
215 EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*AsfEntry
;
216 EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*HpetTbl
;
219 EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*Facp
;
220 EFI_ACPI_OSFR_TABLE
*OsfrTable
;
221 EFI_ACPI_OSFR_OCUR_OBJECT
*pOcurObject
;
222 EFI_ACPI_OSFR_OCUR_OBJECT OcurObject
= {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};
223 CHAR16
*OcurMfgStringBuffer
= NULL
;
224 CHAR16
*OcurModelStringBuffer
= NULL
;
225 UINT8
*OcurRefDataBlockBuffer
= NULL
;
226 UINTN OcurMfgStringBufferSize
;
227 UINTN OcurModelStringBufferSize
;
228 UINTN OcurRefDataBlockBufferSize
;
229 #if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED
230 EFI_ACPI_ASPT_TABLE
*pSpttTable
;
232 UINT16 NumberOfHpets
;
233 UINT16 HpetCapIdValue
;
235 EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer
;
237 EFI_ACPI_3_0_IO_APIC_STRUCTURE
*IOApicType
;
238 EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*APICTableHeader
;
239 EFI_ACPI_WSMT_TABLE
*WsmtTable
;
247 if (Table
->Signature
!= EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE
) {
248 TableHeader
= (EFI_ACPI_DESCRIPTION_HEADER
*) Table
;
252 OemIdValue
= mPlatformInfo
->AcpiOemId
;
254 *(UINT32
*)(TableHeader
->OemId
) = (UINT32
)OemIdValue
;
255 *(UINT16
*)(TableHeader
->OemId
+ 4) = *(UINT16
*)(((UINT8
*)&OemIdValue
) + 4);
257 if ((Table
->Signature
!= EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
)) {
259 // Update the OEM Table ID.
261 TableHeader
->OemTableId
= mPlatformInfo
->AcpiOemTableId
;
265 // Update the OEM Table ID.
267 TableHeader
->OemRevision
= EFI_ACPI_OEM_REVISION
;
270 // Update the creator ID.
272 TableHeader
->CreatorId
= EFI_ACPI_CREATOR_ID
;
275 // Update the creator revision.
277 TableHeader
->CreatorRevision
= EFI_ACPI_CREATOR_REVISION
;
281 // Complete this function.
284 // Locate the MP services protocol.
287 // Find the MP Protocol. This is an MP platform, so MP protocol must be
290 Status
= gBS
->LocateProtocol (
291 &gEfiMpServiceProtocolGuid
,
295 if (EFI_ERROR (Status
)) {
300 // Determine the number of processors.
302 MpService
->GetNumberOfProcessors (
304 &MaximumNumberOfCPUs
,
308 ASSERT (MaximumNumberOfCPUs
<= MAX_CPU_NUM
&& NumberOfEnabledCPUs
>= 1);
312 // Assign a invalid intial value for update.
315 // Update the processors in the APIC table.
317 switch (Table
->Signature
) {
318 case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE
:
320 // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
322 if (mSystemConfig
.Asf
== 1) {
323 return EFI_UNSUPPORTED
;
325 AsfEntry
= (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE
*) Table
;
326 TempVal
= (mNumberSmbusAddress
< ASF_ADDR_DEVICE_ARRAY_LENGTH
)? mNumberSmbusAddress
: ASF_ADDR_DEVICE_ARRAY_LENGTH
;
327 for (Index
= 0; Index
< TempVal
; Index
++) {
328 AsfEntry
->AsfAddr
.FixedSmbusAddresses
[Index
] = mSmbusRsvdAddresses
[Index
];
332 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE
:
334 Status
= MpService
->WhoAmI (
340 // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
342 APICTableHeader
= (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER
*)Table
;
343 APICTableHeader
->Flags
|= EFI_ACPI_3_0_PCAT_COMPAT
;
345 CurrPtr
= (UINT8
*) &((EFI_ACPI_DESCRIPTION_HEADER
*) Table
)[1];
346 CurrPtr
= CurrPtr
+ 8;
349 // Size of Local APIC Address & Flag.
351 EndPtr
= (UINT8
*) Table
;
352 EndPtr
= EndPtr
+ Table
->Length
;
353 while (CurrPtr
< EndPtr
) {
354 ApicPtr
= (ACPI_APIC_STRUCTURE_PTR
*) CurrPtr
;
355 switch (ApicPtr
->AcpiApicCommon
.Type
) {
356 case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC
:
359 // Fix for Ordering of MADT to be maintained as it is in MADT table.
361 // Update processor enabled or disabled and keep the local APIC
362 // order in MADT intact.
364 // Sanity check to make sure proc-id is not arbitrary.
366 DEBUG ((EFI_D_ERROR
, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \
367 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
, MaximumNumberOfCPUs
));
368 if(ApicPtr
->AcpiLocalApic
.AcpiProcessorId
> MaximumNumberOfCPUs
) {
369 ApicPtr
->AcpiLocalApic
.AcpiProcessorId
= (UINT8
)MaximumNumberOfCPUs
;
372 ApicPtr
->AcpiLocalApic
.Flags
= 0;
374 for (CurrProcessor
= 0; CurrProcessor
< MaximumNumberOfCPUs
; CurrProcessor
++) {
375 Status
= MpService
->GetProcessorInfo (
381 if (Status
== EFI_SUCCESS
&& ProcessorInfoBuffer
.ProcessorId
== ApicPtr
->AcpiLocalApic
.ApicId
) {
383 // Check to see whether or not a processor (or thread) is enabled.
385 if ((BspIndex
== CurrProcessor
) || ((ProcessorInfoBuffer
.StatusFlag
& PROCESSOR_ENABLED_BIT
) != 0)) {
387 // Go on and check if Hyper Threading is enabled. If HT not enabled
388 // hide this thread from OS by not setting the flag to 1. This is the
389 // software way to disable Hyper Threading. Basically we just hide it
392 ApicPtr
->AcpiLocalApic
.Flags
= EFI_ACPI_1_0_LOCAL_APIC_ENABLED
;
395 if(ProcessorInfoBuffer
.Location
.Thread
!= 0) {
396 ApicPtr
->AcpiLocalApic
.Flags
= 0;
399 AppendCpuMapTableEntry (&(ApicPtr
->AcpiLocalApic
));
406 // If no APIC-ID match, the cpu may not be populated.
410 case EFI_ACPI_3_0_IO_APIC
:
412 IOApicType
= (EFI_ACPI_3_0_IO_APIC_STRUCTURE
*)CurrPtr
;
413 IOApicType
->IoApicId
= 0x02;
415 // IO APIC entries can be patched here.
420 CurrPtr
= CurrPtr
+ ApicPtr
->AcpiApicCommon
.Length
;
424 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
:
426 Facp
= (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE
*) Table
;
427 Facp
->Flags
&= (UINT32
)(~(3<<2));
431 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
433 // Patch the memory resource.
435 PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER
*) Table
);
438 case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
:
442 // TBD: Need re-design based on the ValleyTrail platform.
446 case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE
:
448 // Adjust HPET Table to correct the Base Address.
450 // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
452 MmioOr8 (R_PCH_PCH_HPET
+ R_PCH_PCH_HPET_GCFG
, B_PCH_PCH_HPET_GCFG_EN
);
455 HpetTbl
= (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER
*) Table
;
456 HpetTbl
->BaseAddressLower32Bit
.Address
= HPET_BASE_ADDRESS
;
457 HpetTbl
->EventTimerBlockId
= *((UINT32
*)(UINTN
)HPET_BASE_ADDRESS
);
459 HpetCapIdValue
= *(UINT16
*)(UINTN
)(HPET_BASE_ADDRESS
);
460 NumberOfHpets
= HpetCapIdValue
& B_PCH_PCH_HPET_GCID_NT
; // Bits [8:12] contains the number of Hpets
461 HpetBlockID
= EFI_ACPI_EVENT_TIMER_BLOCK_ID
;
463 if((NumberOfHpets
) && (NumberOfHpets
& B_PCH_PCH_HPET_GCID_NT
)) {
464 HpetBlockID
|= (NumberOfHpets
);
466 HpetTbl
->EventTimerBlockId
= HpetBlockID
;
470 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
:
472 // Update MCFG base and end bus number.
474 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].BaseAddress
475 = mPlatformInfo
->PciData
.PciExpressBase
;
476 ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE
*) Table
)->Segment
[0].EndBusNumber
477 = (UINT8
)RShiftU64 (mPlatformInfo
->PciData
.PciExpressSize
, 20) - 1;
481 case EFI_ACPI_OSFR_TABLE_SIGNATURE
:
483 // Get size of OSFR variable.
485 OcurMfgStringBufferSize
= 0;
486 Status
= gRT
->GetVariable (
487 gACPIOSFRMfgStringVariableName
,
488 &gACPIOSFRMfgStringVariableGuid
,
490 &OcurMfgStringBufferSize
,
493 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
495 // Variable must not be present on the system.
497 return EFI_UNSUPPORTED
;
501 // Allocate memory for variable data.
503 OcurMfgStringBuffer
= AllocatePool (OcurMfgStringBufferSize
);
504 Status
= gRT
->GetVariable (
505 gACPIOSFRMfgStringVariableName
,
506 &gACPIOSFRMfgStringVariableGuid
,
508 &OcurMfgStringBufferSize
,
511 if (!EFI_ERROR (Status
)) {
512 OcurModelStringBufferSize
= 0;
513 Status
= gRT
->GetVariable (
514 gACPIOSFRModelStringVariableName
,
515 &gACPIOSFRModelStringVariableGuid
,
517 &OcurModelStringBufferSize
,
520 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
522 // Variable must not be present on the system.
524 return EFI_UNSUPPORTED
;
528 // Allocate memory for variable data.
530 OcurModelStringBuffer
= AllocatePool (OcurModelStringBufferSize
);
531 Status
= gRT
->GetVariable (
532 gACPIOSFRModelStringVariableName
,
533 &gACPIOSFRModelStringVariableGuid
,
535 &OcurModelStringBufferSize
,
536 OcurModelStringBuffer
538 if (!EFI_ERROR (Status
)) {
539 OcurRefDataBlockBufferSize
= 0;
540 Status
= gRT
->GetVariable (
541 gACPIOSFRRefDataBlockVariableName
,
542 &gACPIOSFRRefDataBlockVariableGuid
,
544 &OcurRefDataBlockBufferSize
,
547 if (Status
== EFI_BUFFER_TOO_SMALL
) {
549 // Allocate memory for variable data.
551 OcurRefDataBlockBuffer
= AllocatePool (OcurRefDataBlockBufferSize
);
552 Status
= gRT
->GetVariable (
553 gACPIOSFRRefDataBlockVariableName
,
554 &gACPIOSFRRefDataBlockVariableGuid
,
556 &OcurRefDataBlockBufferSize
,
557 OcurRefDataBlockBuffer
560 OsfrTable
= (EFI_ACPI_OSFR_TABLE
*) Table
;
562 // Currently only one object is defined: OCUR_OSFR_TABLE.
564 OsfrTable
->ObjectCount
= 1;
566 // Initialize table length to fixed portion of the ACPI OSFR table.
568 OsfrTable
->Header
.Length
= sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
);
569 *(UINT32
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
)) = \
570 (UINT32
) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + sizeof (UINT32
));
571 pOcurObject
= (EFI_ACPI_OSFR_OCUR_OBJECT
*)((UINTN
) OsfrTable
+ sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION
) + \
573 CopyMem (pOcurObject
, &OcurObject
, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
574 pOcurObject
->ManufacturerNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
575 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
));
576 pOcurObject
->ModelNameStringOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
577 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
);
578 if (OcurRefDataBlockBufferSize
> 0) {
579 pOcurObject
->MicrosoftReferenceOffset
= (UINT32
)((UINTN
) pOcurObject
- (UINTN
) OsfrTable
+ \
580 sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ OcurModelStringBufferSize
);
582 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
)), OcurMfgStringBuffer
, \
583 OcurMfgStringBufferSize
);
584 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
), \
585 OcurModelStringBuffer
, OcurModelStringBufferSize
);
586 if (OcurRefDataBlockBufferSize
> 0) {
587 CopyMem ((UINTN
*)((UINTN
) pOcurObject
+ sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + OcurMfgStringBufferSize
+ \
588 OcurModelStringBufferSize
),OcurRefDataBlockBuffer
, OcurRefDataBlockBufferSize
);
590 OsfrTable
->Header
.Length
+= (UINT32
)(OcurMfgStringBufferSize
+ OcurModelStringBufferSize
+ OcurRefDataBlockBufferSize
);
591 OsfrTable
->Header
.Length
+= sizeof (EFI_ACPI_OSFR_OCUR_OBJECT
) + sizeof (UINT32
);
594 gBS
->FreePool (OcurMfgStringBuffer
);
595 gBS
->FreePool (OcurModelStringBuffer
);
596 gBS
->FreePool (OcurRefDataBlockBuffer
);
600 case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE
:
601 WsmtTable
= (EFI_ACPI_WSMT_TABLE
*) Table
;
603 // Update Microsoft WSMT table Protections flags.
605 WsmtTable
->ProtectionFlags
= ((WsmtTable
->ProtectionFlags
) | (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS
| EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION
));
615 // Update the hardware signature in the FACS structure.
618 // Locate the SPCR table and update based on current settings.
619 // The user may change CR settings via setup or other methods.
620 // The SPCR table must match.
629 GC_TODO: Add function description.
633 Event - GC_TODO: add argument description
634 Context - GC_TODO: add argument description
638 GC_TODO: add return values
650 EFI_ACPI_TABLE_VERSION TableVersion
;
651 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
652 EFI_ACPI_S3_SAVE_PROTOCOL
*AcpiS3Save
;
653 SYSTEM_CONFIGURATION SetupVarBuffer
;
655 EFI_PLATFORM_CPU_INFO
*PlatformCpuInfoPtr
= NULL
;
656 EFI_PLATFORM_CPU_INFO PlatformCpuInfo
;
657 EFI_PEI_HOB_POINTERS GuidHob
;
666 // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
668 PlatformCpuInfo
.CpuVersion
.FullCpuId
= 0;
671 // Get Platform CPU Info HOB.
673 PlatformCpuInfoPtr
= NULL
;
674 ZeroMem (&PlatformCpuInfo
, sizeof(EFI_PLATFORM_CPU_INFO
));
675 VariableSize
= sizeof(EFI_PLATFORM_CPU_INFO
);
676 Status
= gRT
->GetVariable(
677 EfiPlatformCpuInfoVariable
,
678 &gEfiVlv2VariableGuid
,
683 if (EFI_ERROR(Status
)) {
684 GuidHob
.Raw
= GetHobList ();
685 if (GuidHob
.Raw
!= NULL
) {
686 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformCpuInfoGuid
, GuidHob
.Raw
)) != NULL
) {
687 PlatformCpuInfoPtr
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
692 if ((PlatformCpuInfoPtr
!= NULL
)) {
693 CopyMem(&PlatformCpuInfo
, PlatformCpuInfoPtr
, sizeof(EFI_PLATFORM_CPU_INFO
));
697 // Update the ACPI parameter blocks finally.
699 VariableSize
= sizeof (SYSTEM_CONFIGURATION
);
700 Status
= gRT
->GetVariable (
702 &mSystemConfigurationGuid
,
707 if (EFI_ERROR (Status
) || VariableSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
708 //The setup variable is corrupted
709 VariableSize
= sizeof(SYSTEM_CONFIGURATION
);
710 Status
= gRT
->GetVariable(
712 &mSystemConfigurationGuid
,
717 ASSERT_EFI_ERROR (Status
);
721 // Find the AcpiSupport protocol.
723 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
724 ASSERT_EFI_ERROR (Status
);
726 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
729 // Publish ACPI 1.0 or 2.0 Tables.
731 Status
= AcpiSupport
->PublishTables (
735 ASSERT_EFI_ERROR (Status
);
740 Status
= gBS
->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid
, NULL
, (VOID
**) &AcpiS3Save
);
741 if (!EFI_ERROR (Status
)) {
742 AcpiS3Save
->S3Save (AcpiS3Save
, NULL
);
755 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
&& mPlatformInfo
->BoardRev
>= PR1
) {
756 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD PR1\n"));
757 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
759 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
760 DEBUG((EFI_D_ERROR
, "Set FSA status = 1 for FFRD8\n"));
761 mGlobalNvsArea
.Area
->FsaStatus
= mSystemConfiguration
.PchFSAOn
;
767 Entry point for Acpi platform driver.
769 @param[in] ImageHandle A handle for the image that is initializing this driver.
770 @param[in] SystemTable A pointer to the EFI system table.
772 @retval EFI_SUCCESS Driver initialized successfully.
773 @retval EFI_LOAD_ERROR Failed to Initialize or has been loaded.
774 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
779 AcpiPlatformEntryPoint (
780 IN EFI_HANDLE ImageHandle
,
781 IN EFI_SYSTEM_TABLE
*SystemTable
785 EFI_STATUS AcpiStatus
;
786 EFI_ACPI_SUPPORT_PROTOCOL
*AcpiSupport
;
787 EFI_FIRMWARE_VOLUME_PROTOCOL
*FwVol
;
789 EFI_ACPI_COMMON_HEADER
*CurrentTable
;
794 EFI_ACPI_TABLE_VERSION TableVersion
;
798 EFI_PS2_POLICY_PROTOCOL
*Ps2Policy
;
799 EFI_PEI_HOB_POINTERS GuidHob
;
801 EFI_MP_SERVICES_PROTOCOL
*MpService
;
802 UINTN MaximumNumberOfCPUs
;
803 UINTN NumberOfEnabledCPUs
;
804 PCH_STEPPING pchStepping
;
806 mFirstNotify
= FALSE
;
808 TableVersion
= EFI_ACPI_TABLE_VERSION_2_0
;
814 // Update HOB variable for PCI resource information.
815 // Get the HOB list. If it is not present, then ASSERT.
817 GuidHob
.Raw
= GetHobList ();
818 if (GuidHob
.Raw
!= NULL
) {
819 if ((GuidHob
.Raw
= GetNextGuidHob (&gEfiPlatformInfoGuid
, GuidHob
.Raw
)) != NULL
) {
820 mPlatformInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
825 // Search for the Memory Configuration GUID HOB. If it is not present, then
826 // there's nothing we can do. It may not exist on the update path.
828 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
829 Status
= gRT
->GetVariable(
831 &mSystemConfigurationGuid
,
834 &mSystemConfiguration
836 if (EFI_ERROR (Status
) || VarSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
837 //The setup variable is corrupted
838 VarSize
= sizeof(SYSTEM_CONFIGURATION
);
839 Status
= gRT
->GetVariable(
841 &mSystemConfigurationGuid
,
844 &mSystemConfiguration
846 ASSERT_EFI_ERROR (Status
);
850 // Find the AcpiSupport protocol.
852 Status
= LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid
, (VOID
**) &AcpiSupport
, 0);
853 ASSERT_EFI_ERROR (Status
);
856 // Locate the firmware volume protocol.
858 Status
= LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid
, (VOID
**) &FwVol
, 1);
859 ASSERT_EFI_ERROR (Status
);
862 // Read the current system configuration variable store.
864 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
865 Status
= gRT
->GetVariable (
867 &gEfiNormalSetupGuid
,
872 if (EFI_ERROR (Status
) || SysCfgSize
!= sizeof(SYSTEM_CONFIGURATION
)) {
873 //The setup variable is corrupted
874 SysCfgSize
= sizeof(SYSTEM_CONFIGURATION
);
875 Status
= gRT
->GetVariable(
877 &gEfiNormalSetupGuid
,
882 ASSERT_EFI_ERROR (Status
);
886 Status
= EFI_SUCCESS
;
890 // TBD: Need re-design based on the ValleyTrail platform.
892 Status
= gBS
->LocateProtocol (
893 &gEfiMpServiceProtocolGuid
,
897 if (EFI_ERROR (Status
)) {
902 // Determine the number of processors.
904 MpService
->GetNumberOfProcessors (
906 &MaximumNumberOfCPUs
,
911 // Allocate and initialize the NVS area for SMM and ASL communication.
913 Status
= gBS
->AllocatePool (
915 sizeof (EFI_GLOBAL_NVS_AREA
),
916 (void **)&mGlobalNvsArea
.Area
918 ASSERT_EFI_ERROR (Status
);
921 sizeof (EFI_GLOBAL_NVS_AREA
),
924 DEBUG((EFI_D_ERROR
, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea
.Area
));
927 // Update global NVS area for ASL and SMM init code to use.
929 mGlobalNvsArea
.Area
->ApicEnable
= 1;
930 mGlobalNvsArea
.Area
->EmaEnable
= 0;
932 mGlobalNvsArea
.Area
->NumberOfBatteries
= 1;
933 mGlobalNvsArea
.Area
->BatteryCapacity0
= 100;
934 mGlobalNvsArea
.Area
->BatteryStatus0
= 84;
935 mGlobalNvsArea
.Area
->OnboardCom
= 1;
936 mGlobalNvsArea
.Area
->IdeMode
= 0;
937 mGlobalNvsArea
.Area
->PowerState
= 0;
939 mGlobalNvsArea
.Area
->LogicalProcessorCount
= (UINT8
)NumberOfEnabledCPUs
;
941 mGlobalNvsArea
.Area
->PassiveThermalTripPoint
= mSystemConfiguration
.PassiveThermalTripPoint
;
942 mGlobalNvsArea
.Area
->PassiveTc1Value
= mSystemConfiguration
.PassiveTc1Value
;
943 mGlobalNvsArea
.Area
->PassiveTc2Value
= mSystemConfiguration
.PassiveTc2Value
;
944 mGlobalNvsArea
.Area
->PassiveTspValue
= mSystemConfiguration
.PassiveTspValue
;
945 mGlobalNvsArea
.Area
->CriticalThermalTripPoint
= mSystemConfiguration
.CriticalThermalTripPoint
;
947 mGlobalNvsArea
.Area
->IgdPanelType
= mSystemConfiguration
.IgdFlatPanel
;
948 mGlobalNvsArea
.Area
->IgdPanelScaling
= mSystemConfiguration
.PanelScaling
;
949 mGlobalNvsArea
.Area
->IgdSciSmiMode
= 0;
950 mGlobalNvsArea
.Area
->IgdTvFormat
= 0;
951 mGlobalNvsArea
.Area
->IgdTvMinor
= 0;
952 mGlobalNvsArea
.Area
->IgdSscConfig
= 1;
953 mGlobalNvsArea
.Area
->IgdBiaConfig
= mSystemConfiguration
.IgdLcdIBia
;
954 mGlobalNvsArea
.Area
->IgdBlcConfig
= mSystemConfiguration
.IgdLcdIGmchBlc
;
955 mGlobalNvsArea
.Area
->IgdDvmtMemSize
= mSystemConfiguration
.IgdDvmt50TotalAlloc
;
956 mGlobalNvsArea
.Area
->IgdPAVP
= mSystemConfiguration
.PavpMode
;
958 mGlobalNvsArea
.Area
->AlsEnable
= mSystemConfiguration
.AlsEnable
;
959 mGlobalNvsArea
.Area
->BacklightControlSupport
= 2;
960 mGlobalNvsArea
.Area
->BrightnessPercentage
= 100;
961 mGlobalNvsArea
.Area
->IgdState
= 1;
962 mGlobalNvsArea
.Area
->LidState
= 1;
964 mGlobalNvsArea
.Area
->DeviceId1
= 0x80000100 ;
965 mGlobalNvsArea
.Area
->DeviceId2
= 0x80000400 ;
966 mGlobalNvsArea
.Area
->DeviceId3
= 0x80000200 ;
967 mGlobalNvsArea
.Area
->DeviceId4
= 0x04;
968 mGlobalNvsArea
.Area
->DeviceId5
= 0x05;
969 mGlobalNvsArea
.Area
->NumberOfValidDeviceId
= 4 ;
970 mGlobalNvsArea
.Area
->CurrentDeviceList
= 0x0F ;
971 mGlobalNvsArea
.Area
->PreviousDeviceList
= 0x0F ;
973 mGlobalNvsArea
.Area
->UartSelection
= mSystemConfiguration
.UartInterface
;
974 mGlobalNvsArea
.Area
->PcuUart1Enable
= mSystemConfiguration
.PcuUart1
;
975 mGlobalNvsArea
.Area
->NativePCIESupport
= 1;
976 mGlobalNvsArea
.Area
->RtcBattery
= mSystemConfiguration
.RtcBattery
;
983 // Update BootMode: 0:ACPI mode; 1:PCI mode
985 mGlobalNvsArea
.Area
->LpssSccMode
= mSystemConfiguration
.LpssPciModeEnabled
;
986 if (mSystemConfiguration
.LpssMipiHsi
== 0) {
987 mGlobalNvsArea
.Area
->MipiHsiAddr
= 0;
988 mGlobalNvsArea
.Area
->MipiHsiLen
= 0;
989 mGlobalNvsArea
.Area
->MipiHsi1Addr
= 0;
990 mGlobalNvsArea
.Area
->MipiHsi1Len
= 0;
996 mGlobalNvsArea
.Area
->PlatformFlavor
= mPlatformInfo
->PlatformFlavor
;
999 // Update the Platform id
1001 mGlobalNvsArea
.Area
->BoardID
= mPlatformInfo
->BoardId
;
1004 // Update the Board Revision
1006 mGlobalNvsArea
.Area
->FabID
= mPlatformInfo
->BoardRev
;
1009 // Update SOC Stepping
1011 mGlobalNvsArea
.Area
->SocStepping
= (UINT8
)(PchStepping());
1013 mGlobalNvsArea
.Area
->OtgMode
= mSystemConfiguration
.PchUsbOtg
;
1015 pchStepping
= PchStepping();
1016 if (mSystemConfiguration
.UsbAutoMode
== 1) {
1018 // Auto mode is enabled.
1020 if (PchA0
== pchStepping
) {
1022 // For A0, EHCI is enabled as default.
1024 mSystemConfiguration
.PchUsb20
= 1;
1025 mSystemConfiguration
.PchUsb30Mode
= 0;
1026 mSystemConfiguration
.UsbXhciSupport
= 0;
1027 DEBUG ((EFI_D_INFO
, "EHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1030 // For A1 and later, XHCI is enabled as default.
1032 mSystemConfiguration
.PchUsb20
= 0;
1033 mSystemConfiguration
.PchUsb30Mode
= 1;
1034 mSystemConfiguration
.UsbXhciSupport
= 1;
1035 DEBUG ((EFI_D_INFO
, "XHCI is enabled as default. SOC 0x%x\n", pchStepping
));
1039 mGlobalNvsArea
.Area
->XhciMode
= mSystemConfiguration
.PchUsb30Mode
;
1041 mGlobalNvsArea
.Area
->Stepping
= mPlatformInfo
->IchRevision
;
1044 // Override invalid Pre-Boot Driver and XhciMode combination.
1046 if ((mSystemConfiguration
.UsbXhciSupport
== 0) && (mSystemConfiguration
.PchUsb30Mode
== 3)) {
1047 mGlobalNvsArea
.Area
->XhciMode
= 2;
1049 if ((mSystemConfiguration
.UsbXhciSupport
== 1) && (mSystemConfiguration
.PchUsb30Mode
== 2)) {
1050 mGlobalNvsArea
.Area
->XhciMode
= 3;
1053 DEBUG ((EFI_D_ERROR
, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea
.Area
->XhciMode
));
1055 mGlobalNvsArea
.Area
->PmicEnable
= GLOBAL_NVS_DEVICE_DISABLE
;
1056 mGlobalNvsArea
.Area
->BatteryChargingSolution
= GLOBAL_NVS_DEVICE_DISABLE
;
1057 mGlobalNvsArea
.Area
->ISPDevSel
= mSystemConfiguration
.ISPDevSel
;
1058 mGlobalNvsArea
.Area
->LpeEnable
= mSystemConfiguration
.Lpe
;
1059 mGlobalNvsArea
.Area
->LpeAudioReportedByDSDT
= mSystemConfiguration
.LpeAudioReportedByDSDT
;
1061 if (mSystemConfiguration
.ISPEn
== 0) {
1062 mGlobalNvsArea
.Area
->ISPDevSel
= GLOBAL_NVS_DEVICE_DISABLE
;
1065 mGlobalNvsArea
.Area
->WittEnable
= mSystemConfiguration
.WittEnable
;
1066 mGlobalNvsArea
.Area
->UtsEnable
= mSystemConfiguration
.UtsEnable
;
1067 mGlobalNvsArea
.Area
->SarEnable
= mSystemConfiguration
.SAR1
;
1070 mGlobalNvsArea
.Area
->ReservedO
= 1;
1072 SettingI2CTouchAddress();
1073 mGlobalNvsArea
.Area
->IdleReserve
= mSystemConfiguration
.IdleReserve
;
1075 // Read BMBOUND and store it in GlobalNVS to pass into ASL.
1077 // BUGBUG: code was moved into silicon reference code.
1079 if (mSystemConfiguration
.eMMCBootMode
== 1) {
1081 // Auto detect mode.
1083 DEBUG ((EFI_D_ERROR
, "Auto detect mode------------start\n"));
1086 // Silicon Steppings.
1088 switch (PchStepping()) {
1089 case PchA0
: // A0/A1
1091 DEBUG ((EFI_D_ERROR
, "SOC A0/A1: eMMC 4.41 Configuration\n"));
1092 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1093 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1096 case PchB0
: // B0 and later.
1098 DEBUG ((EFI_D_ERROR
, "SOC B0 and later: eMMC 4.5 Configuration\n"));
1099 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1100 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1103 } else if (mSystemConfiguration
.eMMCBootMode
== 2) {
1107 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.41 Configuration\n"));
1108 mSystemConfiguration
.LpsseMMCEnabled
= 1;
1109 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1110 } else if (mSystemConfiguration
.eMMCBootMode
== 3) {
1114 DEBUG ((EFI_D_ERROR
, "Force to eMMC 4.5 Configuration\n"));
1115 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1116 mSystemConfiguration
.LpsseMMC45Enabled
= 1;
1120 // Disable eMMC controllers.
1122 DEBUG ((EFI_D_ERROR
, "Disable eMMC controllers\n"));
1123 mSystemConfiguration
.LpsseMMCEnabled
= 0;
1124 mSystemConfiguration
.LpsseMMC45Enabled
= 0;
1127 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1128 if (mSystemConfiguration
.LpsseMMCEnabled
) {
1129 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
1130 mGlobalNvsArea
.Area
->emmcVersion
= 0;
1133 if (mSystemConfiguration
.LpsseMMC45Enabled
) {
1134 DEBUG ((EFI_D_ERROR
, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
1135 mGlobalNvsArea
.Area
->emmcVersion
= 1;
1138 mGlobalNvsArea
.Area
->SdCardRemovable
= mSystemConfiguration
.SdCardRemovable
;
1143 if ((mSystemConfiguration
.LpssHsuart0FlowControlEnabled
== 1) && \
1144 (mSystemConfiguration
.LpssPwm0Enabled
== 0) && \
1145 (mSystemConfiguration
.LpssPwm1Enabled
== 0)) {
1146 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_ENABLE
;
1147 DEBUG ((EFI_D_ERROR
, "JP1 is set to be MSFT IOT configuration.\n"));
1149 mGlobalNvsArea
.Area
->MicrosoftIoT
= GLOBAL_NVS_DEVICE_DISABLE
;
1150 DEBUG ((EFI_D_ERROR
, "JP1 is not set to be MSFT IOT configuration.\n"));
1154 // SIO related option.
1156 Status
= gBS
->LocateProtocol (&gEfiCpuIoProtocolGuid
, NULL
, (void **)&mCpuIo
);
1157 ASSERT_EFI_ERROR (Status
);
1159 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_DISABLE
;
1161 mGlobalNvsArea
.Area
->DockedSioPresent
= GLOBAL_NVS_DEVICE_DISABLE
;
1163 if (mGlobalNvsArea
.Area
->DockedSioPresent
!= GLOBAL_NVS_DEVICE_ENABLE
) {
1165 // Check ID for SIO WPCN381U.
1167 Status
= mCpuIo
->Io
.Read (
1170 WPCN381U_CONFIG_INDEX
,
1174 ASSERT_EFI_ERROR (Status
);
1175 if (PortData
!= 0xFF) {
1177 Status
= mCpuIo
->Io
.Write (
1180 WPCN381U_CONFIG_INDEX
,
1184 ASSERT_EFI_ERROR (Status
);
1185 Status
= mCpuIo
->Io
.Read (
1188 WPCN381U_CONFIG_DATA
,
1192 ASSERT_EFI_ERROR (Status
);
1193 if ((PortData
== WPCN381U_CHIP_ID
) || (PortData
== WDCP376_CHIP_ID
)) {
1194 mGlobalNvsArea
.Area
->WPCN381U
= GLOBAL_NVS_DEVICE_ENABLE
;
1195 mGlobalNvsArea
.Area
->OnboardCom
= GLOBAL_NVS_DEVICE_ENABLE
;
1196 mGlobalNvsArea
.Area
->OnboardComCir
= GLOBAL_NVS_DEVICE_DISABLE
;
1204 // Get Ps2 policy to set. Will be use if present.
1206 Status
= gBS
->LocateProtocol (
1207 &gEfiPs2PolicyProtocolGuid
,
1211 if (!EFI_ERROR (Status
)) {
1212 Status
= Ps2Policy
->Ps2InitHardware (ImageHandle
);
1215 mGlobalNvsArea
.Area
->SDIOMode
= mSystemConfiguration
.LpssSdioMode
;
1218 Status
= gBS
->InstallMultipleProtocolInterfaces (
1220 &gEfiGlobalNvsAreaProtocolGuid
,
1226 // Read tables from the storage file.
1228 while (!EFI_ERROR (Status
)) {
1229 CurrentTable
= NULL
;
1231 Status
= FwVol
->ReadSection (
1233 &gEfiAcpiTableStorageGuid
,
1236 (VOID
**) &CurrentTable
,
1241 if (!EFI_ERROR (Status
)) {
1243 // Allow platform specific code to reject the table or update it.
1245 AcpiStatus
= AcpiPlatformHooksIsActiveTable (CurrentTable
);
1247 if (!EFI_ERROR (AcpiStatus
)) {
1249 // Perform any table specific updates.
1251 AcpiStatus
= PlatformUpdateTables (CurrentTable
);
1252 if (!EFI_ERROR (AcpiStatus
)) {
1257 AcpiStatus
= AcpiSupport
->SetAcpiTable (
1264 ASSERT_EFI_ERROR (AcpiStatus
);
1269 // Increment the instance.
1275 Status
= EfiCreateEventReadyToBootEx (
1295 IoWrite8(0x72, Index
);
1296 Data
= IoRead8 (0x73);
1301 WriteCmosBank1Byte (
1306 IoWrite8 (0x72, Index
);
1307 IoWrite8 (0x73, Data
);
1313 SettingI2CTouchAddress (
1317 if (mSystemConfiguration
.I2CTouchAd
== 0) {
1319 // If setup menu select auto set I2C Touch Address base on board id.
1321 if (mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP
||
1322 mPlatformInfo
->BoardId
== BOARD_ID_BL_STHI
||
1323 mPlatformInfo
->BoardId
== BOARD_ID_BL_RVP_DDR3L
) {
1327 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4B;
1328 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD
) {
1332 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1333 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BB_RVP
) {
1334 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1335 } else if (mPlatformInfo
->BoardId
== BOARD_ID_CVH
) {
1336 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4C;
1337 } else if (mPlatformInfo
->BoardId
== BOARD_ID_BL_FFRD8
) {
1341 mGlobalNvsArea
.Area
->I2CTouchAddress
= 0x4A;
1344 mGlobalNvsArea
.Area
->I2CTouchAddress
= mSystemConfiguration
.I2CTouchAd
;
1346 DEBUG((EFI_D_ERROR
, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea
.Area
->I2CTouchAddress
));