]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / AcpiPlatform / AcpiPlatform.c
diff --git a/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c b/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
new file mode 100644 (file)
index 0000000..824f237
--- /dev/null
@@ -0,0 +1,1307 @@
+/** @file\r
+\r
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>\r
+                                                                                   \r
+\r
+  This program and the accompanying materials are licensed and made available under\r
+\r
+  the terms and conditions of the BSD License that accompanies this distribution.  \r
+\r
+  The full text of the license may be found at                                     \r
+\r
+  http://opensource.org/licenses/bsd-license.php.                                  \r
+\r
+                                                                                   \r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            \r
+\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    \r
+\r
+                                                                                   \r
+\r
+\r
+\r
+\r
+Module Name:\r
+\r
+  AcpiPlatform.c\r
+\r
+Abstract:\r
+\r
+  ACPI Platform Driver\r
+\r
+\r
+--*/\r
+\r
+#include <PiDxe.h>\r
+#include <Protocol/TcgService.h>\r
+#include <Protocol/FirmwareVolume.h>\r
+#include "AcpiPlatform.h"\r
+#include "AcpiPlatformHooks.h"\r
+#include "AcpiPlatformHooksLib.h"\r
+#include "Platform.h"\r
+#include <Hpet.h>\r
+#include <Mcfg.h>\r
+#include "Osfr.h"\r
+#include <Guid/GlobalVariable.h>\r
+#include <Guid/SetupVariable.h>\r
+#include <Guid/PlatformInfo.h>\r
+#include <Protocol/CpuIo.h>\r
+#include <Guid/BoardFeatures.h>\r
+#include <Protocol/AcpiSupport.h>\r
+#include <Protocol/AcpiS3Save.h>\r
+#include <Protocol/Ps2Policy.h>\r
+#include <Library/CpuIA32.h>\r
+#include <SetupMode.h>\r
+#include <Guid/AcpiTableStorage.h>\r
+#include <Guid/EfiVpdData.h>\r
+#include <PchAccess.h>\r
+#include <Guid/Vlv2Variable.h>\r
+#include <Guid/PlatformCpuInfo.h>\r
+\r
+\r
+CHAR16    EfiPlatformCpuInfoVariable[] = L"PlatformCpuInfo";\r
+CHAR16    gACPIOSFRModelStringVariableName[] = ACPI_OSFR_MODEL_STRING_VARIABLE_NAME;\r
+CHAR16    gACPIOSFRRefDataBlockVariableName[] = ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME;\r
+CHAR16    gACPIOSFRMfgStringVariableName[] = ACPI_OSFR_MFG_STRING_VARIABLE_NAME;\r
+\r
+EFI_CPU_IO_PROTOCOL                    *mCpuIo;\r
+#ifndef __GNUC__\r
+#pragma optimize("", off)\r
+#endif\r
+BOOLEAN                   mFirstNotify;\r
+EFI_PLATFORM_INFO_HOB     *mPlatformInfo;\r
+EFI_GUID                  mSystemConfigurationGuid = SYSTEM_CONFIGURATION_GUID;\r
+SYSTEM_CONFIGURATION      mSystemConfiguration;\r
+SYSTEM_CONFIGURATION      mSystemConfig;\r
+\r
+UINT8 mSmbusRsvdAddresses[] = PLATFORM_SMBUS_RSVD_ADDRESSES;\r
+UINT8 mNumberSmbusAddress = sizeof( mSmbusRsvdAddresses ) / sizeof( mSmbusRsvdAddresses[0] );\r
+\r
+/**\r
+  Locate the first instance of a protocol.  If the protocol requested is an\r
+  FV protocol, then it will return the first FV that contains the ACPI table\r
+  storage file.\r
+\r
+  @param[in]  Protocol            The protocol to find.\r
+  @param[in]  Instance            Return pointer to the first instance of the protocol.\r
+  @param[in]  Type                The type of protocol to locate.\r
+\r
+  @retval  EFI_SUCCESS            The function completed successfully.\r
+  @retval  EFI_NOT_FOUND          The protocol could not be located.\r
+  @retval  EFI_OUT_OF_RESOURCES   There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateSupportProtocol (\r
+  IN   EFI_GUID       *Protocol,\r
+  OUT  VOID           **Instance,\r
+  IN   UINT32         Type\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_HANDLE              *HandleBuffer;\r
+  UINTN                   NumberOfHandles;\r
+  EFI_FV_FILETYPE         FileType;\r
+  UINT32                  FvStatus;\r
+  EFI_FV_FILE_ATTRIBUTES  Attributes;\r
+  UINTN                   Size;\r
+  UINTN                   Index;\r
+\r
+  FvStatus = 0;\r
+\r
+  //\r
+  // Locate protocol.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  Protocol,\r
+                  NULL,\r
+                  &NumberOfHandles,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Defined errors at this time are not found and out of resources.\r
+    //\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Looking for FV with ACPI storage file.\r
+  //\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle.\r
+    // This should not fail because of LocateHandleBuffer.\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                    HandleBuffer[Index],\r
+                    Protocol,\r
+                    Instance\r
+                    );\r
+    ASSERT (!EFI_ERROR (Status));\r
+\r
+    if (!Type) {\r
+      //\r
+      // Not looking for the FV protocol, so find the first instance of the\r
+      // protocol.  There should not be any errors because our handle buffer\r
+      // should always contain at least one or LocateHandleBuffer would have\r
+      // returned not found.\r
+      //\r
+      break;\r
+    }\r
+\r
+    //\r
+    // See if it has the ACPI storage file.\r
+    //\r
+    Status = ((EFI_FIRMWARE_VOLUME_PROTOCOL *) (*Instance))->ReadFile (\r
+                                                              *Instance,\r
+                                                              &gEfiAcpiTableStorageGuid,\r
+                                                              NULL,\r
+                                                              &Size,\r
+                                                              &FileType,\r
+                                                              &Attributes,\r
+                                                              &FvStatus\r
+                                                              );\r
+\r
+    //\r
+    // If we found it, then we are done.\r
+    //\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Our exit status is determined by the success of the previous operations.\r
+  // If the protocol was found, Instance already points to it.\r
+  //\r
+  //\r
+  // Free any allocated buffers.\r
+  //\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function will update any runtime platform specific information.\r
+  This currently includes:\r
+    Setting OEM table values, ID, table ID, creator ID and creator revision.\r
+    Enabling the proper processor entries in the APIC tables.\r
+\r
+  @param[in]  Table       The table to update.\r
+\r
+  @retval  EFI_SUCCESS    The function completed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+PlatformUpdateTables (\r
+  IN OUT EFI_ACPI_COMMON_HEADER  *Table\r
+  )\r
+{\r
+  EFI_ACPI_DESCRIPTION_HEADER                                 *TableHeader;\r
+  UINT8                                                       *CurrPtr;\r
+  UINT8                                                       *EndPtr;\r
+  ACPI_APIC_STRUCTURE_PTR                                     *ApicPtr;\r
+  UINT8                                                       CurrProcessor;\r
+  EFI_STATUS                                                  Status;\r
+  EFI_MP_SERVICES_PROTOCOL                                    *MpService;\r
+  UINTN                                                       MaximumNumberOfCPUs;\r
+  UINTN                                                       NumberOfEnabledCPUs;\r
+  UINTN                                                       BufferSize;\r
+  ACPI_APIC_STRUCTURE_PTR                                     *ProcessorLocalApicEntry;\r
+  UINTN                                                       BspIndex;\r
+  EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE                          *AsfEntry;\r
+  EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER            *HpetTbl;\r
+  UINT64                                                      OemIdValue;\r
+  UINT8                                                       Index;\r
+  EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE                   *Facp;\r
+  EFI_ACPI_OSFR_TABLE                                         *OsfrTable;\r
+  EFI_ACPI_OSFR_OCUR_OBJECT                                   *pOcurObject;\r
+  EFI_ACPI_OSFR_OCUR_OBJECT                                   OcurObject = {{0xB46F133D, 0x235F, 0x4634, 0x9F, 0x03, 0xB1, 0xC0, 0x1C, 0x54, 0x78, 0x5B}, 0, 0, 0, 0, 0};\r
+  CHAR16                                                      *OcurMfgStringBuffer = NULL;\r
+  CHAR16                                                      *OcurModelStringBuffer = NULL;\r
+  UINT8                                                       *OcurRefDataBlockBuffer = NULL;\r
+  UINTN                                                       OcurMfgStringBufferSize;\r
+  UINTN                                                       OcurModelStringBufferSize;\r
+  UINTN                                                       OcurRefDataBlockBufferSize;\r
+#if defined (IDCC2_SUPPORTED) && IDCC2_SUPPORTED\r
+  EFI_ACPI_ASPT_TABLE                                         *pSpttTable;\r
+#endif\r
+  UINT16                                                      NumberOfHpets;\r
+  UINT16                                                      HpetCapIdValue;\r
+  UINT32                                                      HpetBlockID;\r
+  UINTN                                                       LocalApicCounter;\r
+  EFI_PROCESSOR_INFORMATION                                   ProcessorInfoBuffer;\r
+  UINT8                                                       TempVal;\r
+  EFI_ACPI_3_0_IO_APIC_STRUCTURE                              *IOApicType;\r
+  EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER         *APICTableHeader;\r
+\r
+  CurrPtr                 = NULL;\r
+  EndPtr                  = NULL;\r
+  ApicPtr                 = NULL;\r
+  LocalApicCounter        = 0;\r
+  CurrProcessor           = 0;\r
+  ProcessorLocalApicEntry = NULL;\r
+\r
+\r
+ if (Table->Signature != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
+    TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;\r
+    //\r
+    // Update the OEMID.\r
+    //\r
+    OemIdValue = mPlatformInfo->AcpiOemId;\r
+\r
+    *(UINT32 *)(TableHeader->OemId)     = (UINT32)OemIdValue;\r
+    *(UINT16 *)(TableHeader->OemId + 4) = *(UINT16*)(((UINT8 *)&OemIdValue) + 4);\r
+\r
+    if ((Table->Signature != EFI_ACPI_2_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {\r
+    //\r
+    // Update the OEM Table ID.\r
+    //\r
+      TableHeader->OemTableId = mPlatformInfo->AcpiOemTableId;\r
+    }\r
+\r
+    //\r
+    // Update the OEM Table ID.\r
+    //\r
+    TableHeader->OemRevision = EFI_ACPI_OEM_REVISION;\r
+\r
+    //\r
+    // Update the creator ID.\r
+    //\r
+    TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;\r
+\r
+    //\r
+    // Update the creator revision.\r
+    //\r
+    TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;\r
+  }\r
+\r
+  //\r
+  // Complete this function.\r
+  //\r
+  //\r
+  // Locate the MP services protocol.\r
+  //\r
+  //\r
+  // Find the MP Protocol. This is an MP platform, so MP protocol must be\r
+  // there.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiMpServiceProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &MpService\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Determine the number of processors.\r
+  //\r
+  MpService->GetNumberOfProcessors (\r
+              MpService,\r
+              &MaximumNumberOfCPUs,\r
+              &NumberOfEnabledCPUs\r
+              );\r
+\r
+  ASSERT (MaximumNumberOfCPUs <= MAX_CPU_NUM && NumberOfEnabledCPUs >= 1);\r
+\r
+\r
+  //\r
+  // Assign a invalid intial value for update.\r
+  //\r
+  //\r
+  // Update the processors in the APIC table.\r
+  //\r
+  switch (Table->Signature) {\r
+    case EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE:\r
+      //\r
+      // Update the table if ASF is enabled. Otherwise, return error so caller will not install.\r
+      //\r
+      if (mSystemConfig.Asf == 1) {\r
+        return  EFI_UNSUPPORTED;\r
+      }\r
+      AsfEntry = (EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE *) Table;\r
+      TempVal = (mNumberSmbusAddress < ASF_ADDR_DEVICE_ARRAY_LENGTH)? mNumberSmbusAddress : ASF_ADDR_DEVICE_ARRAY_LENGTH;\r
+      for (Index = 0; Index < TempVal; Index++) {\r
+        AsfEntry->AsfAddr.FixedSmbusAddresses[Index] = mSmbusRsvdAddresses[Index];\r
+      }\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:\r
+\r
+      Status = MpService->WhoAmI (\r
+                            MpService,\r
+                            &BspIndex\r
+                            );\r
+\r
+      //\r
+      // PCAT_COMPAT Set to 1 indicate 8259 vectors should be disabled.\r
+      //\r
+      APICTableHeader = (EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)Table;\r
+      APICTableHeader->Flags |= EFI_ACPI_3_0_PCAT_COMPAT;\r
+\r
+      CurrPtr = (UINT8 *) &((EFI_ACPI_DESCRIPTION_HEADER *) Table)[1];\r
+      CurrPtr = CurrPtr + 8;\r
+\r
+      //\r
+      // Size of Local APIC Address & Flag.\r
+      //\r
+      EndPtr  = (UINT8 *) Table;\r
+      EndPtr  = EndPtr + Table->Length;\r
+      while (CurrPtr < EndPtr) {\r
+        ApicPtr = (ACPI_APIC_STRUCTURE_PTR *) CurrPtr;\r
+        switch (ApicPtr->AcpiApicCommon.Type) {\r
+          case EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC:\r
+            //\r
+            // ESS override\r
+            // Fix for Ordering of MADT to be maintained as it is in MADT table.\r
+            //\r
+            // Update processor enabled or disabled and keep the local APIC\r
+            // order in MADT intact.\r
+            //\r
+            // Sanity check to make sure proc-id is not arbitrary.\r
+            //\r
+            DEBUG ((EFI_D_ERROR, "ApicPtr->AcpiLocalApic.AcpiProcessorId = %x, MaximumNumberOfCPUs = %x\n", \\r
+            ApicPtr->AcpiLocalApic.AcpiProcessorId, MaximumNumberOfCPUs));\r
+            if(ApicPtr->AcpiLocalApic.AcpiProcessorId > MaximumNumberOfCPUs) {\r
+              ApicPtr->AcpiLocalApic.AcpiProcessorId = (UINT8)MaximumNumberOfCPUs;\r
+            }\r
+\r
+            BufferSize                    = 0;\r
+            ApicPtr->AcpiLocalApic.Flags  = 0;\r
+\r
+            for (CurrProcessor = 0; CurrProcessor < MaximumNumberOfCPUs; CurrProcessor++) {\r
+              Status = MpService->GetProcessorInfo (\r
+                                    MpService,\r
+                                    CurrProcessor,\r
+                                    &ProcessorInfoBuffer\r
+                                    );\r
+\r
+              if (Status == EFI_SUCCESS && ProcessorInfoBuffer.ProcessorId == ApicPtr->AcpiLocalApic.ApicId) {\r
+                //\r
+                // Check to see whether or not a processor (or thread) is enabled.\r
+                //\r
+                if ((BspIndex == CurrProcessor) || ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0)) {\r
+                  //\r
+                  // Go on and check if Hyper Threading is enabled. If HT not enabled\r
+                  // hide this thread from OS by not setting the flag to 1.  This is the\r
+                  // software way to disable Hyper Threading.  Basically we just hide it\r
+                  // from the OS.\r
+                  //\r
+                  ApicPtr->AcpiLocalApic.Flags = EFI_ACPI_1_0_LOCAL_APIC_ENABLED;\r
+\r
+\r
+                  if(ProcessorInfoBuffer.Location.Thread != 0) {\r
+                    ApicPtr->AcpiLocalApic.Flags = 0;\r
+                  }\r
+\r
+                  AppendCpuMapTableEntry (&(ApicPtr->AcpiLocalApic));\r
+                }\r
+                break;\r
+              }\r
+            }\r
+\r
+            //\r
+            // If no APIC-ID match, the cpu may not be populated.\r
+            //\r
+            break;\r
+\r
+          case EFI_ACPI_3_0_IO_APIC:\r
+\r
+            IOApicType = (EFI_ACPI_3_0_IO_APIC_STRUCTURE *)CurrPtr;\r
+            IOApicType->IoApicId = 0x02;\r
+            //\r
+            // IO APIC entries can be patched here.\r
+            //\r
+            break;\r
+        }\r
+\r
+        CurrPtr = CurrPtr + ApicPtr->AcpiApicCommon.Length;\r
+      }\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
+\r
+       Facp = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) Table;\r
+       Facp->Flags &= (UINT32)(~(3<<2));\r
+\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
+      //\r
+      // Patch the memory resource.\r
+      //\r
+      PatchDsdtTable ((EFI_ACPI_DESCRIPTION_HEADER *) Table);\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
+      //\r
+      // Gv3 support\r
+      //\r
+      // TBD: Need re-design based on the ValleyTrail platform.\r
+      //\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE:\r
+      //\r
+      // Adjust HPET Table to correct the Base Address.\r
+      //\r
+      // Enable HPET always as Hpet.asi always indicates that Hpet is enabled.\r
+      //\r
+      MmioOr8 (R_PCH_PCH_HPET + R_PCH_PCH_HPET_GCFG, B_PCH_PCH_HPET_GCFG_EN);\r
+\r
+\r
+      HpetTbl = (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER *) Table;\r
+      HpetTbl->BaseAddressLower32Bit.Address = HPET_BASE_ADDRESS;\r
+      HpetTbl->EventTimerBlockId = *((UINT32*)(UINTN)HPET_BASE_ADDRESS);\r
+\r
+      HpetCapIdValue = *(UINT16 *)(UINTN)(HPET_BASE_ADDRESS);\r
+      NumberOfHpets = HpetCapIdValue & B_PCH_PCH_HPET_GCID_NT;  // Bits [8:12] contains the number of Hpets\r
+      HpetBlockID = EFI_ACPI_EVENT_TIMER_BLOCK_ID;\r
+\r
+      if((NumberOfHpets) && (NumberOfHpets & B_PCH_PCH_HPET_GCID_NT)) {\r
+        HpetBlockID |= (NumberOfHpets);\r
+      }\r
+      HpetTbl->EventTimerBlockId = HpetBlockID;\r
+\r
+      break;\r
+\r
+    case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:\r
+      //\r
+      // Update MCFG base and end bus number.\r
+      //\r
+      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].BaseAddress\r
+        = mPlatformInfo->PciData.PciExpressBase;\r
+      ((EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE *) Table)->Segment[0].EndBusNumber\r
+        = (UINT8)RShiftU64 (mPlatformInfo->PciData.PciExpressSize, 20) - 1;\r
+      break;\r
+\r
+\r
+    case EFI_ACPI_OSFR_TABLE_SIGNATURE:\r
+      //\r
+      // Get size of OSFR variable.\r
+      //\r
+      OcurMfgStringBufferSize = 0;\r
+      Status = gRT->GetVariable (\r
+                      gACPIOSFRMfgStringVariableName,\r
+                      &gACPIOSFRMfgStringVariableGuid,\r
+                      NULL,\r
+                      &OcurMfgStringBufferSize,\r
+                      NULL\r
+                      );\r
+      if (Status != EFI_BUFFER_TOO_SMALL) {\r
+        //\r
+        // Variable must not be present on the system.\r
+        //\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
+      //\r
+      // Allocate memory for variable data.\r
+      //\r
+      OcurMfgStringBuffer = AllocatePool (OcurMfgStringBufferSize);\r
+      Status = gRT->GetVariable (\r
+                      gACPIOSFRMfgStringVariableName,\r
+                      &gACPIOSFRMfgStringVariableGuid,\r
+                      NULL,\r
+                      &OcurMfgStringBufferSize,\r
+                      OcurMfgStringBuffer\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        OcurModelStringBufferSize = 0;\r
+        Status = gRT->GetVariable (\r
+                        gACPIOSFRModelStringVariableName,\r
+                        &gACPIOSFRModelStringVariableGuid,\r
+                        NULL,\r
+                        &OcurModelStringBufferSize,\r
+                        NULL\r
+                        );\r
+        if (Status != EFI_BUFFER_TOO_SMALL) {\r
+          //\r
+          // Variable must not be present on the system.\r
+          //\r
+          return EFI_UNSUPPORTED;\r
+        }\r
+\r
+        //\r
+        // Allocate memory for variable data.\r
+        //\r
+        OcurModelStringBuffer = AllocatePool (OcurModelStringBufferSize);\r
+        Status = gRT->GetVariable (\r
+                        gACPIOSFRModelStringVariableName,\r
+                        &gACPIOSFRModelStringVariableGuid,\r
+                        NULL,\r
+                        &OcurModelStringBufferSize,\r
+                        OcurModelStringBuffer\r
+                        );\r
+        if (!EFI_ERROR (Status)) {\r
+          OcurRefDataBlockBufferSize = 0;\r
+          Status = gRT->GetVariable (\r
+                          gACPIOSFRRefDataBlockVariableName,\r
+                          &gACPIOSFRRefDataBlockVariableGuid,\r
+                          NULL,\r
+                          &OcurRefDataBlockBufferSize,\r
+                          NULL\r
+                          );\r
+          if (Status == EFI_BUFFER_TOO_SMALL) {\r
+            //\r
+            // Allocate memory for variable data.\r
+            //\r
+            OcurRefDataBlockBuffer = AllocatePool (OcurRefDataBlockBufferSize);\r
+            Status = gRT->GetVariable (\r
+                            gACPIOSFRRefDataBlockVariableName,\r
+                            &gACPIOSFRRefDataBlockVariableGuid,\r
+                            NULL,\r
+                            &OcurRefDataBlockBufferSize,\r
+                            OcurRefDataBlockBuffer\r
+                            );\r
+          }\r
+          OsfrTable = (EFI_ACPI_OSFR_TABLE *) Table;\r
+          //\r
+          // Currently only one object is defined: OCUR_OSFR_TABLE.\r
+          //\r
+          OsfrTable->ObjectCount = 1;\r
+          //\r
+          // Initialize table length to fixed portion of the ACPI OSFR table.\r
+          //\r
+          OsfrTable->Header.Length = sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION);\r
+          *(UINT32 *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION)) = \\r
+            (UINT32) (sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + sizeof (UINT32));\r
+          pOcurObject = (EFI_ACPI_OSFR_OCUR_OBJECT *)((UINTN) OsfrTable + sizeof (EFI_ACPI_OSFR_TABLE_FIXED_PORTION) + \\r
+            sizeof (UINT32));\r
+          CopyMem (pOcurObject, &OcurObject, sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));\r
+          pOcurObject->ManufacturerNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \\r
+            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT));\r
+          pOcurObject->ModelNameStringOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \\r
+            sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize);\r
+          if (OcurRefDataBlockBufferSize > 0) {\r
+            pOcurObject->MicrosoftReferenceOffset = (UINT32)((UINTN) pOcurObject - (UINTN) OsfrTable + \\r
+              sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + OcurModelStringBufferSize);\r
+          }\r
+          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT)), OcurMfgStringBuffer, \\r
+            OcurMfgStringBufferSize);\r
+          CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize), \\r
+            OcurModelStringBuffer, OcurModelStringBufferSize);\r
+          if (OcurRefDataBlockBufferSize > 0) {\r
+            CopyMem ((UINTN *)((UINTN) pOcurObject + sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + OcurMfgStringBufferSize + \\r
+            OcurModelStringBufferSize),OcurRefDataBlockBuffer, OcurRefDataBlockBufferSize);\r
+          }\r
+          OsfrTable->Header.Length += (UINT32)(OcurMfgStringBufferSize + OcurModelStringBufferSize + OcurRefDataBlockBufferSize);\r
+          OsfrTable->Header.Length += sizeof (EFI_ACPI_OSFR_OCUR_OBJECT) + sizeof (UINT32);\r
+        }\r
+      }\r
+      gBS->FreePool (OcurMfgStringBuffer);\r
+      gBS->FreePool (OcurModelStringBuffer);\r
+      gBS->FreePool (OcurRefDataBlockBuffer);\r
+      break;\r
+    default:\r
+      break;\r
+  }\r
+\r
+  //\r
+  //\r
+  // Update the hardware signature in the FACS structure.\r
+  //\r
+  //\r
+  // Locate the SPCR table and update based on current settings.\r
+  // The user may change CR settings via setup or other methods.\r
+  // The SPCR table must match.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description.\r
+\r
+Arguments:\r
+\r
+  Event   - GC_TODO: add argument description\r
+  Context - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+OnReadyToBoot (\r
+  IN      EFI_EVENT                 Event,\r
+  IN      VOID                      *Context\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_ACPI_TABLE_VERSION      TableVersion;\r
+  EFI_ACPI_SUPPORT_PROTOCOL   *AcpiSupport;\r
+  EFI_ACPI_S3_SAVE_PROTOCOL   *AcpiS3Save;\r
+  SYSTEM_CONFIGURATION        SetupVarBuffer;\r
+  UINTN                       VariableSize;\r
+  EFI_PLATFORM_CPU_INFO       *PlatformCpuInfoPtr = NULL;\r
+  EFI_PLATFORM_CPU_INFO       PlatformCpuInfo;\r
+  EFI_PEI_HOB_POINTERS          GuidHob;\r
+\r
+  if (mFirstNotify) {\r
+    return;\r
+  }\r
+\r
+  mFirstNotify = TRUE;\r
+\r
+  //\r
+  // To avoid compiler warning of "C4701: potentially uninitialized local variable 'PlatformCpuInfo' used".\r
+  //\r
+  PlatformCpuInfo.CpuVersion.FullCpuId = 0;\r
+\r
+  //\r
+  // Get Platform CPU Info HOB.\r
+  //\r
+  PlatformCpuInfoPtr = NULL;\r
+  ZeroMem (&PlatformCpuInfo, sizeof(EFI_PLATFORM_CPU_INFO));\r
+  VariableSize = sizeof(EFI_PLATFORM_CPU_INFO);\r
+  Status = gRT->GetVariable(\r
+                  EfiPlatformCpuInfoVariable,\r
+                  &gEfiVlv2VariableGuid,\r
+                  NULL,\r
+                  &VariableSize,\r
+                  PlatformCpuInfoPtr\r
+                  );\r
+  if (EFI_ERROR(Status)) {\r
+    GuidHob.Raw = GetHobList ();\r
+    if (GuidHob.Raw != NULL) {\r
+      if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformCpuInfoGuid, GuidHob.Raw)) != NULL) {\r
+        PlatformCpuInfoPtr = GET_GUID_HOB_DATA (GuidHob.Guid);\r
+      }\r
+    }\r
+  }\r
+\r
+  if ((PlatformCpuInfoPtr != NULL)) {\r
+    CopyMem(&PlatformCpuInfo, PlatformCpuInfoPtr, sizeof(EFI_PLATFORM_CPU_INFO));\r
+  }\r
+\r
+  //\r
+  // Update the ACPI parameter blocks finally.\r
+  //\r
+  VariableSize = sizeof (SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable (\r
+                  L"Setup",\r
+                  &mSystemConfigurationGuid,\r
+                  NULL,\r
+                  &VariableSize,\r
+                  &SetupVarBuffer\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Find the AcpiSupport protocol.\r
+  //\r
+  Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  TableVersion = EFI_ACPI_TABLE_VERSION_2_0;\r
+\r
+  //\r
+  // Publish ACPI 1.0 or 2.0 Tables.\r
+  //\r
+  Status = AcpiSupport->PublishTables (\r
+                          AcpiSupport,\r
+                          TableVersion\r
+                          );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // S3 script save.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **) &AcpiS3Save);\r
+  if (!EFI_ERROR (Status)) {\r
+    AcpiS3Save->S3Save (AcpiS3Save, NULL);\r
+  }\r
+\r
+}\r
+\r
+VOID\r
+PR1FSASetting (\r
+  IN VOID\r
+  )\r
+{\r
+  //\r
+  // for FSA on  PR1.\r
+  //\r
+  if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD && mPlatformInfo->BoardRev >= PR1) {\r
+    DEBUG((EFI_D_ERROR, "Set FSA status = 1 for FFRD PR1\n"));\r
+    mGlobalNvsArea.Area->FsaStatus  = mSystemConfiguration.PchFSAOn;\r
+  }\r
+  if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD8) {\r
+    DEBUG((EFI_D_ERROR, "Set FSA status = 1 for FFRD8\n"));\r
+    mGlobalNvsArea.Area->FsaStatus  = mSystemConfiguration.PchFSAOn;\r
+  }\r
+\r
+}\r
+\r
+/**\r
+  Entry point for Acpi platform driver.\r
+\r
+  @param[in]  ImageHandle        A handle for the image that is initializing this driver.\r
+  @param[in]  SystemTable        A pointer to the EFI system table.\r
+\r
+  @retval  EFI_SUCCESS           Driver initialized successfully.\r
+  @retval  EFI_LOAD_ERROR        Failed to Initialize or has been loaded.\r
+  @retval  EFI_OUT_OF_RESOURCES  Could not allocate needed resources.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiPlatformEntryPoint (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_STATUS                    AcpiStatus;\r
+  EFI_ACPI_SUPPORT_PROTOCOL     *AcpiSupport;\r
+  EFI_FIRMWARE_VOLUME_PROTOCOL  *FwVol;\r
+  INTN                          Instance;\r
+  EFI_ACPI_COMMON_HEADER        *CurrentTable;\r
+  UINTN                         TableHandle;\r
+  UINT32                        FvStatus;\r
+  UINT32                        Size;\r
+  EFI_EVENT                     Event;\r
+  EFI_ACPI_TABLE_VERSION        TableVersion;\r
+  UINTN                         VarSize;\r
+  UINTN                         SysCfgSize;\r
+  EFI_HANDLE                    Handle;\r
+  EFI_PS2_POLICY_PROTOCOL       *Ps2Policy;\r
+  EFI_PEI_HOB_POINTERS          GuidHob;\r
+  UINT8                         PortData;\r
+  EFI_MP_SERVICES_PROTOCOL      *MpService;\r
+  UINTN                         MaximumNumberOfCPUs;\r
+  UINTN                         NumberOfEnabledCPUs;\r
+  UINT32                        Data32;\r
+  PCH_STEPPING                  pchStepping;\r
+\r
+  mFirstNotify      = FALSE;\r
+\r
+  TableVersion      = EFI_ACPI_TABLE_VERSION_2_0;\r
+  Instance          = 0;\r
+  CurrentTable      = NULL;\r
+  TableHandle       = 0;\r
+  Data32            = 0;\r
+\r
+  //\r
+  // Update HOB variable for PCI resource information.\r
+  // Get the HOB list.  If it is not present, then ASSERT.\r
+  //\r
+  GuidHob.Raw = GetHobList ();\r
+  if (GuidHob.Raw != NULL) {\r
+    if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformInfoGuid, GuidHob.Raw)) != NULL) {\r
+      mPlatformInfo = GET_GUID_HOB_DATA (GuidHob.Guid);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Search for the Memory Configuration GUID HOB.  If it is not present, then\r
+  // there's nothing we can do. It may not exist on the update path.\r
+  //\r
+  VarSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable(\r
+                  L"Setup",\r
+                  &mSystemConfigurationGuid,\r
+                  NULL,\r
+                  &VarSize,\r
+                  &mSystemConfiguration\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Find the AcpiSupport protocol.\r
+  //\r
+  Status = LocateSupportProtocol (&gEfiAcpiSupportProtocolGuid, (VOID **) &AcpiSupport, 0);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Locate the firmware volume protocol.\r
+  //\r
+  Status = LocateSupportProtocol (&gEfiFirmwareVolumeProtocolGuid, (VOID **) &FwVol, 1);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Read the current system configuration variable store.\r
+  //\r
+  SysCfgSize = sizeof(SYSTEM_CONFIGURATION);\r
+  Status = gRT->GetVariable (\r
+                  L"Setup",\r
+                  &gEfiNormalSetupGuid,\r
+                  NULL,\r
+                  &SysCfgSize,\r
+                  &mSystemConfig\r
+                  );\r
+\r
+  Status    = EFI_SUCCESS;\r
+  Instance  = 0;\r
+\r
+  //\r
+  // TBD: Need re-design based on the ValleyTrail platform.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiMpServiceProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &MpService\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Determine the number of processors.\r
+  //\r
+  MpService->GetNumberOfProcessors (\r
+               MpService,\r
+               &MaximumNumberOfCPUs,\r
+               &NumberOfEnabledCPUs\r
+               );\r
+\r
+  //\r
+  // Allocate and initialize the NVS area for SMM and ASL communication.\r
+  //\r
+  Status = gBS->AllocatePool (\r
+                  EfiACPIMemoryNVS,\r
+                  sizeof (EFI_GLOBAL_NVS_AREA),\r
+                  (void **)&mGlobalNvsArea.Area\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  gBS->SetMem (\r
+         mGlobalNvsArea.Area,\r
+         sizeof (EFI_GLOBAL_NVS_AREA),\r
+         0\r
+         );\r
+  DEBUG((EFI_D_ERROR, "mGlobalNvsArea.Area is at 0x%X\n", mGlobalNvsArea.Area));\r
+\r
+  //\r
+  // Update global NVS area for ASL and SMM init code to use.\r
+  //\r
+  mGlobalNvsArea.Area->ApicEnable                 = 1;\r
+  mGlobalNvsArea.Area->EmaEnable                  = 0;\r
+\r
+  mGlobalNvsArea.Area->NumberOfBatteries          = 1;\r
+  mGlobalNvsArea.Area->BatteryCapacity0           = 100;\r
+  mGlobalNvsArea.Area->BatteryStatus0             = 84;\r
+  mGlobalNvsArea.Area->OnboardCom                 = 1;\r
+  mGlobalNvsArea.Area->IdeMode                    = 0;\r
+  mGlobalNvsArea.Area->PowerState                 = 0;\r
+\r
+  mGlobalNvsArea.Area->LogicalProcessorCount    = (UINT8)NumberOfEnabledCPUs;\r
+\r
+  mGlobalNvsArea.Area->PassiveThermalTripPoint  = mSystemConfiguration.PassiveThermalTripPoint;\r
+  mGlobalNvsArea.Area->PassiveTc1Value          = mSystemConfiguration.PassiveTc1Value;\r
+  mGlobalNvsArea.Area->PassiveTc2Value          = mSystemConfiguration.PassiveTc2Value;\r
+  mGlobalNvsArea.Area->PassiveTspValue          = mSystemConfiguration.PassiveTspValue;\r
+  mGlobalNvsArea.Area->CriticalThermalTripPoint = mSystemConfiguration.CriticalThermalTripPoint;\r
+\r
+  mGlobalNvsArea.Area->IgdPanelType             = mSystemConfiguration.IgdFlatPanel;\r
+  mGlobalNvsArea.Area->IgdPanelScaling          = mSystemConfiguration.PanelScaling;\r
+  mGlobalNvsArea.Area->IgdSciSmiMode            = 0;\r
+  mGlobalNvsArea.Area->IgdTvFormat              = 0;\r
+  mGlobalNvsArea.Area->IgdTvMinor               = 0;\r
+  mGlobalNvsArea.Area->IgdSscConfig             = 1;\r
+  mGlobalNvsArea.Area->IgdBiaConfig             = mSystemConfiguration.IgdLcdIBia;\r
+  mGlobalNvsArea.Area->IgdBlcConfig             = mSystemConfiguration.IgdLcdIGmchBlc;\r
+  mGlobalNvsArea.Area->IgdDvmtMemSize           =  mSystemConfiguration.IgdDvmt50TotalAlloc;\r
+  mGlobalNvsArea.Area->IgdPAVP                  = mSystemConfiguration.PavpMode;\r
+\r
+  mGlobalNvsArea.Area->AlsEnable                = mSystemConfiguration.AlsEnable;\r
+  mGlobalNvsArea.Area->BacklightControlSupport  = 2;\r
+  mGlobalNvsArea.Area->BrightnessPercentage    = 100;\r
+  mGlobalNvsArea.Area->IgdState = 1;\r
+  mGlobalNvsArea.Area->LidState = 1;\r
+\r
+  mGlobalNvsArea.Area->DeviceId1 = 0x80000100 ;\r
+  mGlobalNvsArea.Area->DeviceId2 = 0x80000400 ;\r
+  mGlobalNvsArea.Area->DeviceId3 = 0x80000200 ;\r
+  mGlobalNvsArea.Area->DeviceId4 = 0x04;\r
+  mGlobalNvsArea.Area->DeviceId5 = 0x05;\r
+  mGlobalNvsArea.Area->NumberOfValidDeviceId = 4 ;\r
+  mGlobalNvsArea.Area->CurrentDeviceList = 0x0F ;\r
+  mGlobalNvsArea.Area->PreviousDeviceList = 0x0F ;\r
+\r
+  mGlobalNvsArea.Area->UartSelection = mSystemConfiguration.UartInterface;\r
+  mGlobalNvsArea.Area->PcuUart1Enable = mSystemConfiguration.PcuUart1;\r
+  mGlobalNvsArea.Area->NativePCIESupport = 1;\r
+\r
+\r
+\r
+\r
+\r
+  //\r
+  // Update BootMode: 0:ACPI mode; 1:PCI mode\r
+  //\r
+  mGlobalNvsArea.Area->LpssSccMode = mSystemConfiguration.LpssPciModeEnabled;\r
+  if (mSystemConfiguration.LpssMipiHsi == 0) {\r
+    mGlobalNvsArea.Area->MipiHsiAddr  = 0;\r
+    mGlobalNvsArea.Area->MipiHsiLen   = 0;\r
+    mGlobalNvsArea.Area->MipiHsi1Addr = 0;\r
+    mGlobalNvsArea.Area->MipiHsi1Len  = 0;\r
+  }\r
+\r
+  //\r
+  // Platform Flavor\r
+  //\r
+  mGlobalNvsArea.Area->PlatformFlavor = mPlatformInfo->PlatformFlavor;\r
+\r
+  //\r
+  // Update the Platform id\r
+  //\r
+  mGlobalNvsArea.Area->BoardID = mPlatformInfo->BoardId;\r
+\r
+  //\r
+  // Update the  Board Revision\r
+  //\r
+  mGlobalNvsArea.Area->FabID = mPlatformInfo->BoardRev;\r
+\r
+  //\r
+  // Update SOC Stepping\r
+  //\r
+  mGlobalNvsArea.Area->SocStepping = (UINT8)(PchStepping());\r
+\r
+  mGlobalNvsArea.Area->OtgMode = mSystemConfiguration.PchUsbOtg;\r
+\r
+  pchStepping = PchStepping();\r
+  if (mSystemConfiguration.UsbAutoMode == 1) {\r
+    //\r
+    // Auto mode is enabled.\r
+    //\r
+    if (PchA0 == pchStepping) {\r
+      //\r
+      //  For A0, EHCI is enabled as default.\r
+      //\r
+      mSystemConfiguration.PchUsb20       = 1;\r
+      mSystemConfiguration.PchUsb30Mode   = 0;\r
+      mSystemConfiguration.UsbXhciSupport = 0;\r
+      DEBUG ((EFI_D_INFO, "EHCI is enabled as default. SOC 0x%x\n", pchStepping));\r
+    } else {\r
+      //\r
+      //  For A1 and later, XHCI is enabled as default.\r
+      //\r
+      mSystemConfiguration.PchUsb20       = 0;\r
+      mSystemConfiguration.PchUsb30Mode   = 1;\r
+      mSystemConfiguration.UsbXhciSupport = 1;\r
+      DEBUG ((EFI_D_INFO, "XHCI is enabled as default. SOC 0x%x\n", pchStepping));\r
+    }\r
+  }\r
+\r
+  mGlobalNvsArea.Area->XhciMode = mSystemConfiguration.PchUsb30Mode;\r
+\r
+  mGlobalNvsArea.Area->Stepping = mPlatformInfo->IchRevision;\r
+\r
+  //\r
+  // Override invalid Pre-Boot Driver and XhciMode combination.\r
+  //\r
+  if ((mSystemConfiguration.UsbXhciSupport == 0) && (mSystemConfiguration.PchUsb30Mode == 3)) {\r
+    mGlobalNvsArea.Area->XhciMode = 2;\r
+  }\r
+  if ((mSystemConfiguration.UsbXhciSupport == 1) && (mSystemConfiguration.PchUsb30Mode == 2)) {\r
+    mGlobalNvsArea.Area->XhciMode = 3;\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "ACPI NVS XHCI:0x%x\n", mGlobalNvsArea.Area->XhciMode));\r
+\r
+  mGlobalNvsArea.Area->PmicEnable                       = GLOBAL_NVS_DEVICE_DISABLE;\r
+  mGlobalNvsArea.Area->BatteryChargingSolution          = GLOBAL_NVS_DEVICE_DISABLE;\r
+  mGlobalNvsArea.Area->ISPDevSel                        = mSystemConfiguration.ISPDevSel;\r
+  mGlobalNvsArea.Area->LpeEnable                        = mSystemConfiguration.Lpe;\r
+\r
+  if (mSystemConfiguration.ISPEn == 0) {\r
+    mGlobalNvsArea.Area->ISPDevSel                      = GLOBAL_NVS_DEVICE_DISABLE;\r
+  }\r
+\r
+  mGlobalNvsArea.Area->WittEnable                       = mSystemConfiguration.WittEnable;\r
+  mGlobalNvsArea.Area->UtsEnable                        = mSystemConfiguration.UtsEnable;\r
+  mGlobalNvsArea.Area->SarEnable                        = mSystemConfiguration.SAR1;\r
+\r
+\r
+  mGlobalNvsArea.Area->ReservedO                        = 1;\r
+\r
+  SettingI2CTouchAddress();\r
+  mGlobalNvsArea.Area->IdleReserve= mSystemConfiguration.IdleReserve;\r
+  //\r
+  // Read BMBOUND and store it in GlobalNVS to pass into ASL.\r
+  //\r
+  // BUGBUG: code was moved into silicon reference code.\r
+  //\r
+  if (mSystemConfiguration.eMMCBootMode== 1) {\r
+    //\r
+    // Auto detect mode.\r
+    //\r
+    DEBUG ((EFI_D_ERROR, "Auto detect mode------------start\n"));\r
+\r
+    //\r
+    // Silicon Steppings.\r
+    //\r
+    switch (PchStepping()) {\r
+      case PchA0: // A0/A1\r
+      case PchA1:\r
+        DEBUG ((EFI_D_ERROR, "SOC A0/A1: eMMC 4.41 Configuration\n"));\r
+        mSystemConfiguration.LpsseMMCEnabled            = 1;\r
+        mSystemConfiguration.LpsseMMC45Enabled          = 0;\r
+        break;\r
+\r
+      case PchB0: // B0 and later.\r
+      default:\r
+        DEBUG ((EFI_D_ERROR, "SOC B0 and later: eMMC 4.5 Configuration\n"));\r
+        mSystemConfiguration.LpsseMMCEnabled            = 0;\r
+        mSystemConfiguration.LpsseMMC45Enabled          = 1;\r
+        break;\r
+   }\r
+  } else if (mSystemConfiguration.eMMCBootMode == 2) {\r
+      //\r
+      // eMMC 4.41\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.41 Configuration\n"));\r
+      mSystemConfiguration.LpsseMMCEnabled            = 1;\r
+      mSystemConfiguration.LpsseMMC45Enabled          = 0;\r
+  } else if (mSystemConfiguration.eMMCBootMode == 3) {\r
+      //\r
+      // eMMC 4.5\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Force to eMMC 4.5 Configuration\n"));\r
+      mSystemConfiguration.LpsseMMCEnabled            = 0;\r
+      mSystemConfiguration.LpsseMMC45Enabled          = 1;\r
+\r
+  } else {\r
+      //\r
+      // Disable eMMC controllers.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Disable eMMC controllers\n"));\r
+      mSystemConfiguration.LpsseMMCEnabled            = 0;\r
+      mSystemConfiguration.LpsseMMC45Enabled          = 0;\r
+  }\r
+\r
+  mGlobalNvsArea.Area->emmcVersion = 0;\r
+  if (mSystemConfiguration.LpsseMMCEnabled) {\r
+     DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 0\n"));\r
+     mGlobalNvsArea.Area->emmcVersion = 0;\r
+  }\r
+\r
+  if (mSystemConfiguration.LpsseMMC45Enabled) {\r
+     DEBUG ((EFI_D_ERROR, "mGlobalNvsArea.Area->emmcVersion = 1\n"));\r
+     mGlobalNvsArea.Area->emmcVersion = 1;\r
+  }\r
+\r
+  mGlobalNvsArea.Area->SdCardRemovable = mSystemConfiguration.SdCardRemovable;\r
+  \r
+  //\r
+  // Microsoft IOT\r
+  //\r
+  if ((mSystemConfiguration.LpssHsuart0FlowControlEnabled == 1) && \\r
+      (mSystemConfiguration.LpssPwm0Enabled == 0) && \\r
+      (mSystemConfiguration.LpssPwm1Enabled == 0)) {\r
+    mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_ENABLE;\r
+    DEBUG ((EFI_D_ERROR, "JP1 is set to be MSFT IOT configuration.\n"));\r
+  } else {\r
+    mGlobalNvsArea.Area->MicrosoftIoT = GLOBAL_NVS_DEVICE_DISABLE;\r
+    DEBUG ((EFI_D_ERROR, "JP1 is not set to be MSFT IOT configuration.\n"));\r
+  }\r
+  \r
+  //\r
+  // SIO related option.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (void **)&mCpuIo);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_DISABLE;\r
+\r
+  mGlobalNvsArea.Area->DockedSioPresent = GLOBAL_NVS_DEVICE_DISABLE;\r
+\r
+  if (mGlobalNvsArea.Area->DockedSioPresent != GLOBAL_NVS_DEVICE_ENABLE) {\r
+    //\r
+    // Check ID for SIO WPCN381U.\r
+    //\r
+    Status = mCpuIo->Io.Read (\r
+                          mCpuIo,\r
+                          EfiCpuIoWidthUint8,\r
+                          WPCN381U_CONFIG_INDEX,\r
+                          1,\r
+                          &PortData\r
+                          );\r
+    ASSERT_EFI_ERROR (Status);\r
+    if (PortData != 0xFF) {\r
+      PortData = 0x20;\r
+      Status = mCpuIo->Io.Write (\r
+                            mCpuIo,\r
+                            EfiCpuIoWidthUint8,\r
+                            WPCN381U_CONFIG_INDEX,\r
+                            1,\r
+                            &PortData\r
+                            );\r
+      ASSERT_EFI_ERROR (Status);\r
+      Status = mCpuIo->Io.Read (\r
+                            mCpuIo,\r
+                            EfiCpuIoWidthUint8,\r
+                            WPCN381U_CONFIG_DATA,\r
+                            1,\r
+                            &PortData\r
+                            );\r
+      ASSERT_EFI_ERROR (Status);\r
+      if ((PortData == WPCN381U_CHIP_ID) || (PortData == WDCP376_CHIP_ID)) {\r
+        mGlobalNvsArea.Area->WPCN381U = GLOBAL_NVS_DEVICE_ENABLE;\r
+        mGlobalNvsArea.Area->OnboardCom = GLOBAL_NVS_DEVICE_ENABLE;\r
+        mGlobalNvsArea.Area->OnboardComCir = GLOBAL_NVS_DEVICE_DISABLE;\r
+      }\r
+    }\r
+  }\r
+\r
+\r
+\r
+  //\r
+  // Get Ps2 policy to set. Will be use if present.\r
+  //\r
+  Status =  gBS->LocateProtocol (\r
+                   &gEfiPs2PolicyProtocolGuid,\r
+                   NULL,\r
+                   (VOID **)&Ps2Policy\r
+                   );\r
+  if (!EFI_ERROR (Status)) {\r
+          Status = Ps2Policy->Ps2InitHardware (ImageHandle);\r
+  }\r
+\r
+  mGlobalNvsArea.Area->SDIOMode = mSystemConfiguration.LpssSdioMode;\r
+\r
+  Handle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Handle,\r
+                  &gEfiGlobalNvsAreaProtocolGuid,\r
+                  &mGlobalNvsArea,\r
+                  NULL\r
+                  );\r
+\r
+  //\r
+  // Read tables from the storage file.\r
+  //\r
+  while (!EFI_ERROR (Status)) {\r
+    CurrentTable = NULL;\r
+\r
+    Status = FwVol->ReadSection (\r
+                      FwVol,\r
+                      &gEfiAcpiTableStorageGuid,\r
+                      EFI_SECTION_RAW,\r
+                      Instance,\r
+                      (VOID **) &CurrentTable,\r
+                      (UINTN *) &Size,\r
+                      &FvStatus\r
+                      );\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Allow platform specific code to reject the table or update it.\r
+      //\r
+      AcpiStatus = AcpiPlatformHooksIsActiveTable (CurrentTable);\r
+\r
+      if (!EFI_ERROR (AcpiStatus)) {\r
+        //\r
+        // Perform any table specific updates.\r
+        //\r
+        AcpiStatus = PlatformUpdateTables (CurrentTable);\r
+        if (!EFI_ERROR (AcpiStatus)) {\r
+          //\r
+          // Add the table.\r
+          //\r
+          TableHandle = 0;\r
+          AcpiStatus = AcpiSupport->SetAcpiTable (\r
+                                      AcpiSupport,\r
+                                      CurrentTable,\r
+                                      TRUE,\r
+                                      TableVersion,\r
+                                      &TableHandle\r
+                                      );\r
+          ASSERT_EFI_ERROR (AcpiStatus);\r
+        }\r
+      }\r
+\r
+      //\r
+      // Increment the instance.\r
+      //\r
+      Instance++;\r
+    }\r
+  }\r
+\r
+  Status = EfiCreateEventReadyToBootEx (\r
+             TPL_NOTIFY,\r
+             OnReadyToBoot,\r
+             NULL,\r
+             &Event\r
+             );\r
+\r
+  //\r
+  // Finished.\r
+  //\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+UINT8\r
+ReadCmosBank1Byte (\r
+  IN  UINT8                           Index\r
+  )\r
+{\r
+  UINT8                               Data;\r
+\r
+  IoWrite8(0x72, Index);\r
+  Data = IoRead8 (0x73);\r
+  return Data;\r
+}\r
+\r
+VOID\r
+WriteCmosBank1Byte (\r
+  IN  UINT8                           Index,\r
+  IN  UINT8                           Data\r
+  )\r
+{\r
+  IoWrite8 (0x72, Index);\r
+  IoWrite8 (0x73, Data);\r
+}\r
+\r
+\r
+\r
+VOID\r
+SettingI2CTouchAddress (\r
+  IN VOID\r
+  )\r
+{\r
+  if (mSystemConfiguration.I2CTouchAd == 0) {\r
+    //\r
+    // If setup menu select auto set I2C Touch Address base on board id.\r
+    //\r
+    if (mPlatformInfo->BoardId == BOARD_ID_BL_RVP ||\r
+        mPlatformInfo->BoardId == BOARD_ID_BL_STHI ||\r
+        mPlatformInfo->BoardId == BOARD_ID_BL_RVP_DDR3L ) {\r
+      //\r
+      //RVP\r
+      //\r
+      mGlobalNvsArea.Area->I2CTouchAddress = 0x4B;\r
+    } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD) {\r
+      //\r
+      //FFRD\r
+      //\r
+      mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;\r
+    } else if (mPlatformInfo->BoardId == BOARD_ID_BB_RVP) {\r
+      mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;\r
+    } else if (mPlatformInfo->BoardId == BOARD_ID_CVH) {\r
+      mGlobalNvsArea.Area->I2CTouchAddress = 0x4C;\r
+    } else if (mPlatformInfo->BoardId == BOARD_ID_BL_FFRD8) {\r
+      //\r
+      //FFRD8 uses 0x4A.\r
+      //\r
+      mGlobalNvsArea.Area->I2CTouchAddress = 0x4A;\r
+    }\r
+  } else {\r
+    mGlobalNvsArea.Area->I2CTouchAddress = mSystemConfiguration.I2CTouchAd;\r
+  }\r
+  DEBUG((EFI_D_ERROR, "GlobalNvsArea.Area->I2CTouchAddress: [%02x]\n", mGlobalNvsArea.Area->I2CTouchAddress));\r
+}\r
+\r
+\r