Home | History | Annotate | Download | only in AcpiPlatform
      1 /** @file
      2 
      3   Copyright (c) 2004  - 2016, Intel Corporation. All rights reserved.<BR>
      4 
      5 
      6   This program and the accompanying materials are licensed and made available under
      7 
      8   the terms and conditions of the BSD License that accompanies this distribution.
      9 
     10   The full text of the license may be found at
     11 
     12   http://opensource.org/licenses/bsd-license.php.
     13 
     14 
     15 
     16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17 
     18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     19 
     20 
     21 
     22 
     23 
     24 
     25 Module Name:
     26 
     27   AcpiPlatform.c
     28 
     29 Abstract:
     30 
     31   ACPI Platform Driver
     32 
     33 
     34 **/
     35 
     36 #include <PiDxe.h>
     37 #include <Protocol/TcgService.h>
     38 #include <Protocol/FirmwareVolume.h>
     39 #include "AcpiPlatform.h"
     40 #include "AcpiPlatformHooks.h"
     41 #include "AcpiPlatformHooksLib.h"
     42 #include "Platform.h"
     43 #include <Hpet.h>
     44 #include <Mcfg.h>
     45 #include "Osfr.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>
     62 
     63 
     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;
     68 
     69 EFI_CPU_IO_PROTOCOL                    *mCpuIo;
     70 EFI_GLOBAL_NVS_AREA_PROTOCOL            mGlobalNvsArea;
     71 #ifndef __GNUC__
     72 #pragma optimize("", off)
     73 #endif
     74 BOOLEAN                   mFirstNotify;
     75 EFI_PLATFORM_INFO_HOB     *mPlatformInfo;
     76 EFI_GUID                  mSystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;
     77 SYSTEM_CONFIGURATION      mSystemConfiguration;
     78 SYSTEM_CONFIGURATION      mSystemConfig;
     79 
     80 UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;
     81 UINT8 mNumberSmbusAddress = sizeof( mSmbusRsvdAddresses ) / sizeof( mSmbusRsvdAddresses[0] );
     82 
     83 /**
     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
     86   storage file.
     87 
     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.
     91 
     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.
     95 
     96 **/
     97 EFI_STATUS
     98 LocateSupportProtocol (
     99   IN   EFI_GUID       *Protocol,
    100   OUT  VOID           **Instance,
    101   IN   UINT32         Type
    102   )
    103 {
    104   EFI_STATUS              Status;
    105   EFI_HANDLE              *HandleBuffer;
    106   UINTN                   NumberOfHandles;
    107   EFI_FV_FILETYPE         FileType;
    108   UINT32                  FvStatus;
    109   EFI_FV_FILE_ATTRIBUTES  Attributes;
    110   UINTN                   Size;
    111   UINTN                   Index;
    112 
    113   FvStatus = 0;
    114 
    115   //
    116   // Locate protocol.
    117   //
    118   Status = gBS->LocateHandleBuffer (
    119                   ByProtocol,
    120                   Protocol,
    121                   NULL,
    122                   &NumberOfHandles,
    123                   &HandleBuffer
    124                   );
    125   if (EFI_ERROR (Status)) {
    126     //
    127     // Defined errors at this time are not found and out of resources.
    128     //
    129     return Status;
    130   }
    131 
    132   //
    133   // Looking for FV with ACPI storage file.
    134   //
    135   for (Index = 0; Index < NumberOfHandles; Index++) {
    136     //
    137     // Get the protocol on this handle.
    138     // This should not fail because of LocateHandleBuffer.
    139     //
    140     Status = gBS->HandleProtocol (
    141                     HandleBuffer[Index],
    142                     Protocol,
    143                     Instance
    144                     );
    145     ASSERT (!EFI_ERROR (Status));
    146 
    147     if (!Type) {
    148       //
    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.
    153       //
    154       break;
    155     }
    156 
    157     //
    158     // See if it has the ACPI storage file.
    159     //
    160     Status = ((EFI_FIRMWARE_VOLUME_PROTOCOL *) (*Instance))->ReadFile (
    161                                                               *Instance,
    162                                                               &gEfiAcpiTableStorageGuid,
    163                                                               NULL,
    164                                                               &Size,
    165                                                               &FileType,
    166                                                               &Attributes,
    167                                                               &FvStatus
    168                                                               );
    169 
    170     //
    171     // If we found it, then we are done.
    172     //
    173     if (!EFI_ERROR (Status)) {
    174       break;
    175     }
    176   }
    177 
    178   //
    179   // Our exit status is determined by the success of the previous operations.
    180   // If the protocol was found, Instance already points to it.
    181   //
    182   //
    183   // Free any allocated buffers.
    184   //
    185   gBS->FreePool (HandleBuffer);
    186 
    187   return Status;
    188 }
    189 
    190 /**
    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.
    195 
    196   @param[in]  Table       The table to update.
    197 
    198   @retval  EFI_SUCCESS    The function completed successfully.
    199 
    200 **/
    201 EFI_STATUS
    202 PlatformUpdateTables (
    203   IN OUT EFI_ACPI_COMMON_HEADER  *Table
    204   )
    205 {
    206   EFI_ACPI_DESCRIPTION_HEADER                                 *TableHeader;
    207   UINT8                                                       *CurrPtr;
    208   UINT8                                                       *EndPtr;
    209   ACPI_APIC_STRUCTURE_PTR                                     *ApicPtr;
    210   UINT8                                                       CurrProcessor;
    211   EFI_STATUS                                                  Status;
    212   EFI_MP_SERVICES_PROTOCOL                                    *MpService;
    213   UINTN                                                       MaximumNumberOfCPUs;
    214   UINTN                                                       NumberOfEnabledCPUs;
    215   UINTN                                                       BspIndex;
    216   EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE                          *AsfEntry;
    217   EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER            *HpetTbl;
    218   UINT64                                                      OemIdValue;
    219   UINT8                                                       Index;
    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;
    232 #endif
    233   UINT16                                                      NumberOfHpets;
    234   UINT16                                                      HpetCapIdValue;
    235   UINT32                                                      HpetBlockID;
    236   EFI_PROCESSOR_INFORMATION                                   ProcessorInfoBuffer;
    237   UINT8                                                       TempVal;
    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;
    241 
    242   CurrPtr                 = NULL;
    243   EndPtr                  = NULL;
    244   ApicPtr                 = NULL;
    245   CurrProcessor           = 0;
    246 
    247 
    248  if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
    249     TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
    250     //
    251     // Update the OEMID.
    252     //
    253     OemIdValue = mPlatformInfo->AcpiOemId;
    254 
    255     *(UINT32 *)(TableHeader->OemId)     = (UINT32)OemIdValue;
    256     *(UINT16 *)(TableHeader->OemId + 4) = *(UINT16*)(((UINT8 *)&OemIdValue) + 4);
    257 
    258     if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
    259     //
    260     // Update the OEM Table ID.
    261     //
    262       TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId;
    263     }
    264 
    265     //
    266     // Update the OEM Table ID.
    267     //
    268     TableHeader->OemRevision = EFI_ACPI_OEM_REVISION;
    269 
    270     //
    271     // Update the creator ID.
    272     //
    273     TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
    274 
    275     //
    276     // Update the creator revision.
    277     //
    278     TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
    279   }
    280 
    281   //
    282   // Complete this function.
    283   //
    284   //
    285   // Locate the MP services protocol.
    286   //
    287   //
    288   // Find the MP Protocol. This is an MP platform, so MP protocol must be
    289   // there.
    290   //
    291   Status = gBS->LocateProtocol (
    292                   &gEfiMpServiceProtocolGuid,
    293                   NULL,
    294                   (VOID **) &MpService
    295                   );
    296   if (EFI_ERROR (Status)) {
    297     return Status;
    298   }
    299 
    300   //
    301   // Determine the number of processors.
    302   //
    303   MpService->GetNumberOfProcessors (
    304               MpService,
    305               &MaximumNumberOfCPUs,
    306               &NumberOfEnabledCPUs
    307               );
    308 
    309   ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);
    310 
    311 
    312   //
    313   // Assign a invalid intial value for update.
    314   //
    315   //
    316   // Update the processors in the APIC table.
    317   //
    318   switch (Table->Signature) {
    319     case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE:
    320       //
    321       // Update the table if ASF is enabled. Otherwise, return error so caller will not install.
    322       //
    323       if (mSystemConfig.Asf == 1) {
    324         return  EFI_UNSUPPORTED;
    325       }
    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];
    330       }
    331       break;
    332 
    333     case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
    334 
    335       Status = MpService->WhoAmI (
    336                             MpService,
    337                             &BspIndex
    338                             );
    339 
    340       //
    341       // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.
    342       //
    343       APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;
    344       APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;
    345 
    346       CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1];
    347       CurrPtr = CurrPtr + 8;
    348 
    349       //
    350       // Size of Local APIC Address & Flag.
    351       //
    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:
    358             //
    359             // ESS override
    360             // Fix for Ordering of MADT to be maintained as it is in MADT table.
    361             //
    362             // Update processor enabled or disabled and keep the local APIC
    363             // order in MADT intact.
    364             //
    365             // Sanity check to make sure proc-id is not arbitrary.
    366             //
    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;
    371             }
    372 
    373             ApicPtr->AcpiLocalApic.Flags  = 0;
    374 
    375             for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {
    376               Status = MpService->GetProcessorInfo (
    377                                     MpService,
    378                                     CurrProcessor,
    379                                     &ProcessorInfoBuffer
    380                                     );
    381 
    382               if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) {
    383                 //
    384                 // Check to see whether or not a processor (or thread) is enabled.
    385                 //
    386                 if ((BspIndex == CurrProcessor) || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) {
    387                   //
    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
    391                   // from the OS.
    392                   //
    393                   ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;
    394 
    395 
    396                   if(ProcessorInfoBuffer.Location.Thread != 0) {
    397                     ApicPtr->AcpiLocalApic.Flags = 0;
    398                   }
    399 
    400                   AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic));
    401                 }
    402                 break;
    403               }
    404             }
    405 
    406             //
    407             // If no APIC-ID match, the cpu may not be populated.
    408             //
    409             break;
    410 
    411           case EFI_ACPI_3_0_IO_APIC:
    412 
    413             IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;
    414             IOApicType->IoApicId = 0x02;
    415             //
    416             // IO APIC entries can be patched here.
    417             //
    418             break;
    419         }
    420 
    421         CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;
    422       }
    423       break;
    424 
    425     case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
    426 
    427        Facp = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;
    428        Facp->Flags &= (UINT32)(~(3<<2));
    429 
    430       break;
    431 
    432     case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
    433       //
    434       // Patch the memory resource.
    435       //
    436       PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table);
    437       break;
    438 
    439     case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
    440       //
    441       // Gv3 support
    442       //
    443       // TBD: Need re-design based on the ValleyTrail platform.
    444       //
    445       break;
    446 
    447     case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:
    448       //
    449       // Adjust HPET Table to correct the Base Address.
    450       //
    451       // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.
    452       //
    453       MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);
    454 
    455 
    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);
    459 
    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;
    463 
    464       if((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_HPET_GCID_NT)) {
    465         HpetBlockID |= (NumberOfHpets);
    466       }
    467       HpetTbl->EventTimerBlockId = HpetBlockID;
    468 
    469       break;
    470 
    471     case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:
    472       //
    473       // Update MCFG base and end bus number.
    474       //
    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;
    479       break;
    480 
    481 
    482     case EFI_ACPI_OSFR_TABLE_SIGNATURE:
    483       //
    484       // Get size of OSFR variable.
    485       //
    486       OcurMfgStringBufferSize = 0;
    487       Status = gRT->GetVariable (
    488                       gACPIOSFRMfgStringVariableName,
    489                       &gACPIOSFRMfgStringVariableGuid,
    490                       NULL,
    491                       &OcurMfgStringBufferSize,
    492                       NULL
    493                       );
    494       if (Status != EFI_BUFFER_TOO_SMALL) {
    495         //
    496         // Variable must not be present on the system.
    497         //
    498         return EFI_UNSUPPORTED;
    499       }
    500 
    501       //
    502       // Allocate memory for variable data.
    503       //
    504       OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize);
    505       Status = gRT->GetVariable (
    506                       gACPIOSFRMfgStringVariableName,
    507                       &gACPIOSFRMfgStringVariableGuid,
    508                       NULL,
    509                       &OcurMfgStringBufferSize,
    510                       OcurMfgStringBuffer
    511                       );
    512       if (!EFI_ERROR (Status)) {
    513         OcurModelStringBufferSize = 0;
    514         Status = gRT->GetVariable (
    515                         gACPIOSFRModelStringVariableName,
    516                         &gACPIOSFRModelStringVariableGuid,
    517                         NULL,
    518                         &OcurModelStringBufferSize,
    519                         NULL
    520                         );
    521         if (Status != EFI_BUFFER_TOO_SMALL) {
    522           //
    523           // Variable must not be present on the system.
    524           //
    525           return EFI_UNSUPPORTED;
    526         }
    527 
    528         //
    529         // Allocate memory for variable data.
    530         //
    531         OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize);
    532         Status = gRT->GetVariable (
    533                         gACPIOSFRModelStringVariableName,
    534                         &gACPIOSFRModelStringVariableGuid,
    535                         NULL,
    536                         &OcurModelStringBufferSize,
    537                         OcurModelStringBuffer
    538                         );
    539         if (!EFI_ERROR (Status)) {
    540           OcurRefDataBlockBufferSize = 0;
    541           Status = gRT->GetVariable (
    542                           gACPIOSFRRefDataBlockVariableName,
    543                           &gACPIOSFRRefDataBlockVariableGuid,
    544                           NULL,
    545                           &OcurRefDataBlockBufferSize,
    546                           NULL
    547                           );
    548           if (Status == EFI_BUFFER_TOO_SMALL) {
    549             //
    550             // Allocate memory for variable data.
    551             //
    552             OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize);
    553             Status = gRT->GetVariable (
    554                             gACPIOSFRRefDataBlockVariableName,
    555                             &gACPIOSFRRefDataBlockVariableGuid,
    556                             NULL,
    557                             &OcurRefDataBlockBufferSize,
    558                             OcurRefDataBlockBuffer
    559                             );
    560           }
    561           OsfrTable = (EFI_ACPI_OSFR_TABLE *) Table;
    562           //
    563           // Currently only one object is defined: OCUR_OSFR_TABLE.
    564           //
    565           OsfrTable->ObjectCount = 1;
    566           //
    567           // Initialize table length to fixed portion of the ACPI OSFR table.
    568           //
    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) + \
    573             sizeof (UINT32));
    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);
    582           }
    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);
    590           }
    591           OsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize);
    592           OsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32);
    593         }
    594       }
    595       gBS->FreePool (OcurMfgStringBuffer);
    596       gBS->FreePool (OcurModelStringBuffer);
    597       gBS->FreePool (OcurRefDataBlockBuffer);
    598       break;
    599 
    600 
    601     case EFI_ACPI_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE:
    602       WsmtTable = (EFI_ACPI_WSMT_TABLE *) Table;
    603        //
    604        // Update Microsoft WSMT table Protections flags.
    605        //
    606       WsmtTable->ProtectionFlags = ((WsmtTable->ProtectionFlags) | (EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS | EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION ));
    607       break;
    608 
    609 
    610     default:
    611       break;
    612   }
    613 
    614   //
    615   //
    616   // Update the hardware signature in the FACS structure.
    617   //
    618   //
    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.
    622   //
    623   return EFI_SUCCESS;
    624 }
    625 
    626 /**
    627 
    628 Routine Description:
    629 
    630   GC_TODO: Add function description.
    631 
    632 Arguments:
    633 
    634   Event   - GC_TODO: add argument description
    635   Context - GC_TODO: add argument description
    636 
    637 Returns:
    638 
    639   GC_TODO: add return values
    640 
    641 **/
    642 STATIC
    643 VOID
    644 EFIAPI
    645 OnReadyToBoot (
    646   IN      EFI_EVENT                 Event,
    647   IN      VOID                      *Context
    648   )
    649 {
    650   EFI_STATUS                  Status;
    651   EFI_ACPI_TABLE_VERSION      TableVersion;
    652   EFI_ACPI_SUPPORT_PROTOCOL   *AcpiSupport;
    653   EFI_ACPI_S3_SAVE_PROTOCOL   *AcpiS3Save;
    654   SYSTEM_CONFIGURATION        SetupVarBuffer;
    655   UINTN                       VariableSize;
    656   EFI_PLATFORM_CPU_INFO       *PlatformCpuInfoPtr = NULL;
    657   EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;
    658   EFI_PEI_HOB_POINTERS          GuidHob;
    659 
    660   if (mFirstNotify) {
    661     return;
    662   }
    663 
    664   mFirstNotify = TRUE;
    665 
    666   //
    667   // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".
    668   //
    669   PlatformCpuInfo.CpuVersion.FullCpuId = 0;
    670 
    671   //
    672   // Get Platform CPU Info HOB.
    673   //
    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,
    680                   NULL,
    681                   &VariableSize,
    682                   PlatformCpuInfoPtr
    683                   );
    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);
    689       }
    690     }
    691   }
    692 
    693   if ((PlatformCpuInfoPtr != NULL)) {
    694     CopyMem(&PlatformCpuInfo, PlatformCpuInfoPtr, sizeof(EFI_PLATFORM_CPU_INFO));
    695   }
    696 
    697   //
    698   // Update the ACPI parameter blocks finally.
    699   //
    700   VariableSize = sizeof (SYSTEM_CONFIGURATION);
    701   Status = gRT->GetVariable (
    702                   L"Setup",
    703                   &mSystemConfigurationGuid,
    704                   NULL,
    705                   &VariableSize,
    706                   &SetupVarBuffer
    707                   );
    708   if (EFI_ERROR (Status) || VariableSize != sizeof(SYSTEM_CONFIGURATION)) {
    709     //The setup variable is corrupted
    710     VariableSize = sizeof(SYSTEM_CONFIGURATION);
    711     Status = gRT->GetVariable(
    712               L"SetupRecovery",
    713               &mSystemConfigurationGuid,
    714               NULL,
    715               &VariableSize,
    716               &SetupVarBuffer
    717               );
    718     ASSERT_EFI_ERROR (Status);
    719   }
    720 
    721   //
    722   // Find the AcpiSupport protocol.
    723   //
    724   Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);
    725   ASSERT_EFI_ERROR (Status);
    726 
    727   TableVersion = EFI_ACPI_TABLE_VERSION_2_0;
    728 
    729   //
    730   // Publish ACPI 1.0 or 2.0 Tables.
    731   //
    732   Status = AcpiSupport->PublishTables (
    733                           AcpiSupport,
    734                           TableVersion
    735                           );
    736   ASSERT_EFI_ERROR (Status);
    737 
    738   //
    739   // S3 script save.
    740   //
    741   Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);
    742   if (!EFI_ERROR (Status)) {
    743     AcpiS3Save->S3Save (AcpiS3Save, NULL);
    744   }
    745 
    746 }
    747 
    748 VOID
    749 PR1FSASetting (
    750   IN VOID
    751   )
    752 {
    753   //
    754   // for FSA on  PR1.
    755   //
    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;
    759   }
    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;
    763   }
    764 
    765 }
    766 
    767 /**
    768   Entry point for Acpi platform driver.
    769 
    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.
    772 
    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.
    776 
    777 **/
    778 EFI_STATUS
    779 EFIAPI
    780 AcpiPlatformEntryPoint (
    781   IN EFI_HANDLE         ImageHandle,
    782   IN EFI_SYSTEM_TABLE   *SystemTable
    783   )
    784 {
    785   EFI_STATUS                    Status;
    786   EFI_STATUS                    AcpiStatus;
    787   EFI_ACPI_SUPPORT_PROTOCOL     *AcpiSupport;
    788   EFI_FIRMWARE_VOLUME_PROTOCOL  *FwVol;
    789   INTN                          Instance;
    790   EFI_ACPI_COMMON_HEADER        *CurrentTable;
    791   UINTN                         TableHandle;
    792   UINT32                        FvStatus;
    793   UINT32                        Size;
    794   EFI_EVENT                     Event;
    795   EFI_ACPI_TABLE_VERSION        TableVersion;
    796   UINTN                         VarSize;
    797   UINTN                         SysCfgSize;
    798   EFI_HANDLE                    Handle;
    799   EFI_PS2_POLICY_PROTOCOL       *Ps2Policy;
    800   EFI_PEI_HOB_POINTERS          GuidHob;
    801   UINT8                         PortData;
    802   EFI_MP_SERVICES_PROTOCOL      *MpService;
    803   UINTN                         MaximumNumberOfCPUs;
    804   UINTN                         NumberOfEnabledCPUs;
    805   PCH_STEPPING                  pchStepping;
    806 
    807   mFirstNotify      = FALSE;
    808 
    809   TableVersion      = EFI_ACPI_TABLE_VERSION_2_0;
    810   Instance          = 0;
    811   CurrentTable      = NULL;
    812   TableHandle       = 0;
    813 
    814   //
    815   // Update HOB variable for PCI resource information.
    816   // Get the HOB list.  If it is not present, then ASSERT.
    817   //
    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);
    822     }
    823   }
    824 
    825   //
    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.
    828   //
    829   VarSize = sizeof(SYSTEM_CONFIGURATION);
    830   Status = gRT->GetVariable(
    831                   L"Setup",
    832                   &mSystemConfigurationGuid,
    833                   NULL,
    834                   &VarSize,
    835                   &mSystemConfiguration
    836                   );
    837   if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
    838     //The setup variable is corrupted
    839     VarSize = sizeof(SYSTEM_CONFIGURATION);
    840     Status = gRT->GetVariable(
    841               L"SetupRecovery",
    842               &mSystemConfigurationGuid,
    843               NULL,
    844               &VarSize,
    845               &mSystemConfiguration
    846               );
    847     ASSERT_EFI_ERROR (Status);
    848   }
    849 
    850   //
    851   // Find the AcpiSupport protocol.
    852   //
    853   Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);
    854   ASSERT_EFI_ERROR (Status);
    855 
    856   //
    857   // Locate the firmware volume protocol.
    858   //
    859   Status = LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid, (VOID **) &FwVol, 1);
    860   ASSERT_EFI_ERROR (Status);
    861 
    862   //
    863   // Read the current system configuration variable store.
    864   //
    865   SysCfgSize = sizeof(SYSTEM_CONFIGURATION);
    866   Status = gRT->GetVariable (
    867                   L"Setup",
    868                   &gEfiNormalSetupGuid,
    869                   NULL,
    870                   &SysCfgSize,
    871                   &mSystemConfig
    872                   );
    873   if (EFI_ERROR (Status) || SysCfgSize != sizeof(SYSTEM_CONFIGURATION)) {
    874     //The setup variable is corrupted
    875     SysCfgSize = sizeof(SYSTEM_CONFIGURATION);
    876     Status = gRT->GetVariable(
    877               L"SetupRecovery",
    878               &gEfiNormalSetupGuid,
    879               NULL,
    880               &SysCfgSize,
    881               &mSystemConfig
    882               );
    883     ASSERT_EFI_ERROR (Status);
    884   }
    885 
    886 
    887   Status    = EFI_SUCCESS;
    888   Instance  = 0;
    889 
    890   //
    891   // TBD: Need re-design based on the ValleyTrail platform.
    892   //
    893   Status = gBS->LocateProtocol (
    894                   &gEfiMpServiceProtocolGuid,
    895                   NULL,
    896                   (VOID **) &MpService
    897                   );
    898   if (EFI_ERROR (Status)) {
    899     return Status;
    900   }
    901 
    902   //
    903   // Determine the number of processors.
    904   //
    905   MpService->GetNumberOfProcessors (
    906                MpService,
    907                &MaximumNumberOfCPUs,
    908                &NumberOfEnabledCPUs
    909                );
    910 
    911   //
    912   // Allocate and initialize the NVS area for SMM and ASL communication.
    913   //
    914   Status = gBS->AllocatePool (
    915                   EfiACPIMemoryNVS,
    916                   sizeof (EFI_GLOBAL_NVS_AREA),
    917                   (void **)&mGlobalNvsArea.Area
    918                   );
    919   ASSERT_EFI_ERROR (Status);
    920   gBS->SetMem (
    921          mGlobalNvsArea.Area,
    922          sizeof (EFI_GLOBAL_NVS_AREA),
    923          0
    924          );
    925   DEBUG((EFI_D_ERROR, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area));
    926 
    927   //
    928   // Update global NVS area for ASL and SMM init code to use.
    929   //
    930   mGlobalNvsArea.Area->ApicEnable                 = 1;
    931   mGlobalNvsArea.Area->EmaEnable                  = 0;
    932 
    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;
    939 
    940   mGlobalNvsArea.Area->LogicalProcessorCount    = (UINT8)NumberOfEnabledCPUs;
    941 
    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;
    947 
    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;
    958 
    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;
    964 
    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 ;
    973 
    974   mGlobalNvsArea.Area->UartSelection = mSystemConfiguration.UartInterface;
    975   mGlobalNvsArea.Area->PcuUart1Enable = mSystemConfiguration.PcuUart1;
    976   mGlobalNvsArea.Area->NativePCIESupport = 1;
    977   mGlobalNvsArea.Area->RtcBattery = mSystemConfiguration.RtcBattery;
    978 
    979 
    980 
    981 
    982 
    983   //
    984   // Update BootMode: 0:ACPI mode; 1:PCI mode
    985   //
    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;
    992   }
    993 
    994   //
    995   // Platform Flavor
    996   //
    997   mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor;
    998 
    999   //
   1000   // Update the Platform id
   1001   //
   1002   mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId;
   1003 
   1004   //
   1005   // Update the  Board Revision
   1006   //
   1007   mGlobalNvsArea.Area->FabID = mPlatformInfo->BoardRev;
   1008 
   1009   //
   1010   // Update SOC Stepping
   1011   //
   1012   mGlobalNvsArea.Area->SocStepping = (UINT8)(PchStepping());
   1013 
   1014   mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg;
   1015 
   1016   pchStepping = PchStepping();
   1017   if (mSystemConfiguration.UsbAutoMode == 1) {
   1018     //
   1019     // Auto mode is enabled.
   1020     //
   1021     if (PchA0 == pchStepping) {
   1022       //
   1023       //  For A0, EHCI is enabled as default.
   1024       //
   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));
   1029     } else {
   1030       //
   1031       //  For A1 and later, XHCI is enabled as default.
   1032       //
   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));
   1037     }
   1038   }
   1039 
   1040   mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode;
   1041 
   1042   mGlobalNvsArea.Area->Stepping = mPlatformInfo->IchRevision;
   1043 
   1044   //
   1045   // Override invalid Pre-Boot Driver and XhciMode combination.
   1046   //
   1047   if ((mSystemConfiguration.UsbXhciSupport == 0) && (mSystemConfiguration.PchUsb30Mode == 3)) {
   1048     mGlobalNvsArea.Area->XhciMode = 2;
   1049   }
   1050   if ((mSystemConfiguration.UsbXhciSupport == 1) && (mSystemConfiguration.PchUsb30Mode == 2)) {
   1051     mGlobalNvsArea.Area->XhciMode = 3;
   1052   }
   1053 
   1054   DEBUG ((EFI_D_ERROR, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea.Area->XhciMode));
   1055 
   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;
   1061 
   1062   if (mSystemConfiguration.ISPEn == 0) {
   1063     mGlobalNvsArea.Area->ISPDevSel                      = GLOBAL_NVS_DEVICE_DISABLE;
   1064   }
   1065 
   1066   mGlobalNvsArea.Area->WittEnable                       = mSystemConfiguration.WittEnable;
   1067   mGlobalNvsArea.Area->UtsEnable                        = mSystemConfiguration.UtsEnable;
   1068   mGlobalNvsArea.Area->SarEnable                        = mSystemConfiguration.SAR1;
   1069 
   1070 
   1071   mGlobalNvsArea.Area->ReservedO                        = 1;
   1072 
   1073   SettingI2CTouchAddress();
   1074   mGlobalNvsArea.Area->IdleReserve= mSystemConfiguration.IdleReserve;
   1075   //
   1076   // Read BMBOUND and store it in GlobalNVS to pass into ASL.
   1077   //
   1078   // BUGBUG: code was moved into silicon reference code.
   1079   //
   1080   if (mSystemConfiguration.eMMCBootMode== 1) {
   1081     //
   1082     // Auto detect mode.
   1083     //
   1084     DEBUG ((EFI_D_ERROR, "Auto detect mode------------start\n"));
   1085 
   1086     //
   1087     // Silicon Steppings.
   1088     //
   1089     switch (PchStepping()) {
   1090       case PchA0: // A0/A1
   1091       case PchA1:
   1092         DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 Configuration\n"));
   1093         mSystemConfiguration.LpsseMMCEnabled            = 1;
   1094         mSystemConfiguration.LpsseMMC45Enabled          = 0;
   1095         break;
   1096 
   1097       case PchB0: // B0 and later.
   1098       default:
   1099         DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 Configuration\n"));
   1100         mSystemConfiguration.LpsseMMCEnabled            = 0;
   1101         mSystemConfiguration.LpsseMMC45Enabled          = 1;
   1102         break;
   1103    }
   1104   } else if (mSystemConfiguration.eMMCBootMode == 2) {
   1105       //
   1106       // eMMC 4.41
   1107       //
   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) {
   1112       //
   1113       // eMMC 4.5
   1114       //
   1115       DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));
   1116       mSystemConfiguration.LpsseMMCEnabled            = 0;
   1117       mSystemConfiguration.LpsseMMC45Enabled          = 1;
   1118 
   1119   } else {
   1120       //
   1121       // Disable eMMC controllers.
   1122       //
   1123       DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));
   1124       mSystemConfiguration.LpsseMMCEnabled            = 0;
   1125       mSystemConfiguration.LpsseMMC45Enabled          = 0;
   1126   }
   1127 
   1128   mGlobalNvsArea.Area->emmcVersion = 0;
   1129   if (mSystemConfiguration.LpsseMMCEnabled) {
   1130      DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 0\n"));
   1131      mGlobalNvsArea.Area->emmcVersion = 0;
   1132   }
   1133 
   1134   if (mSystemConfiguration.LpsseMMC45Enabled) {
   1135      DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n"));
   1136      mGlobalNvsArea.Area->emmcVersion = 1;
   1137   }
   1138 
   1139   mGlobalNvsArea.Area->SdCardRemovable = mSystemConfiguration.SdCardRemovable;
   1140 
   1141   //
   1142   // Microsoft IOT
   1143   //
   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"));
   1149   } else {
   1150     mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_DISABLE;
   1151     DEBUG ((EFI_D_ERROR, "JP1 is not set to be MSFT IOT configuration.\n"));
   1152   }
   1153 
   1154   //
   1155   // SIO related option.
   1156   //
   1157   Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (void **)&mCpuIo);
   1158   ASSERT_EFI_ERROR (Status);
   1159 
   1160   mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE;
   1161 
   1162   mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE;
   1163 
   1164   if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) {
   1165     //
   1166     // Check ID for SIO WPCN381U.
   1167     //
   1168     Status = mCpuIo->Io.Read (
   1169                           mCpuIo,
   1170                           EfiCpuIoWidthUint8,
   1171                           WPCN381U_CONFIG_INDEX,
   1172                           1,
   1173                           &PortData
   1174                           );
   1175     ASSERT_EFI_ERROR (Status);
   1176     if (PortData != 0xFF) {
   1177       PortData = 0x20;
   1178       Status = mCpuIo->Io.Write (
   1179                             mCpuIo,
   1180                             EfiCpuIoWidthUint8,
   1181                             WPCN381U_CONFIG_INDEX,
   1182                             1,
   1183                             &PortData
   1184                             );
   1185       ASSERT_EFI_ERROR (Status);
   1186       Status = mCpuIo->Io.Read (
   1187                             mCpuIo,
   1188                             EfiCpuIoWidthUint8,
   1189                             WPCN381U_CONFIG_DATA,
   1190                             1,
   1191                             &PortData
   1192                             );
   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;
   1198       }
   1199     }
   1200   }
   1201 
   1202 
   1203 
   1204   //
   1205   // Get Ps2 policy to set. Will be use if present.
   1206   //
   1207   Status =  gBS->LocateProtocol (
   1208                    &gEfiPs2PolicyProtocolGuid,
   1209                    NULL,
   1210                    (VOID **)&Ps2Policy
   1211                    );
   1212   if (!EFI_ERROR (Status)) {
   1213           Status = Ps2Policy->Ps2InitHardware (ImageHandle);
   1214   }
   1215 
   1216   mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode;
   1217 
   1218   Handle = NULL;
   1219   Status = gBS->InstallMultipleProtocolInterfaces (
   1220                   &Handle,
   1221                   &gEfiGlobalNvsAreaProtocolGuid,
   1222                   &mGlobalNvsArea,
   1223                   NULL
   1224                   );
   1225 
   1226   //
   1227   // Read tables from the storage file.
   1228   //
   1229   while (!EFI_ERROR (Status)) {
   1230     CurrentTable = NULL;
   1231 
   1232     Status = FwVol->ReadSection (
   1233                       FwVol,
   1234                       &gEfiAcpiTableStorageGuid,
   1235                       EFI_SECTION_RAW,
   1236                       Instance,
   1237                       (VOID **) &CurrentTable,
   1238                       (UINTN *) &Size,
   1239                       &FvStatus
   1240                       );
   1241 
   1242     if (!EFI_ERROR (Status)) {
   1243       //
   1244       // Allow platform specific code to reject the table or update it.
   1245       //
   1246       AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);
   1247 
   1248       if (!EFI_ERROR (AcpiStatus)) {
   1249         //
   1250         // Perform any table specific updates.
   1251         //
   1252         AcpiStatus = PlatformUpdateTables (CurrentTable);
   1253         if (!EFI_ERROR (AcpiStatus)) {
   1254           //
   1255           // Add the table.
   1256           //
   1257           TableHandle = 0;
   1258           AcpiStatus = AcpiSupport->SetAcpiTable (
   1259                                       AcpiSupport,
   1260                                       CurrentTable,
   1261                                       TRUE,
   1262                                       TableVersion,
   1263                                       &TableHandle
   1264                                       );
   1265           ASSERT_EFI_ERROR (AcpiStatus);
   1266         }
   1267       }
   1268 
   1269       //
   1270       // Increment the instance.
   1271       //
   1272       Instance++;
   1273     }
   1274   }
   1275 
   1276   Status = EfiCreateEventReadyToBootEx (
   1277              TPL_NOTIFY,
   1278              OnReadyToBoot,
   1279              NULL,
   1280              &Event
   1281              );
   1282 
   1283   //
   1284   // Finished.
   1285   //
   1286   return EFI_SUCCESS;
   1287 }
   1288 
   1289 UINT8
   1290 ReadCmosBank1Byte (
   1291   IN  UINT8                           Index
   1292   )
   1293 {
   1294   UINT8                               Data;
   1295 
   1296   IoWrite8(0x72, Index);
   1297   Data = IoRead8 (0x73);
   1298   return Data;
   1299 }
   1300 
   1301 VOID
   1302 WriteCmosBank1Byte (
   1303   IN  UINT8                           Index,
   1304   IN  UINT8                           Data
   1305   )
   1306 {
   1307   IoWrite8 (0x72, Index);
   1308   IoWrite8 (0x73, Data);
   1309 }
   1310 
   1311 
   1312 
   1313 VOID
   1314 SettingI2CTouchAddress (
   1315   IN VOID
   1316   )
   1317 {
   1318   if (mSystemConfiguration.I2CTouchAd == 0) {
   1319     //
   1320     // If setup menu select auto set I2C Touch Address base on board id.
   1321     //
   1322     if (mPlatformInfo->BoardId == BOARD_ID_BL_RVP ||
   1323         mPlatformInfo->BoardId == BOARD_ID_BL_STHI ||
   1324         mPlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ) {
   1325       //
   1326       //RVP
   1327       //
   1328       mGlobalNvsArea.Area->I2CTouchAddress = 0x4B;
   1329     } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD) {
   1330       //
   1331       //FFRD
   1332       //
   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) {
   1339       //
   1340       //FFRD8 uses 0x4A.
   1341       //
   1342       mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;
   1343     }
   1344   } else {
   1345     mGlobalNvsArea.Area->I2CTouchAddress = mSystemConfiguration.I2CTouchAd;
   1346   }
   1347   DEBUG((EFI_D_ERROR, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea.Area->I2CTouchAddress));
   1348 }
   1349 
   1350 
   1351