Browse Source

Platform/Vlv2TbltDevicePkg: Import Vlv2TbltDevicePkg from edk2

https://bugzilla.tianocore.org/show_bug.cgi?id=1374

Import Vlv2TbltDevicePkg from edk2/master.

Cc: Zailiang Sun <zailiang.sun@intel.com>
Cc: Yi Qian <yi.qian@intel.com>
Cc: Michael Kubacki <michael.a.kubacki@intel.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Zailiang Sun <zailiang.sun@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Michael D Kinney 5 years ago
parent
commit
31a2b7d34b
100 changed files with 15222 additions and 0 deletions
  1. 5 0
      Platform/Intel/Vlv2TbltDevicePkg/.gitignore
  2. 1338 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c
  3. 219 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h
  4. 89 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf
  5. 493 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c
  6. 127 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h
  7. 91 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h
  8. 56 0
      Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h
  9. 922 0
      Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
  10. 185 0
      Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
  11. 83 0
      Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf
  12. 45 0
      Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni
  13. BIN
      Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe
  14. 25 0
      Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env
  15. 25 0
      Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env
  16. 25 0
      Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env
  17. 25 0
      Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env
  18. 60 0
      Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf
  19. 102 0
      Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h
  20. 626 0
      Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
  21. 200 0
      Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat
  22. 104 0
      Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh
  23. BIN
      Platform/Intel/Vlv2TbltDevicePkg/FCE.exe
  24. 35 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat
  25. 28 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh
  26. 131 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat
  27. 65 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh
  28. 131 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat
  29. 65 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh
  30. 137 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat
  31. 70 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh
  32. 14 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf
  33. 139 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat
  34. 139 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat
  35. 145 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat
  36. 1 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
  37. 1 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
  38. 1 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
  39. 27 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml
  40. 589 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c
  41. 46 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf
  42. 412 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c
  43. 34 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
  44. 685 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
  45. 54 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf
  46. 83 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc
  47. 40 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf
  48. 60 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c
  49. 66 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini
  50. 66 0
      Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini
  51. 55 0
      Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc
  52. 22 0
      Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc
  53. 55 0
      Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc
  54. 59 0
      Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc
  55. 55 0
      Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc
  56. BIN
      Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin
  57. 42 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c
  58. 40 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf
  59. 421 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c
  60. 74 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf
  61. 144 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c
  62. 82 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf
  63. 45 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm
  64. 45 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc
  65. 135 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm
  66. 338 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm
  67. 71 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S
  68. 76 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm
  69. 36 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c
  70. 108 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c
  71. 83 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c
  72. 77 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c
  73. 16 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c
  74. 149 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c
  75. 192 0
      Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c
  76. 68 0
      Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c
  77. 49 0
      Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf
  78. 170 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c
  79. 80 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf
  80. 1098 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c
  81. 182 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h
  82. 199 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
  83. 127 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c
  84. 82 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf
  85. 73 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h
  86. 944 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c
  87. 232 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h
  88. 50 0
      Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf
  89. BIN
      Platform/Intel/Vlv2TbltDevicePkg/GenBiosId
  90. BIN
      Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe
  91. 122 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h
  92. 28 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h
  93. 115 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h
  94. 59 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h
  95. 499 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h
  96. 30 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h
  97. 86 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h
  98. 30 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h
  99. 214 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h
  100. 156 0
      Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h

+ 5 - 0
Platform/Intel/Vlv2TbltDevicePkg/.gitignore

@@ -0,0 +1,5 @@
+AutoPlatformCFG.txt
+Stitch/Stitching.log
+Stitch/MNW*.bin
+Stitch/MNW*.rom
+Stitch/MNW*.rom.orig

+ 1338 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.c

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

+ 219 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.h

@@ -0,0 +1,219 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+  AcpiPlatform.h
+
+Abstract:
+
+  This is an implementation of the ACPI platform driver.  Requirements for
+  this driver are defined in the Tiano ACPI External Product Specification,
+  revision 0.3.6.
+
+
+--*/
+
+#ifndef _ACPI_PLATFORM_H_
+#define _ACPI_PLATFORM_H_
+
+//
+// Statements that include other header files.
+//
+#include <FrameworkDxe.h>
+#include <PiDxe.h>
+#include <Base.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareVolume.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/MpService.h>
+#include <Protocol/CpuIo.h>
+#include <IndustryStandard/Acpi30.h>
+#include <IndustryStandard/Acpi20.h>
+#include <Library/HobLib.h>
+#include <AlertStandardFormatTable.h>
+#include <Guid/SetupVariable.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <PchRegs.h>
+#include <Library/PchPlatformLib.h>
+//
+// Global variables.
+//
+extern EFI_GLOBAL_NVS_AREA_PROTOCOL  mGlobalNvsArea;
+
+//
+// ACPI table information used to initialize tables.
+#define EFI_ACPI_OEM_REVISION     0x00000003
+#define EFI_ACPI_CREATOR_ID       SIGNATURE_32 ('V', 'L', 'V', '2')
+#define EFI_ACPI_CREATOR_REVISION 0x0100000D
+
+#define WPCN381U_CONFIG_INDEX     0x2E
+#define WPCN381U_CONFIG_DATA      0x2F
+#define WPCN381U_CHIP_ID          0xF4
+#define WDCP376_CHIP_ID           0xF1
+
+#define MOBILE_PLATFORM 1
+#define DESKTOP_PLATFORM 2
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#ifndef EFI_SIGNATURE_16
+#define EFI_SIGNATURE_16(A, B)        ((A) | (B << 8))
+#endif
+#ifndef EFI_SIGNATURE_32
+#define EFI_SIGNATURE_32(A, B, C, D)  (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#endif
+#ifndef EFI_SIGNATURE_64
+#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \
+    (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32))
+#endif
+
+
+#define GV3_SSDT_OEM_TABLE_IDBASE 0x4000
+
+//
+// Private Driver Data.
+//
+//
+// Define Union of IO APIC & Local APIC structure.
+//
+typedef union {
+  EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE AcpiLocalApic;
+  EFI_ACPI_2_0_IO_APIC_STRUCTURE              AcpiIoApic;
+  struct {
+    UINT8 Type;
+    UINT8 Length;
+  } AcpiApicCommon;
+} ACPI_APIC_STRUCTURE_PTR;
+
+//
+// Protocol private structure definition.
+//
+
+/**
+  Entry point of the ACPI platform driver.
+
+  @param[in]  ImageHandle        EFI_HANDLE: A handle for the image that is initializing this driver.
+  @param[in]  SystemTable        EFI_SYSTEM_TABLE: A pointer to the EFI system table.
+
+  @retval  EFI_SUCCESS           Driver initialized successfully.
+  @retval  EFI_LOAD_ERROR        Failed to Initialize or has been loaded.
+  @retval  EFI_OUT_OF_RESOURCES  Could not allocate needed resources.
+
+**/
+EFI_STATUS
+InstallAcpiPlatform (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+/**
+  Get Acpi Table Version.
+
+  @param[in]  ImageHandle          EFI_HANDLE: A handle for the image that is initializing this driver.
+  @param[in]  SystemTable          EFI_SYSTEM_TABLE: A pointer to the EFI system table.
+
+  @retval  EFI_SUCCESS:            Driver initialized successfully.
+  @retval  EFI_LOAD_ERROR:         Failed to Initialize or has been loaded.
+  @retval  EFI_OUT_OF_RESOURCES:   Could not allocate needed resources.
+
+--*/
+EFI_ACPI_TABLE_VERSION
+GetAcpiTableVersion (
+  VOID
+  );
+
+/**
+  The funtion returns Oem specific information of Acpi Platform.
+
+  @param[in]  OemId          OemId returned.
+  @param[in]  OemTableId     OemTableId returned.
+  @param[in]  OemRevision    OemRevision returned.
+
+  @retval  EFI_STATUS        Status of function execution.
+
+**/
+EFI_STATUS
+AcpiPlatformGetOemFields (
+  OUT UINT8   *OemId,
+  OUT UINT64  *OemTableId,
+  OUT UINT32  *OemRevision
+  );
+
+/**
+  The function returns Acpi table version.
+
+  @param[in]
+
+  @retval  EFI_ACPI_TABLE_VERSION   Acpi table version encoded as a UINT32.
+
+**/
+EFI_ACPI_TABLE_VERSION
+AcpiPlatformGetAcpiSetting (
+  VOID
+  );
+
+/**
+  Entry point for Acpi platform driver.
+
+  @param[in]  ImageHandle        A handle for the image that is initializing this driver.
+  @param[in]  SystemTable        A pointer to the EFI system table.
+
+  @retval  EFI_SUCCESS           Driver initialized successfully.
+  @retval  EFI_LOAD_ERROR        Failed to Initialize or has been loaded.
+  @retval  EFI_OUT_OF_RESOURCES  Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPlatformEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+UINT8
+ReadCmosBank1Byte (
+  IN  UINT8                           Index
+  );
+
+VOID
+WriteCmosBank1Byte (
+  IN  UINT8                           Index,
+  IN  UINT8                           Data
+  );
+
+VOID
+SelectNFCDevice (
+  IN VOID
+  );
+
+VOID
+SettingI2CTouchAddress (
+  IN VOID
+  );
+
+extern 
+EFI_STATUS 
+EFIAPI
+IsctDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  );
+
+#endif

+ 89 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf

@@ -0,0 +1,89 @@
+#
+#
+# Copyright (c)  1999  - 2019, Intel Corporation. All rights reserved
+#
+
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#
+
+#
+#
+#  Module Name:
+#
+#   AcpiPlatformBB.inf
+#
+#  Abstract:
+#
+#
+
+
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = AcpiPlatform
+  FILE_GUID                      = F0F6F006-DAB4-44b2-A7A1-0F72EEDCA716
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiPlatformEntryPoint
+
+[sources.common]
+  AcpiPlatformHooks.c
+  AcpiPlatform.c
+
+[Packages]
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  HobLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  PchPlatformLib
+
+[Guids]
+  gACPIOSFRMfgStringVariableGuid
+  gEfiAcpiTableStorageGuid
+  gACPIOSFRMfgStringVariableGuid
+  gEfiBoardFeaturesGuid
+  gEfiPlatformInfoGuid
+  gEfiNormalSetupGuid
+  gACPIOSFRRefDataBlockVariableGuid
+  gACPIOSFRModelStringVariableGuid
+  gEfiPlatformCpuInfoGuid
+  gEfiVlv2VariableGuid
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+  gEnhancedSpeedstepProtocolGuid
+  gEfiPlatformCpuProtocolGuid
+  gEfiAcpiSupportProtocolGuid
+  gEfiAcpiS3SaveProtocolGuid
+  gEfiCpuIoProtocolGuid
+  gEfiPs2PolicyProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gEfiMpServiceProtocolGuid
+  gEfiGlobalNvsAreaProtocolGuid
+  gEfiTcgProtocolGuid
+  gEfiFirmwareVolume2ProtocolGuid
+  gIgdOpRegionProtocolGuid
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile
+
+[Depex]
+  gEfiVariableArchProtocolGuid        AND
+  gEfiVariableWriteArchProtocolGuid   AND
+  gEfiAcpiSupportProtocolGuid AND
+  gEfiMpServiceProtocolGuid AND
+  gEfiCpuIoProtocolGuid
+

+ 493 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.c

@@ -0,0 +1,493 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  AcpiPlatformHooks.c
+
+Abstract:
+
+  ACPI Platform Driver Hooks
+
+--*/
+
+//
+// Statements that include other files.
+//
+#include "AcpiPlatform.h"
+#include "AcpiPlatformHooks.h"
+#include "Platform.h"
+
+//
+// Prototypes of the various hook functions.
+//
+#include "AcpiPlatformHooksLib.h"
+
+extern SYSTEM_CONFIGURATION             mSystemConfiguration;
+
+ENHANCED_SPEEDSTEP_PROTOCOL             *mEistProtocol  = NULL;
+
+EFI_CPU_ID_MAP              mCpuApicIdAcpiIdMapTable[MAX_CPU_NUM];
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+  IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE   *AcpiLocalApic
+  )
+{
+  BOOLEAN Added;
+  UINTN   Index;
+
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if ((mCpuApicIdAcpiIdMapTable[Index].ApicId == AcpiLocalApic->ApicId) && mCpuApicIdAcpiIdMapTable[Index].Flags) {
+      return EFI_SUCCESS;
+    }
+  }
+
+  Added = FALSE;
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+      if (!mCpuApicIdAcpiIdMapTable[Index].Flags) {
+        mCpuApicIdAcpiIdMapTable[Index].Flags           = 1;
+        mCpuApicIdAcpiIdMapTable[Index].ApicId          = AcpiLocalApic->ApicId;
+        mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId = AcpiLocalApic->AcpiProcessorId;
+      Added = TRUE;
+      break;
+    }
+  }
+
+  ASSERT (Added);
+  return EFI_SUCCESS;
+}
+
+UINT32
+ProcessorId2ApicId (
+  UINT32  AcpiProcessorId
+  )
+{
+  UINTN Index;
+
+  ASSERT (AcpiProcessorId < MAX_CPU_NUM);
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if (mCpuApicIdAcpiIdMapTable[Index].Flags && (mCpuApicIdAcpiIdMapTable[Index].AcpiProcessorId == AcpiProcessorId)) {
+      return mCpuApicIdAcpiIdMapTable[Index].ApicId;
+    }
+  }
+
+  return (UINT32) -1;
+}
+
+UINT8
+GetProcNumberInPackage (
+  IN UINT8  Package
+  )
+{
+  UINTN Index;
+  UINT8 Number;
+
+  Number = 0;
+  for (Index = 0; Index < MAX_CPU_NUM; Index++) {
+    if (mCpuApicIdAcpiIdMapTable[Index].Flags && (((mCpuApicIdAcpiIdMapTable[Index].ApicId >> 0x04) & 0x01) == Package)) {
+      Number++;
+    }
+  }
+
+  return Number;
+}
+
+EFI_STATUS
+LocateCpuEistProtocol (
+  IN UINT32                           CpuIndex,
+  OUT ENHANCED_SPEEDSTEP_PROTOCOL     **EistProtocol
+  )
+{
+  UINTN                       HandleCount;
+  EFI_HANDLE                  *HandleBuffer;
+  ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;
+  UINTN                       Index;
+  UINT32                      ApicId;
+  EFI_STATUS                  Status;
+
+  HandleCount = 0;
+  gBS->LocateHandleBuffer (
+         ByProtocol,
+         &gEnhancedSpeedstepProtocolGuid,
+         NULL,
+         &HandleCount,
+         &HandleBuffer
+         );
+
+  Index     = 0;
+  EistProt  = NULL;
+  Status    = EFI_NOT_FOUND;
+  while (Index < HandleCount) {
+    gBS->HandleProtocol (
+           HandleBuffer[Index],
+           &gEnhancedSpeedstepProtocolGuid,
+          (VOID **) &EistProt
+           );
+    //
+    // Adjust the CpuIndex by +1 due to the AcpiProcessorId is 1 based.
+    //
+    ApicId = ProcessorId2ApicId (CpuIndex+1);
+    if (ApicId == (UINT32) -1) {
+      break;
+    }
+
+    if (EistProt->ProcApicId == ApicId) {
+      Status = EFI_SUCCESS;
+      break;
+    }
+
+    Index++;
+  }
+
+  if (HandleBuffer != NULL) {
+    gBS->FreePool (HandleBuffer);
+  }
+
+  if (!EFI_ERROR (Status)) {
+    *EistProtocol = EistProt;
+  } else {
+    *EistProtocol = NULL;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+PlatformHookInit (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol (
+                  &gEnhancedSpeedstepProtocolGuid,
+                  NULL,
+                  (VOID **) &mEistProtocol
+                  );
+
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Called for every ACPI table found in the BIOS flash.
+  Returns whether a table is active or not. Inactive tables
+  are not published in the ACPI table list.
+
+  This hook can be used to implement optional SSDT tables or
+  enabling/disabling specific functionality (e.g. SPCR table)
+  based on a setup switch or platform preference. In case of
+  optional SSDT tables,the platform flash will include all the
+  SSDT tables but will return EFI_SUCCESS only for those tables
+  that need to be published.
+
+  @param[in]  *Table         Pointer to the active table.
+
+  @retval  EFI_SUCCESS       if the table is active.
+  @retval  EFI_UNSUPPORTED   if the table is not active.
+
+**/
+EFI_STATUS
+AcpiPlatformHooksIsActiveTable (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  )
+{
+  EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
+
+  TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *) Table;
+
+  if (TableHeader->Signature == EFI_ACPI_2_0_STATIC_RESOURCE_AFFINITY_TABLE_SIGNATURE) {
+
+  }
+
+  if ((mSystemConfiguration.ENDBG2 == 0) && (CompareMem (&TableHeader->OemTableId, "INTLDBG2", 8) == 0)) {
+    return EFI_UNSUPPORTED;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+    Update the GV3 SSDT table.
+
+    @param[in][out]  *TableHeader   The table to be set.
+
+    @retval  EFI_SUCCESS            Returns Success.
+
+**/
+EFI_STATUS
+PatchGv3SsdtTable (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader
+  )
+{
+  UINT8                       *CurrPtr;
+  UINT8                       *SsdtPointer;
+  UINT32                      Signature;
+  UINT32                      CpuFixes;
+  UINT32                      NpssFixes;
+  UINT32                      SpssFixes;
+  UINT32                      CpuIndex;
+  UINT32                      PackageSize;
+  UINT32                      NewPackageSize;
+  UINT32                      AdjustSize;
+  UINTN                       EntryIndex;
+  UINTN                       TableIndex;
+  EFI_ACPI_NAME_COMMAND       *PssTable;
+  EFI_PSS_PACKAGE             *PssTableItemPtr;
+  ENHANCED_SPEEDSTEP_PROTOCOL *EistProt;
+  EIST_INFORMATION            *EistInfo;
+  EFI_ACPI_CPU_PSS_STATE      *PssState;
+  EFI_ACPI_NAMEPACK_DWORD     *NamePtr;
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  NpssFixes = 0;
+  SpssFixes = 0;
+  CpuFixes  = 0;
+  CpuIndex  = 0;
+  CurrPtr   = (UINT8 *) TableHeader;
+
+  EistProt  = NULL;
+  for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {
+    Signature = *(UINT32 *) SsdtPointer;
+    switch (Signature) {
+
+    case SIGNATURE_32 ('_', 'P', 'R', '_'):
+      //
+      // _CPUX ('0' to '0xF')
+      //
+      CpuIndex = *(SsdtPointer + 7);
+      if (CpuIndex >= '0' && CpuIndex <= '9') {
+        CpuIndex -= '0';
+      } else {
+        if (CpuIndex > '9') {
+          CpuIndex -= '7';
+        }
+      }
+
+      CpuFixes++;
+      LocateCpuEistProtocol (CpuIndex, &EistProt);
+      break;
+
+    case SIGNATURE_32 ('D', 'O', 'M', 'N'):
+
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {
+        continue;
+      }
+
+      NamePtr->Value = 0;
+
+        if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {
+          NamePtr->Value = (mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01;
+      }
+      break;
+
+    case SIGNATURE_32 ('N', 'C', 'P', 'U'):
+
+      NamePtr = ACPI_NAME_COMMAND_FROM_NAMEPACK_STR (SsdtPointer);
+      if (NamePtr->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      if (NamePtr->Size != AML_NAME_DWORD_SIZE) {
+        continue;
+      }
+
+        NamePtr->Value = 0;
+        if (mCpuApicIdAcpiIdMapTable[CpuIndex].Flags) {
+          NamePtr->Value = GetProcNumberInPackage ((mCpuApicIdAcpiIdMapTable[CpuIndex].ApicId >> 0x04) & 0x01);
+      }
+      break;
+
+    case SIGNATURE_32 ('N', 'P', 'S', 'S'):
+    case SIGNATURE_32 ('S', 'P', 'S', 'S'):
+      if (EistProt == NULL) {
+        continue;
+      }
+
+      PssTable = ACPI_NAME_COMMAND_FROM_NAME_STR (SsdtPointer);
+      if (PssTable->StartByte != AML_NAME_OP) {
+        continue;
+      }
+
+      EistProt->GetEistTable (EistProt, &EistInfo, (VOID **) &PssState);
+
+      AdjustSize  = PssTable->NumEntries * sizeof (EFI_PSS_PACKAGE);
+      AdjustSize -= EistInfo->NumStates * sizeof (EFI_PSS_PACKAGE);
+      PackageSize     = (PssTable->Size & 0xF) + ((PssTable->Size & 0xFF00) >> 4);
+      NewPackageSize  = PackageSize - AdjustSize;
+      PssTable->Size  = (UINT16) ((NewPackageSize & 0xF) + ((NewPackageSize & 0x0FF0) << 4));
+
+      //
+      // Set most significant two bits of byte zero to 01, meaning two bytes used.
+      //
+      PssTable->Size |= 0x40;
+
+      //
+      // Set unused table to Noop Code.
+      //
+      SetMem( (UINT8 *) PssTable + NewPackageSize + AML_NAME_PREFIX_SIZE, AdjustSize, AML_NOOP_OP);
+      PssTable->NumEntries  = (UINT8) EistInfo->NumStates;
+      PssTableItemPtr       = (EFI_PSS_PACKAGE *) ((UINT8 *) PssTable + sizeof (EFI_ACPI_NAME_COMMAND));
+
+      //
+      // Update the size.
+      //
+      for (TableIndex = 0; TableIndex < EistInfo->NumStates; TableIndex++) {
+        EntryIndex                = EistInfo->NumStates - TableIndex - 1;
+        PssTableItemPtr->CoreFreq = PssState[EntryIndex].CoreFrequency * PssState[EntryIndex].Control;
+        PssTableItemPtr->Power    = PssState[EntryIndex].Power * 1000;
+        if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {
+          PssTableItemPtr->BMLatency    = PssState[EntryIndex].BusMasterLatency;
+          PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency;
+        } else {
+          //
+          // This method should be supported by SMM PPM Handler.
+          //
+          PssTableItemPtr->BMLatency    = PssState[EntryIndex].BusMasterLatency * 2;
+          PssTableItemPtr->TransLatency = PssState[EntryIndex].TransitionLatency * 10;
+        }
+
+        PssTableItemPtr->Control  = PssState[EntryIndex].Control;
+        PssTableItemPtr->Status   = PssState[EntryIndex].Status;
+        PssTableItemPtr++;
+      }
+
+      if (PssTable->NameStr == SIGNATURE_32 ('N', 'P', 'S', 'S')) {
+        NpssFixes++;
+      } else {
+        SpssFixes++;
+      }
+
+      SsdtPointer = (UINT8 *) PssTable + PackageSize;
+      break;
+    }
+  }
+
+  //
+  // N fixes together currently.
+  //
+  ASSERT (CpuFixes == (UINT32) MAX_CPU_NUM);
+  ASSERT (SpssFixes == NpssFixes);
+  ASSERT (CpuFixes >= SpssFixes);
+
+  return EFI_SUCCESS;
+}
+
+/**
+    Update the DSDT table.
+
+    @param[in][out]  *TableHeader   The table to be set.
+
+    @retval  EFI_SUCCESS            Returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+PatchDsdtTable (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader
+  )
+{
+
+  UINT8                              *CurrPtr;
+  UINT8                              *DsdtPointer;
+  UINT32                             *Signature;
+  UINT8                              *EndPtr;
+  UINT8   *Operation;
+  UINT32  *Address;
+  UINT16  *Size;
+
+  //
+  // Fix PCI32 resource "FIX0" -- PSYS system status area
+  //
+  CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];
+  EndPtr = (UINT8*) TableHeader;
+  EndPtr = EndPtr + TableHeader->Length;
+  while (CurrPtr < (EndPtr-2)) {
+    //
+    // Removed the _S3 tag to indicate that we do not support S3. The 4th byte is blank space
+    // since there are only 3 char "_S3".
+    //
+    if (mSystemConfiguration.AcpiSuspendState == 0) {
+      //
+      // For iasl compiler version 20061109.
+      //
+      if ((CurrPtr[0] == '_') && (CurrPtr[1] == 'S') && (CurrPtr[2] == '3') && (CurrPtr[3] == '_')) {
+        break;
+      }
+      //
+      // For iasl compiler version 20040527.
+      //
+      if ((CurrPtr[0] == '\\') && (CurrPtr[1] == '_') && (CurrPtr[2] == 'S') && (CurrPtr[3] == '3')) {
+        break;
+      }
+    }
+    CurrPtr++;
+  }
+  CurrPtr = (UINT8*) &((EFI_ACPI_DESCRIPTION_HEADER*) TableHeader)[0];
+  EndPtr = (UINT8*) TableHeader;
+  EndPtr = EndPtr + TableHeader->Length;
+  while (CurrPtr < (EndPtr-2)) {
+    //
+    // For mipi dsi port select _DEP.
+    //
+    if (mSystemConfiguration.MipiDsi== 1) {
+      //
+      // For iasl compiler version 20061109.
+      //
+      if ((CurrPtr[0] == 'N') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {
+        CurrPtr[0] = '_';
+        break;
+      }
+
+    } else {
+      if ((CurrPtr[0] == 'P') && (CurrPtr[1] == 'D') && (CurrPtr[2] == 'E') && (CurrPtr[3] == 'P')) {
+        CurrPtr[0] = '_';
+        break;
+      }
+
+    }
+    CurrPtr++;
+  }
+  //
+  // Loop through the ASL looking for values that we must fix up.
+  //
+  CurrPtr = (UINT8 *) TableHeader;
+  for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+    Signature = (UINT32 *) DsdtPointer;
+
+    switch (*Signature) {
+    //
+    // GNVS operation region.
+    //
+    case (SIGNATURE_32 ('G', 'N', 'V', 'S')):
+      //
+      // Conditional match.  For Region Objects, the Operator will always be the
+      // byte immediately before the specific name.  Therefore, subtract 1 to check
+      // the Operator.
+      //
+      Operation = DsdtPointer - 1;
+      if (*Operation == AML_OPREGION_OP) {
+        Address   = (UINT32 *) (DsdtPointer + 6);
+        *Address  = (UINT32) (UINTN) mGlobalNvsArea.Area;
+        Size      = (UINT16 *) (DsdtPointer + 11);
+        *Size     = sizeof (EFI_GLOBAL_NVS_AREA);
+      }
+      break;
+    default:
+      break;
+    }
+  }
+  return EFI_SUCCESS;
+}
+

+ 127 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooks.h

@@ -0,0 +1,127 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  AcpiPlatformHooks.h
+
+Abstract:
+
+  This is an implementation of the ACPI platform driver.  Requirements for
+  this driver are defined in the Tiano ACPI External Product Specification,
+  revision 0.3.6.
+
+--*/
+
+#ifndef _ACPI_PLATFORM_HOOKS_H_
+#define _ACPI_PLATFORM_HOOKS_H_
+
+//
+// Statements that include other header files
+//
+
+#include <IndustryStandard/Acpi.h>
+#include "Platform.h"
+#include <Protocol/EnhancedSpeedstep.h>
+
+#define AML_NAME_OP           0x08
+#define AML_METHOD_OP         0x14
+#define AML_OPREGION_OP       0x80
+#define AML_PACKAGE_OP        0x12  // Package operator.
+#define AML_NAME_PREFIX_SIZE  0x06
+#define AML_NAME_DWORD_SIZE   0x0C
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8   AcpiProcessorId;
+  UINT8   ApicId;
+  UINT16  Flags;
+} EFI_CPU_ID_MAP;
+
+typedef struct {
+  UINT8   StartByte;
+  UINT32  NameStr;
+  UINT8   Size;
+  UINT32  Value;
+} EFI_ACPI_NAMEPACK_DWORD;
+
+typedef struct {
+  UINT8   StartByte;
+  UINT32  NameStr;
+  UINT8   OpCode;
+  UINT16  Size;                     // Hardcode to 16bit width because the table we use is fixed size
+  UINT8   NumEntries;
+} EFI_ACPI_NAME_COMMAND;
+
+typedef struct {
+  UINT8   PackageOp;
+  UINT8   PkgLeadByte;
+  UINT8   NumEntries;
+  UINT8   DwordPrefix0;
+  UINT32  CoreFreq;
+  UINT8   DwordPrefix1;
+  UINT32  Power;
+  UINT8   DwordPrefix2;
+  UINT32  TransLatency;
+  UINT8   DwordPrefix3;
+  UINT32  BMLatency;
+  UINT8   DwordPrefix4;
+  UINT32  Control;
+  UINT8   DwordPrefix5;
+  UINT32  Status;
+} EFI_PSS_PACKAGE;
+
+typedef struct {
+  UINT8 PackageOp;
+  UINT8 PkgLeadByte;
+  UINT8 NumEntries;
+  UINT8 BytePrefix0;
+  UINT8 Entries;
+  UINT8 BytePrefix1;
+  UINT8 Revision;
+  UINT8 BytePrefix2;
+  UINT8 Domain;
+  UINT8 BytePrefix3;
+  UINT8 Coordinate;
+  UINT8 BytePrefix4;
+  UINT8 ProcNumber;
+} EFI_PSD_PACKAGE;
+
+#pragma pack()
+
+#define ACPI_NAME_COMMAND_FROM_NAME_STR(a)  BASE_CR (a, EFI_ACPI_NAME_COMMAND, NameStr)
+#define ACPI_NAME_COMMAND_FROM_NAMEPACK_STR(a)  BASE_CR (a, EFI_ACPI_NAMEPACK_DWORD, NameStr)
+
+EFI_STATUS
+PlatformHookInit (
+  VOID
+  );
+
+
+EFI_STATUS
+PatchDsdtTable (
+  IN OUT   EFI_ACPI_DESCRIPTION_HEADER  *TableHeader
+  );
+
+EFI_STATUS
+PatchGv3SsdtTable (
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER *Table
+  );
+
+EFI_STATUS
+PatchErstTable (
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER *Table
+  );
+
+EFI_STATUS
+AppendCpuMapTableEntry (
+  IN EFI_ACPI_2_0_PROCESSOR_LOCAL_APIC_STRUCTURE   *AcpiLocalApic
+  );
+
+#endif

+ 91 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatformHooksLib.h

@@ -0,0 +1,91 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  AcpiPlatformHooksLib.h
+
+Abstract:
+
+  This is an implementation of the ACPI platform driver.  Requirements for
+  this driver are defined in the Tiano ACPI External Product Specification,
+  revision 0.3.6.
+
+--*/
+
+#ifndef _ACPI_PLATFORM_HOOKS_LIB_H_
+#define _ACPI_PLATFORM_HOOKS_LIB_H_
+
+//
+// Statements that include other header files.
+//
+#include <IndustryStandard/Acpi.h>
+
+/**
+  Returns the ACPI table version that the platform wants.
+
+  @param[in]  None
+
+  @retval  EFI_ACPI_TABLE_VERSION_NONE  if ACPI is to be disabled.
+  @retval  EFI_ACPI_TABLE_VERSION_1_0B  if 1.0b.
+  @retval  EFI_ACPI_TABLE_VERSION_2_00  if 2.00.
+**/
+EFI_ACPI_TABLE_VERSION
+AcpiPlatformHooksGetAcpiTableVersion (
+  VOID
+  );
+
+/**
+  Returns the OEMID, OEM Table ID, OEM Revision.
+
+  @param[in]  None
+
+  @retval  OemId        OEM ID string for ACPI tables, maximum 6 ASCII characters.
+                        This is an OEM-supplied string that identifies the OEM.
+  @retval  OemTableId   An OEM-supplied string that the OEM uses to identify
+                        the particular data table. This field is particularly useful
+                        when defining a definition block to distinguish definition block
+                        functions. The OEM assigns each dissimilar table a new OEM Table ID.
+  @retval  OemRevision  An OEM-supplied revision number for ACPI tables.
+                        Larger numbers are assumed to be newer revisions.
+
+**/
+EFI_STATUS
+AcpiPlatformHooksGetOemFields (
+  OUT UINT8   *OemId,
+  OUT UINT64  *OemTableId,
+  OUT UINT32  *OemRevision
+  );
+
+ /**
+  Called for every ACPI table found in the BIOS flash.
+  Returns whether a table is active or not. Inactive tables
+  are not published in the ACPI table list. This hook can be
+  used to implement optional SSDT tables or enabling/disabling
+  specific functionality (e.g. SPCR table) based on a setup
+  switch or platform preference. In case of optional SSDT tables,
+  the platform flash will include all the SSDT tables but will
+  return EFI_SUCCESS only for those tables that need to be
+  published.
+  This hook can also be used to update the table data. The header
+  is updated by the common code. For example, if a platform wants
+  to use an SSDT table to export some platform settings to the
+  ACPI code, it needs to update the data inside that SSDT based
+  on platform preferences in this hook.
+
+  @param[in]  None
+
+  @retval  EFI_SUCCESS      if the table is active.
+  @retval  EFI_UNSUPPORTED  if the table is not active.
+**/
+EFI_STATUS
+AcpiPlatformHooksIsActiveTable (
+  IN OUT EFI_ACPI_COMMON_HEADER     *Table
+  );
+
+#endif

+ 56 - 0
Platform/Intel/Vlv2TbltDevicePkg/AcpiPlatform/Osfr.h

@@ -0,0 +1,56 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  Osfr.h
+
+Abstract:
+
+  This file describes the contents of the ACPI OSFR Table.
+
+--*/
+
+#ifndef _OSFR_H
+#define _OSFR_H
+
+//
+// Statements that include other files.
+//
+#include <IndustryStandard/Acpi10.h>
+#include <IndustryStandard/Acpi20.h>
+
+#pragma pack (1)
+
+#define EFI_ACPI_OSFR_TABLE_REVISION            0x1
+//#define EFI_ACPI_OSFR_TABLE_SIGNATURE           'RFSO'
+#define EFI_ACPI_OSFR_TABLE_SIGNATURE           SIGNATURE_32('O', 'S', 'F', 'R')  //'RFSO'
+
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER          Header;
+  UINT32                               ObjectCount;
+  UINT32                               TableDWORDs [64];
+} EFI_ACPI_OSFR_TABLE;
+
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER          Header;
+  UINT32                               ObjectCount;
+} EFI_ACPI_OSFR_TABLE_FIXED_PORTION;
+
+typedef struct {
+  EFI_GUID  ObjectUUID;
+  UINT32    Reserved1;
+  UINT32    ManufacturerNameStringOffset;
+  UINT32    ModelNameStringOffset;
+  UINT32    Reserved2;
+  UINT32    MicrosoftReferenceOffset;
+} EFI_ACPI_OSFR_OCUR_OBJECT;
+
+#pragma pack ()
+
+#endif

+ 922 - 0
Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c

@@ -0,0 +1,922 @@
+/** @file
+
+Copyright (c) 2007  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include "FirmwareUpdate.h"
+
+EFI_HII_HANDLE  HiiHandle;
+
+//
+// MinnowMax Flash Layout
+//
+//Start (hex)	End (hex)	Length (hex)	Area Name
+//-----------	---------	------------	---------
+//00000000	007FFFFF	00800000	Flash Image
+//
+//00000000	00000FFF	00001000	Descriptor Region
+//00001000	003FFFFF	003FF000	TXE Region
+//00500000	007FFFFF	00400000	BIOS Region
+//
+FV_REGION_INFO mRegionInfo[] = {
+  {FixedPcdGet32 (PcdFlashDescriptorBase), FixedPcdGet32 (PcdFlashDescriptorSize), TRUE},
+  {FixedPcdGet32 (PcdTxeRomBase), FixedPcdGet32 (PcdTxeRomSize), TRUE},
+  {FixedPcdGet32 (PcdBiosRomBase), FixedPcdGet32 (PcdBiosRomSize), TRUE}
+};
+
+UINTN mRegionInfoCount = ARRAY_SIZE (mRegionInfo);
+
+FV_INPUT_DATA mInputData = {0};
+
+EFI_SPI_PROTOCOL  *mSpiProtocol;
+
+EFI_STATUS
+GetRegionIndex (
+  IN  EFI_PHYSICAL_ADDRESS  Address,
+  OUT UINTN                 *RegionIndex
+  )
+{
+  UINTN Index;
+
+  for (Index = 0; Index < mRegionInfoCount; Index++) {
+    if (Address >= mRegionInfo[Index].Base &&
+        Address < (mRegionInfo[Index].Base + mRegionInfo[Index].Size)
+        ) {
+      break;
+    }
+  }
+
+  *RegionIndex = Index;
+  if (Index >= mRegionInfoCount) {
+    return EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+UpdateBlock (
+  IN  EFI_PHYSICAL_ADDRESS  Address
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       Index;
+
+  if (mInputData.FullFlashUpdate) {
+    return TRUE;
+  }
+
+  Status = GetRegionIndex (Address, &Index);
+  if ((!EFI_ERROR(Status)) && mRegionInfo[Index].Update) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+MarkRegionState (
+  IN  EFI_PHYSICAL_ADDRESS  Address,
+  IN  BOOLEAN               Update
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       Index;
+
+  Status = GetRegionIndex (Address, &Index);
+  if (!EFI_ERROR(Status)) {
+    mRegionInfo[Index].Update = Update;
+  }
+
+  return Status;
+}
+
+UINTN
+InternalPrintToken (
+  IN  CONST CHAR16                     *Format,
+  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,
+  IN  VA_LIST                          Marker
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       Return;
+  CHAR16      *Buffer;
+  UINTN       BufferSize;
+
+  ASSERT (Format != NULL);
+  ASSERT (((UINTN) Format & BIT0) == 0);
+  ASSERT (Console != NULL);
+
+  BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);
+
+  Buffer = (CHAR16 *) AllocatePool(BufferSize);
+  ASSERT (Buffer != NULL);
+
+  Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);
+
+  if (Console != NULL && Return > 0) {
+    //
+    // To be extra safe make sure Console has been initialized.
+    //
+    Status = Console->OutputString (Console, Buffer);
+    if (EFI_ERROR (Status)) {
+      Return = 0;
+    }
+  }
+
+  FreePool (Buffer);
+
+  return Return;
+}
+
+UINTN
+EFIAPI
+PrintToken (
+  IN UINT16             Token,
+  IN EFI_HII_HANDLE     Handle,
+  ...
+  )
+{
+  VA_LIST Marker;
+  UINTN   Return;
+  CHAR16  *Format;
+
+  VA_START (Marker, Handle);
+
+  Format = HiiGetString (Handle, Token, NULL);
+  ASSERT (Format != NULL);
+
+  Return = InternalPrintToken (Format, gST->ConOut, Marker);
+
+  FreePool (Format);
+
+  VA_END (Marker);
+
+  return Return;
+}
+
+EFI_STATUS
+ParseCommandLine (
+  IN  UINTN   Argc,
+  IN  CHAR16  **Argv
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       Index;
+
+  //
+  // Check to make sure that the command line has enough arguments for minimal
+  // operation.  The minimum is just the file name.
+  //
+  if (Argc < 2 || Argc > 4) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Loop through command line arguments.
+  //
+  for (Index = 1; Index < Argc; Index++) {
+    //
+    // Make sure the string is valid.
+    //
+    if (StrLen (Argv[Index]) == 0) {;
+      PrintToken (STRING_TOKEN (STR_FWUPDATE_ZEROLENGTH_ARG), HiiHandle);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // Check to see if this is an option or the file name.
+    //
+    if ((Argv[Index])[0] == L'-' || (Argv[Index])[0] == L'/') {
+      //
+      // Parse the arguments.
+      //
+      if ((StrCmp (Argv[Index], L"-h") == 0) ||
+          (StrCmp (Argv[Index], L"--help") == 0) ||
+          (StrCmp (Argv[Index], L"/?") == 0) ||
+          (StrCmp (Argv[Index], L"/h") == 0)) {
+        //
+        // Print Help Information.
+        //
+        return EFI_INVALID_PARAMETER;
+      } else if (StrCmp (Argv[Index], L"-m") == 0) {
+        //
+        // Parse the MAC address here.
+        //
+        Status = ConvertMac(Argv[Index+1]);
+        if (EFI_ERROR(Status)) {
+          PrintToken (STRING_TOKEN (STR_FWUPDATE_INVAILD_MAC), HiiHandle);
+          return Status;
+        }
+
+        //
+        // Save the MAC address to mInputData.MacValue.
+        //
+        mInputData.UpdateMac= TRUE;
+        Index++;
+        } else {
+        //
+        // Invalid option was provided.
+        //
+        return EFI_INVALID_PARAMETER;
+      }
+    }
+    if ((Index == Argc - 1) && (StrCmp (Argv[Index - 1], L"-m") != 0)) {
+      //
+      // The only parameter that is not an option is the firmware image.  Check
+      // to make sure that the file exists.
+      //
+      Status = ShellIsFile (Argv[Index]);
+      if (EFI_ERROR (Status)) {
+        PrintToken (STRING_TOKEN (STR_FWUPDATE_FILE_NOT_FOUND_ERROR), HiiHandle, Argv[Index]);
+        return EFI_INVALID_PARAMETER;
+      }
+      if (StrLen (Argv[Index]) > INPUT_STRING_LEN) {
+        PrintToken (STRING_TOKEN (STR_FWUPDATE_PATH_ERROR), HiiHandle, Argv[Index]);
+        return EFI_INVALID_PARAMETER;
+      }
+      StrCpy (mInputData.FileName, Argv[Index]);
+      mInputData.UpdateFromFile = TRUE;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+INTN
+EFIAPI
+ShellAppMain (
+  IN UINTN Argc,
+  IN CHAR16 **Argv
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 Index;
+  UINT32                FileSize;
+  UINT32                BufferSize;
+  UINT8                 *FileBuffer;
+  UINT8                 *Buffer;
+  EFI_PHYSICAL_ADDRESS  Address;
+  UINTN                 CountOfBlocks;
+  EFI_TPL               OldTpl;
+  BOOLEAN               ResetRequired;
+  BOOLEAN               FlashError;
+
+  Index             = 0;
+  FileSize          = 0;
+  BufferSize        = 0;
+  FileBuffer        = NULL;
+  Buffer            = NULL;
+  Address           = 0;
+  CountOfBlocks     = 0;
+  ResetRequired     = FALSE;
+  FlashError        = FALSE;
+
+  Status = EFI_SUCCESS;
+
+  mInputData.FullFlashUpdate = TRUE;
+
+  //
+  // Publish our HII data.
+  //
+  HiiHandle = HiiAddPackages (
+                &gEfiCallerIdGuid,
+                NULL,
+                FirmwareUpdateStrings,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  //
+  // Locate the SPI protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                  (VOID **)&mSpiProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    PrintToken (STRING_TOKEN (STR_SPI_NOT_FOUND), HiiHandle);
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Parse the command line.
+  //
+  Status = ParseCommandLine (Argc, Argv);
+  if (EFI_ERROR (Status)) {
+    PrintHelpInfo ();
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+
+  //
+  // Display sign-on information.
+  //
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);
+
+  //
+  // Test to see if the firmware needs to be updated.
+  //
+  if (mInputData.UpdateFromFile) {
+    //
+    // Get the file to use in the update.
+    //
+    PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE), HiiHandle, mInputData.FileName);
+    Status = ReadFileData (mInputData.FileName, &FileBuffer, &FileSize);
+    if (EFI_ERROR (Status)) {
+      PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE_ERROR), HiiHandle, mInputData.FileName);
+      goto Done;
+    }
+
+    //
+    // Check that the file and flash sizes match.
+    //
+    if (FileSize != PcdGet32 (PcdFlashChipSize)) {
+      PrintToken (STRING_TOKEN (STR_FWUPDATE_SIZE), HiiHandle);
+      Status = EFI_UNSUPPORTED;
+      goto Done;
+    }
+
+    //
+    // Display flash update information.
+    //
+    PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATING_FIRMWARE), HiiHandle);
+
+    //
+    // Update it.
+    //
+    Buffer        = FileBuffer;
+    BufferSize    = FileSize;
+    Address       = PcdGet32 (PcdFlashChipBase);
+    CountOfBlocks = (UINTN) (BufferSize / BLOCK_SIZE);
+
+    //
+    // Raise TPL to TPL_NOTIFY to block any event handler,
+    // while still allowing RaiseTPL(TPL_NOTIFY) within
+    // output driver during Print().
+    //
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+    for (Index = 0; Index < CountOfBlocks; Index++) {
+      //
+      // Handle block based on address and contents.
+      //
+      if (!UpdateBlock (Address)) {
+        DEBUG((EFI_D_INFO, "Skipping block at 0x%lx\n", Address));
+      } else if (!EFI_ERROR (InternalCompareBlock (Address, Buffer))) {
+        DEBUG((EFI_D_INFO, "Skipping block at 0x%lx (already programmed)\n", Address));
+      } else {
+        //
+        // Display a dot for each block being updated.
+        //
+        Print (L".");
+
+        //
+        // Flag that the flash image will be changed and the system must be rebooted
+        // to use the change.
+        //
+        ResetRequired = TRUE;
+
+        //
+        // Make updating process uninterruptable,
+        // so that the flash memory area is not accessed by other entities
+        // which may interfere with the updating process.
+        //
+        Status  = InternalEraseBlock (Address);
+        ASSERT_EFI_ERROR(Status);
+        if (EFI_ERROR (Status)) {
+          gBS->RestoreTPL (OldTpl);
+          FlashError = TRUE;
+          goto Done;
+        }
+        Status = InternalWriteBlock (
+                  Address,
+                  Buffer,
+                  (BufferSize > BLOCK_SIZE ? BLOCK_SIZE : BufferSize)
+                  );
+        if (EFI_ERROR (Status)) {
+          gBS->RestoreTPL (OldTpl);
+          FlashError = TRUE;
+          goto Done;
+        }
+      }
+
+      //
+      // Move to next block to update.
+      //
+      Address += BLOCK_SIZE;
+      Buffer += BLOCK_SIZE;
+      if (BufferSize > BLOCK_SIZE) {
+        BufferSize -= BLOCK_SIZE;
+      } else {
+        BufferSize = 0;
+      }
+    }
+    gBS->RestoreTPL (OldTpl);
+
+    //
+    // Print result of update.
+    //
+    if (!FlashError) {
+      if (ResetRequired) {
+        Print (L"\n");
+        PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_SUCCESS), HiiHandle);
+      } else {
+        PrintToken (STRING_TOKEN (STR_FWUPDATE_NO_RESET), HiiHandle);
+      }
+    } else {
+      goto Done;
+    }
+  }
+
+  //
+  // All flash updates are done so see if the system needs to be reset.
+  //
+  if (ResetRequired && !FlashError) {
+    //
+    // Update successful.
+    //
+    for (Index = 5; Index > 0; Index--) {
+      PrintToken (STRING_TOKEN (STR_FWUPDATE_SHUTDOWN), HiiHandle, Index);
+      gBS->Stall (1000000);
+    }
+
+    gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+    PrintToken (STRING_TOKEN (STR_FWUPDATE_MANUAL_RESET), HiiHandle);
+    CpuDeadLoop ();
+  }
+
+Done:
+  //
+  // Print flash update failure message if error detected.
+  //
+  if (FlashError) {
+    PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_FAILED), HiiHandle, Index);
+  }
+
+  //
+  // Do cleanup.
+  //
+  if (HiiHandle != NULL) {
+    HiiRemovePackages (HiiHandle);
+  }
+  if (FileBuffer) {
+    gBS->FreePool (FileBuffer);
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+InternalEraseBlock (
+  IN  EFI_PHYSICAL_ADDRESS BaseAddress
+  )
+/*++
+
+Routine Description:
+
+  Erase the whole block.
+
+Arguments:
+
+  BaseAddress  - Base address of the block to be erased.
+
+Returns:
+
+  EFI_SUCCESS - The command completed successfully.
+  Other       - Device error or wirte-locked, operation failed.
+
+--*/
+{
+  EFI_STATUS                              Status;
+  UINTN                                   NumBytes;
+
+  NumBytes = BLOCK_SIZE;
+
+  Status = SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes);
+
+  return Status;
+}
+
+#if 0
+STATIC
+EFI_STATUS
+InternalReadBlock (
+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,
+  OUT VOID                  *ReadBuffer
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        BlockSize;
+
+  BlockSize = BLOCK_SIZE;
+
+  Status = SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer);
+
+  return Status;
+}
+#endif
+
+STATIC
+EFI_STATUS
+InternalCompareBlock (
+  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN  UINT8                       *Buffer
+  )
+{
+  EFI_STATUS                              Status;
+  VOID                                    *CompareBuffer;
+  UINT32                                  NumBytes;
+  INTN                                    CompareResult;
+
+  NumBytes = BLOCK_SIZE;
+  CompareBuffer = AllocatePool (NumBytes);
+  if (CompareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = SpiFlashRead ((UINTN) BaseAddress, &NumBytes, CompareBuffer);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+  CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE);
+  if (CompareResult != 0) {
+    Status = EFI_VOLUME_CORRUPTED;
+  }
+
+Done:
+  if (CompareBuffer != NULL) {
+    FreePool (CompareBuffer);
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+InternalWriteBlock (
+  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN  UINT8                       *Buffer,
+  IN  UINT32                      BufferSize
+  )
+/*++
+
+Routine Description:
+
+  Write a block of data.
+
+Arguments:
+
+  BaseAddress  - Base address of the block.
+  Buffer       - Data buffer.
+  BufferSize   - Size of the buffer.
+
+Returns:
+
+  EFI_SUCCESS           - The command completed successfully.
+  EFI_INVALID_PARAMETER - Invalid parameter, can not proceed.
+  Other                 - Device error or wirte-locked, operation failed.
+
+--*/
+{
+  EFI_STATUS                              Status;
+
+  Status = SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer);
+  ASSERT_EFI_ERROR(Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "\nFlash write error."));
+    return Status;
+  }
+
+  WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress, BLOCK_SIZE);
+
+  Status = InternalCompareBlock (BaseAddress, Buffer);
+  if (EFI_ERROR (Status)) {
+    DEBUG((EFI_D_ERROR, "\nError when writing to BaseAddress %lx with different at offset %x.", BaseAddress, Status));
+  } else {
+    DEBUG((EFI_D_INFO, "\nVerified data written to Block at %lx is correct.", BaseAddress));
+  }
+
+  return Status;
+
+}
+
+STATIC
+EFI_STATUS
+ReadFileData (
+  IN  CHAR16   *FileName,
+  OUT UINT8    **Buffer,
+  OUT UINT32   *BufferSize
+  )
+{
+  EFI_STATUS             Status;
+  SHELL_FILE_HANDLE      FileHandle;
+  UINT64                 Size;
+  VOID                   *NewBuffer;
+  UINTN                  ReadSize;
+
+  FileHandle = NULL;
+  NewBuffer = NULL;
+  Size = 0;
+
+  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = FileHandleIsDirectory (FileHandle);
+  if (!EFI_ERROR (Status)) {
+    Status = EFI_NOT_FOUND;
+    goto Done;
+  }
+
+  Status = FileHandleGetSize (FileHandle, &Size);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  NewBuffer = AllocatePool ((UINTN) Size);
+
+  ReadSize = (UINTN) Size;
+  Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  } else if (ReadSize != (UINTN) Size) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+Done:
+  if (FileHandle != NULL) {
+    ShellCloseFile (&FileHandle);
+  }
+
+  if (EFI_ERROR (Status)) {
+    if (NewBuffer != NULL) {
+      FreePool (NewBuffer);
+    }
+  } else {
+    *Buffer = NewBuffer;
+    *BufferSize = (UINT32) Size;
+  }
+
+  return Status;
+}
+
+STATIC
+VOID
+PrintHelpInfo (
+  VOID
+  )
+/*++
+
+Routine Description:
+
+  Print out help information.
+
+Arguments:
+
+  None.
+
+Returns:
+
+  None.
+
+--*/
+{
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);
+
+  Print (L"\n");
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_1), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_2), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_3), HiiHandle);
+  PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_4), HiiHandle);
+
+  Print (L"\n");
+}
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+     OUT UINT8     *Buffer
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+  UINTN         Offset = 0;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+
+    Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+    Status = mSpiProtocol->Execute (
+                             mSpiProtocol,
+                             1, //SPI_READ,
+                             0, //SPI_WREN,
+                             TRUE,
+                             TRUE,
+                             FALSE,
+                             Offset,
+                             BLOCK_SIZE,
+                             Buffer,
+                             EnumSpiRegionAll
+                             );
+    return Status;
+
+}
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+  IN     UINT8     *Buffer
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Offset;
+  UINT32                    Length;
+  UINT32                    RemainingBytes;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
+
+  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+  while (RemainingBytes > 0) {
+    if (RemainingBytes > SIZE_4KB) {
+      Length = SIZE_4KB;
+    } else {
+      Length = RemainingBytes;
+    }
+    Status = mSpiProtocol->Execute (
+                             mSpiProtocol,
+                             SPI_PROG,
+                             SPI_WREN,
+                             TRUE,
+                             TRUE,
+                             TRUE,
+                             (UINT32) Offset,
+                             Length,
+                             Buffer,
+                             EnumSpiRegionAll
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    RemainingBytes -= Length;
+    Offset += Length;
+    Buffer += Length;
+  }
+
+  //
+  // Actual number of bytes written.
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN UINTN    Address,
+  IN UINTN    *NumBytes
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Offset;
+  UINTN               RemainingBytes;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
+
+  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+  ASSERT ((*NumBytes % SIZE_4KB) == 0);
+  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+    while (RemainingBytes > 0) {
+      Status = mSpiProtocol->Execute (
+                               mSpiProtocol,
+                               SPI_SERASE,
+                               SPI_WREN,
+                               FALSE,
+                               TRUE,
+                               FALSE,
+                               (UINT32) Offset,
+                               0,
+                               NULL,
+                               EnumSpiRegionAll
+                               );
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+      RemainingBytes -= SIZE_4KB;
+      Offset         += SIZE_4KB;
+    }
+
+  //
+  // Actual number of bytes erased.
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+ConvertMac (
+  CHAR16 *Str
+  )
+{
+  UINTN Index;
+  UINT8 Temp[MAC_ADD_STR_LEN];
+
+  if (Str == NULL)
+    return EFI_INVALID_PARAMETER;
+
+  if (StrLen(Str) != MAC_ADD_STR_LEN)
+    return EFI_INVALID_PARAMETER;
+
+  for (Index = 0; Index < MAC_ADD_STR_LEN; Index++) {
+    if (Str[Index] >= 0x30 && Str[Index] <= 0x39) {
+      Temp[Index] = (UINT8)Str[Index] - 0x30;
+    } else if (Str[Index] >= 0x41 && Str[Index] <= 0x46) {
+      Temp[Index] = (UINT8)Str[Index] - 0x37;
+    } else if (Str[Index] >= 0x61 && Str[Index] <= 0x66) {
+      Temp[Index] = (UINT8)Str[Index] - 0x57;
+    } else {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  for (Index = 0; Index < MAC_ADD_BYTE_COUNT; Index++) {
+    mInputData.MacValue[Index] = (Temp[2 * Index] << 4) + Temp[2 * Index + 1];
+  }
+
+  return EFI_SUCCESS;
+}
+

+ 185 - 0
Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h

@@ -0,0 +1,185 @@
+/** @file
+
+Copyright (c) 1999  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _FIRMWARE_UPDATE_H_
+#define _FIRMWARE_UPDATE_H_
+
+#include <Uefi.h>
+
+#include <PiDxe.h>
+
+#include <Guid/FileInfo.h>
+
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/SimpleFileSystem.h>
+#include <Protocol/Spi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FileHandleLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+//
+// Function Prototypes.
+//
+STATIC
+EFI_STATUS
+ReadFileData (
+  IN  CHAR16   *FileName,
+  OUT UINT8    **Buffer,
+  OUT UINT32   *BufferSize
+  );
+
+STATIC
+EFI_STATUS
+InternalEraseBlock (
+  IN  EFI_PHYSICAL_ADDRESS    BaseAddress
+  );
+
+#if 0
+STATIC
+EFI_STATUS
+InternalReadBlock (
+  IN  EFI_PHYSICAL_ADDRESS    BaseAddress,
+  OUT VOID                    *ReadBuffer
+  );
+#endif
+
+STATIC
+EFI_STATUS
+InternalCompareBlock (
+  IN  EFI_PHYSICAL_ADDRESS    BaseAddress,
+  IN  UINT8                   *Buffer
+  );
+
+STATIC
+EFI_STATUS
+InternalWriteBlock (
+  IN  EFI_PHYSICAL_ADDRESS    BaseAddress,
+  IN  UINT8                   *Buffer,
+  IN  UINT32                  BufferSize
+  );
+
+STATIC
+VOID
+PrintHelpInfo (
+  VOID
+  );
+
+STATIC
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+     OUT UINT8     *Buffer
+  );
+
+STATIC
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+  IN     UINT8     *Buffer
+  );
+
+STATIC
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN    UINTN    Address,
+  IN    UINTN    *NumBytes
+  );
+
+STATIC
+EFI_STATUS
+EFIAPI
+ConvertMac (
+  CHAR16 *Str
+  );
+
+EFI_STATUS
+InitializeFVUPDATE (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  );
+
+//
+// Flash specific definitions.
+// - Should we use a PCD for this information?
+//
+#define BLOCK_SIZE          SIZE_4KB
+
+//
+// Flash region layout and update information.
+//
+typedef struct {
+  EFI_PHYSICAL_ADDRESS  Base;
+  UINTN                 Size;
+  BOOLEAN               Update;
+} FV_REGION_INFO;
+
+//
+// MAC Address information.
+//
+#define MAC_ADD_STR_LEN       12
+#define MAC_ADD_STR_SIZE      (MAC_ADD_STR_LEN + 1)
+#define MAC_ADD_BYTE_COUNT    6
+#define MAC_ADD_TMP_STR_LEN   2
+#define MAC_ADD_TMP_STR_SIZE  (MAC_ADD_TMP_STR_LEN + 1)
+
+//
+// Command Line Data.
+//
+#define INPUT_STRING_LEN    255
+#define INPUT_STRING_SIZE   (INPUT_STRING_LEN + 1)
+typedef struct {
+  BOOLEAN   UpdateFromFile;
+  CHAR16    FileName[INPUT_STRING_SIZE];
+  BOOLEAN   UpdateMac;
+  UINT8     MacValue[MAC_ADD_BYTE_COUNT];
+  BOOLEAN   FullFlashUpdate;
+} FV_INPUT_DATA;
+
+//
+// Prefix Opcode Index on the host SPI controller.
+//
+typedef enum {
+  SPI_WREN,             // Prefix Opcode 0: Write Enable.
+  SPI_EWSR,             // Prefix Opcode 1: Enable Write Status Register.
+} PREFIX_OPCODE_INDEX;
+
+//
+// Opcode Menu Index on the host SPI controller.
+//
+typedef enum {
+  SPI_READ_ID,        // Opcode 0: READ ID, Read cycle with address.
+  SPI_READ,           // Opcode 1: READ, Read cycle with address.
+  SPI_RDSR,           // Opcode 2: Read Status Register, No address.
+  SPI_WRDI_SFDP,      // Opcode 3: Write Disable or Discovery Parameters, No address.
+  SPI_SERASE,         // Opcode 4: Sector Erase (4KB), Write cycle with address.
+  SPI_BERASE,         // Opcode 5: Block Erase (32KB), Write cycle with address.
+  SPI_PROG,           // Opcode 6: Byte Program, Write cycle with address.
+  SPI_WRSR,           // Opcode 7: Write Status Register, No address.
+} SPI_OPCODE_INDEX;
+
+#endif

+ 83 - 0
Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.inf

@@ -0,0 +1,83 @@
+## @file
+# Implements a Tunnel Mountain specific flash update program.  This will allow
+# users to update all regions of the flash as needed in a given update.
+#
+# Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#                                                                                  
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FirmwareUpdate
+  FILE_GUID                      = AEFAF26C-FB6D-4fef-AF7A-9D78FF201FCA
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = ShellCEntryLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = X64
+#
+
+[Sources]
+  FirmwareUpdateStrings.uni
+  FirmwareUpdate.c
+  FirmwareUpdate.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CacheMaintenanceLib
+  DebugLib
+  FileHandleLib
+  #FlashDeviceLib
+  #SpiFlashCommonLib
+  MemoryAllocationLib
+  PcdLib
+  ShellCEntryLib
+  ShellLib
+  UefiApplicationEntryPoint
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED
+  gEfiFirmwareVolumeBlockProtocolGuid           # PROTOCOL ALWAYS_CONSUMED
+  gEfiSpiProtocolGuid
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize   ## CONSUMES
+
+[FixedPcd]
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipSize
+  gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorSize
+  gPlatformModuleTokenSpaceGuid.PcdTxeRomBase
+  gPlatformModuleTokenSpaceGuid.PcdTxeRomSize
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomBase
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomSize
+
+[BuildOptions]
+  MSFT:*_*_X64_CC_FLAGS       = /Od 
+  INTEL:*_*_X64_CC_FLAGS       = /Od 

+ 45 - 0
Platform/Intel/Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdateStrings.uni

@@ -0,0 +1,45 @@
+// *++
+//
+// Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// -- *
+
+#langdef   en-US "English"
+#langdef   fr-FR "Français"
+
+#string STR_FWUPDATE_FIRMWARE_VOL_UPDATE  #language en-US  "Intel(R) UDK2014 Firmware Update Utility for the Intel(R) MinnowMax\n"
+#string STR_FWUPDATE_COPYRIGHT            #language en-US  "Copyright(c) Intel Corporation 2006 - 2014\n"
+                                          #language fr-FR  "Déposer(c) la Société commerciale de Intel 2006 - 2014\n"
+#string STR_FWUPDATE_VERSION              #language en-US  "Version 0.72\n"
+
+#string STR_FWUPDATE_ZEROLENGTH_ARG       #language en-US  "Argument with zero length is not allowed\n"
+                                          #language fr-FR  "L'argument avec zéro longueur n'est pas permis\n"
+#string STR_FWUPDATE_INVAILD_MAC          #language en-US  "Invalid MAC address.\n"
+										  #string STR_FWUPDATE_READ_FILE            #language en-US  "\nReading file %s\n"
+#string STR_FWUPDATE_READ_FILE_ERROR      #language en-US  "Unable to read file %s\n"
+#string STR_FWUPDATE_SIZE                 #language en-US  "File size should be 16MB\n"
+                                          #language fr-FR  "Doit être 16 MB\n"
+#string STR_FWUPDATE_UPDATE_SUCCESS       #language en-US  "Update successful\n"
+                                          #language fr-FR  "Met à jour prospère\n"
+#string STR_FWUPDATE_UPDATE_FAILED        #language en-US  "\nUpdate failed.  Please make sure the flash is not write protected.\n"
+#string STR_FWUPDATE_RESET                #language en-US  "\rResetting system in %d seconds ..."
+                                          #language fr-FR  "\rLe système qui remettre à l'état initial dans %d les secondes ..."
+#string STR_FWUPDATE_SHUTDOWN             #language en-US  "\rShutdown system in %d seconds ..."								  
+#string STR_FWUPDATE_MANUAL_RESET         #language en-US  "\nPls manually reset system ...\n"
+                                          #language fr-FR  "\nS'il vous plaît manuellement remet à l'état initial le système ...\n"
+#string STR_FWUPDATE_NO_RESET             #language en-US  "Already up to date\n"
+#string STR_MISSING_MAC_ARG               #language en-US  "Option -m specified without MAC address.\n"
+#string STR_INVALID_MAC_ARG               #language en-US  "Invalid MAC address format used (e.g. -m 0011AA33CC55).\n"
+#string STR_FWUPDATE_FILE_NOT_FOUND_ERROR #language en-US  "File %s not found.\n"
+#string STR_FWUPDATE_PATH_ERROR           #language en-US  "File path/name too long.\n"
+#string STR_FWUPDATE_UPDATING_FIRMWARE    #language en-US  "\nUpdating Firmware.  This may take a few minutes.\n"
+#string STR_FWUPDATE_UPDATING_MAC         #language en-US  "\nUpdating MAC Address.\n"
+#string STR_SPI_NOT_FOUND                 #language en-US  "\nSPI Protocol is not found.\n"
+
+#string STR_FWUPDATE_USAGE                #language en-US  "Usage: FirmwareUpdate [IMAGEFILE]\n"
+#string STR_FWUPDATE_USAGE_1              #language en-US  "\n"
+#string STR_FWUPDATE_USAGE_2              #language en-US  "   Programs the 8MB IMAGEFILE for the MinnowMax.\n"
+#string STR_FWUPDATE_USAGE_3              #language en-US  " \n"
+#string STR_FWUPDATE_USAGE_4              #language en-US  " \n"
+

BIN
Platform/Intel/Vlv2TbltDevicePkg/BfmLib.exe


+ 25 - 0
Platform/Intel/Vlv2TbltDevicePkg/BiosIdD.env

@@ -0,0 +1,25 @@
+#/** @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  The BIOS ID format conforms to "BIOS Revision Identification Specification", Rev. 0.7, 6/27/2001.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length.
+#    Example: "TRFTCRB1.86C.0008.D03.0506081529"
+#
+#  Copyright (c) 2008  - 2015, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#**/
+
+BOARD_REV     = 1
+OEM_ID        = I32
+BUILD_TYPE    = D
+
+BOARD_ID = BLAKCRB
+VERSION_MAJOR = 0084
+VERSION_MINOR = 01

+ 25 - 0
Platform/Intel/Vlv2TbltDevicePkg/BiosIdR.env

@@ -0,0 +1,25 @@
+#/** @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  The BIOS ID format conforms to "BIOS Revision Identification Specification", Rev. 0.7, 6/27/2001.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length.
+#    Example: "TRFTCRB1.86C.0008.D03.0506081529"
+#
+#  Copyright (c) 2008  - 2015, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#**/
+
+BOARD_REV     = 1
+OEM_ID        = I32
+BUILD_TYPE    = R
+
+BOARD_ID = BLAKCRB
+VERSION_MAJOR = 0084
+VERSION_MINOR = 01

+ 25 - 0
Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64D.env

@@ -0,0 +1,25 @@
+#/** @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  The BIOS ID format conforms to "BIOS Revision Identification Specification", Rev. 0.7, 6/27/2001.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length.
+#    Example: "TRFTCRB1.86C.0008.D03.0506081529"
+#
+#  Copyright (c) 2008  - 2015, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#**/
+
+BOARD_REV     = 1
+OEM_ID        = X64
+BUILD_TYPE    = D
+
+VERSION_MAJOR = 0084
+VERSION_MINOR = 01
+BOARD_ID = BBAYCRB 

+ 25 - 0
Platform/Intel/Vlv2TbltDevicePkg/BiosIdx64R.env

@@ -0,0 +1,25 @@
+#/** @file
+#  This file is used to define the BIOS ID parameters of the build.
+#  This file is processed by GenBiosId.
+#  The BIOS ID format conforms to "BIOS Revision Identification Specification", Rev. 0.7, 6/27/2001.
+#
+#  BIOS ID string format:
+#    $(BOARD_ID)$(BOARD_REV).$(OEM_ID).$(VERSION_MAJOR).$(BUILD_TYPE)$(VERSION_MINOR).YYMMDDHHMM
+#  All fields must have a fixed length.
+#    Example: "TRFTCRB1.86C.0008.D03.0506081529"
+#
+#  Copyright (c) 2008  - 2015, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#**/
+
+BOARD_REV     = 1
+OEM_ID        = X64
+BUILD_TYPE    = R
+
+VERSION_MAJOR = 0084
+VERSION_MINOR = 01
+BOARD_ID = BBAYCRB 

+ 60 - 0
Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/BootScriptSaveDxe.inf

@@ -0,0 +1,60 @@
+#
+#
+## @file
+# Component description file for ScriptSave Lite module.
+#
+# This is an implementation of the Boot Script Save protocol.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BootScriptSaveDxe
+  FILE_GUID                      = 42BB673D-09F3-4e2e-9FEE-D081131DED5B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeScriptSave
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  ScriptSave.c
+  InternalBootScriptSave.h
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+
+[LibraryClasses]
+  PcdLib
+  UefiRuntimeServicesTableLib
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  UefiDriverEntryPoint
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  S3BootScriptLib
+
+[Protocols]
+  gEfiBootScriptSaveProtocolGuid                # PROTOCOL ALWAYS_PRODUCED
+
+
+[Depex]
+  TRUE
+

+ 102 - 0
Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/InternalBootScriptSave.h

@@ -0,0 +1,102 @@
+/** @file
+//
+//
+  Internal header file for S3 Boot Script Saver driver.
+
+  Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _INTERNAL_BOOT_SCRIPT_SAVE_H_
+#define _INTERNAL_BOOT_SCRIPT_SAVE_H_
+#include <FrameworkDxe.h>
+
+#include <Protocol/BootScriptSave.h>
+#include <Protocol/FirmwareVolume.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SmbusLib.h>
+#include <IndustryStandard/SmBus.h>
+
+/**
+  Adds a record into a specified Framework boot script table.
+
+  This function is used to store a boot script record into a given boot
+  script table. If the table specified by TableName is nonexistent in the
+  system, a new table will automatically be created and then the script record
+  will be added into the new table. A boot script table can add new script records
+  until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only
+  meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is
+  responsible for allocating necessary memory for the script.
+
+  This function has a variable parameter list. The exact parameter list depends on
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
+  If there are not enough resources available for storing more scripts, this function returns
+  EFI_OUT_OF_RESOURCES.
+
+  @param[in]  This                 A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
+  @param[in]  TableName            Name of the script table. Currently, the only meaningful value is
+                                   EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+  @param[in]  OpCode               The operation code (opcode) number.
+  @param[in]  ...                  Argument list that is specific to each opcode.
+
+  @retval EFI_SUCCESS              The operation succeeded. A record was added into the
+                                   specified script table.
+  @retval EFI_INVALID_PARAMETER    The parameter is illegal or the given boot script is not supported.
+                                   If the opcode is unknow or not supported because of the PCD
+                                   Feature Flags.
+  @retval EFI_OUT_OF_RESOURCES     There is insufficient memory to store the boot script.
+
+**/
+EFI_STATUS
+EFIAPI
+BootScriptWrite (
+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL    *This,
+  IN UINT16                           TableName,
+  IN UINT16                           OpCode,
+  ...
+  );
+
+/**
+  Closes the specified script table.
+
+  This function closes the specified boot script table and returns the base address
+  of the table. It allocates a new pool to duplicate all the boot scripts in the specified
+  table. Once this function is called, the specified table will be destroyed after it is
+  copied into the allocated pool. As a result, any attempts to add a script record into a
+  closed table will cause a new table to be created. The base address of the allocated pool
+  will be returned in Address. After using the boot script table, the caller is responsible
+  for freeing the pool that is allocated by this function. If the boot script table,
+  such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed
+  memory region, the caller should copy the table into the nonperturbed memory region by itself.
+
+  @param[in]  This              A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
+  @param[in]  TableName         Name of the script table. Currently, the only meaningful value is
+                                EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+  @param[in]  Address           A pointer to the physical address where the table begins.
+
+  @retval EFI_SUCCESS           The table was successfully returned.
+  @retval EFI_NOT_FOUND         The specified table was not created previously.
+  @retval EFI_OUT_OF_RESOURCE   Memory is insufficient to hold the reorganized boot script table.
+  @retval EFI_UNSUPPORTED       The table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+
+**/
+EFI_STATUS
+EFIAPI
+BootScriptCloseTable (
+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL    *This,
+  IN UINT16                           TableName,
+  OUT EFI_PHYSICAL_ADDRESS            *Address
+  );
+#endif //_INTERNAL_BOOT_SCRIPT_SAVE_H_

+ 626 - 0
Platform/Intel/Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c

@@ -0,0 +1,626 @@
+/** @file
+  Implementation for S3 Boot Script Saver driver.
+
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include "InternalBootScriptSave.h"
+
+EFI_HANDLE                    mHandle = NULL;
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {
+  BootScriptWrite,
+  BootScriptCloseTable
+  };
+
+/**
+  Internal function to add IO write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptIoWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINTN                 Count;
+  UINT8                 *Buffer;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Count       = VA_ARG (Marker, UINTN);
+  Buffer      = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);
+}
+
+/**
+  Internal function to add IO read/write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptIoReadWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINT8                 *Data;
+  UINT8                 *DataMask;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Data        = VA_ARG (Marker, UINT8 *);
+  DataMask    = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask);
+}
+
+/**
+  Internal function to add memory write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptMemWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINTN                 Count;
+  UINT8                 *Buffer;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Count       = VA_ARG (Marker, UINTN);
+  Buffer      = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSaveMemWrite (Width, Address, Count, Buffer);
+}
+
+/**
+  Internal function to add memory read/write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptMemReadWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINT8                 *Data;
+  UINT8                 *DataMask;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Data        = VA_ARG (Marker, UINT8 *);
+  DataMask    = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSaveMemReadWrite (Width, Address, Data, DataMask);
+}
+
+/**
+  Internal function to add PciCfg write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptPciCfgWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINTN                 Count;
+  UINT8                 *Buffer;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Count       = VA_ARG (Marker, UINTN);
+  Buffer      = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSavePciCfgWrite (Width, Address, Count, Buffer);
+}
+
+/**
+  Internal function to PciCfg read/write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptPciCfgReadWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINT8                 *Data;
+  UINT8                 *DataMask;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Data        = VA_ARG (Marker, UINT8 *);
+  DataMask    = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSavePciCfgReadWrite (Width, Address, Data, DataMask);
+}
+
+/**
+  Internal function to add PciCfg2 write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptPciCfg2Write (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINTN                 Count;
+  UINT8                 *Buffer;
+  UINT16                Segment;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Count       = VA_ARG (Marker, UINTN);
+  Buffer      = VA_ARG (Marker, UINT8 *);
+  Segment     = VA_ARG (Marker, UINT16);
+
+  return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer);
+}
+
+/**
+  Internal function to PciCfg2 read/write opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptPciCfg2ReadWrite (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT16                Segment;
+  UINT64                Address;
+  UINT8                 *Data;
+  UINT8                 *DataMask;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  Segment     = VA_ARG (Marker, UINT16);
+  Data        = VA_ARG (Marker, UINT8 *);
+  DataMask    = VA_ARG (Marker, UINT8 *);
+
+  return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask);
+}
+
+/**
+  Internal function to add smbus execute opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptSmbusExecute (
+  IN VA_LIST                       Marker
+  )
+{
+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;
+  EFI_SMBUS_DEVICE_COMMAND  Command;
+  EFI_SMBUS_OPERATION       Operation;
+  BOOLEAN                   PecCheck;
+  VOID                     *Buffer;
+  UINTN                    *DataSize;
+  UINTN                     SmBusAddress;
+
+  SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);
+  Command                         = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);
+  Operation                       = VA_ARG (Marker, EFI_SMBUS_OPERATION);
+  PecCheck                        = VA_ARG (Marker, BOOLEAN);
+  SmBusAddress                    = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck);
+  DataSize                        = VA_ARG (Marker, UINTN *);
+  Buffer                          = VA_ARG (Marker, VOID *);
+
+  return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer);
+}
+
+/**
+  Internal function to add stall opcode to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptStall (
+  IN VA_LIST                       Marker
+  )
+{
+  UINT32                Duration;
+
+  Duration    = VA_ARG (Marker, UINT32);
+
+  return S3BootScriptSaveStall (Duration);
+}
+
+/**
+  Internal function to add Save jmp address according to DISPATCH_OPCODE.
+  We ignore "Context" parameter.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptDispatch (
+  IN VA_LIST                       Marker
+  )
+{
+  VOID        *EntryPoint;
+
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
+  return S3BootScriptSaveDispatch (EntryPoint);
+}
+
+/**
+  Internal function to add memory pool operation to the table.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptMemPoll (
+  IN VA_LIST                       Marker
+  )
+{
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;
+  UINT64                Address;
+  UINT8                 *BitMask;
+  UINT8                 *BitValue;
+  UINTN                Duration;
+  UINT64               LoopTimes;
+
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
+  Address     = VA_ARG (Marker, UINT64);
+  BitMask     = VA_ARG (Marker, UINT8 *);
+  BitValue    = VA_ARG (Marker, UINT8 *);
+  Duration    = (UINTN)VA_ARG (Marker, UINT64);
+  LoopTimes   = VA_ARG (Marker, UINT64);
+
+  return S3BootScriptSaveMemPoll (Width, Address, BitMask, BitValue, Duration, LoopTimes);
+}
+
+/**
+  Internal function to add Save jmp address according to DISPATCH_OPCODE2.
+  The "Context" parameter is not ignored.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
+  @retval EFI_SUCCESS           Opcode is added.
+
+**/
+EFI_STATUS
+BootScriptDispatch2 (
+  IN VA_LIST                       Marker
+  )
+{
+  VOID                  *EntryPoint;
+  VOID                  *Context;
+
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
+  Context    = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
+
+  return S3BootScriptSaveDispatch2 (EntryPoint, Context);
+}
+
+/**
+  Internal function to add the opcode link node to the link list.
+
+  @param  Marker                The variable argument list to get the opcode
+                                and associated attributes.
+
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.
+  @retval EFI_SUCCESS           The opcode entry is added to the link list
+                                successfully.
+**/
+EFI_STATUS
+BootScriptInformation (
+  IN VA_LIST                       Marker
+  )
+{
+  UINT32                InformationLength;
+  EFI_PHYSICAL_ADDRESS  Information;
+
+  InformationLength = VA_ARG (Marker, UINT32);
+  Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
+  return S3BootScriptSaveInformation (InformationLength, (VOID*)(UINTN)Information);
+}
+
+/**
+  Adds a record into a specified Framework boot script table.
+
+  This function is used to store a boot script record into a given boot
+  script table. If the table specified by TableName is nonexistent in the
+  system, a new table will automatically be created and then the script record
+  will be added into the new table. A boot script table can add new script records
+  until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only
+  meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is
+  responsible for allocating necessary memory for the script.
+
+  This function has a variable parameter list. The exact parameter list depends on
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
+  If there are not enough resources available for storing more scripts, this function returns
+  EFI_OUT_OF_RESOURCES.
+
+  @param  This                  A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
+  @param  TableName             Name of the script table. Currently, the only meaningful value is
+                                EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+  @param  OpCode                The operation code (opcode) number.
+  @param  ...                   Argument list that is specific to each opcode.
+
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the
+                                specified script table.
+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
+                                If the opcode is unknow or not supported because of the PCD
+                                Feature Flags.
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.
+
+**/
+EFI_STATUS
+EFIAPI
+BootScriptWrite (
+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL    *This,
+  IN UINT16                           TableName,
+  IN UINT16                           OpCode,
+  ...
+  )
+{
+  EFI_STATUS                Status;
+  VA_LIST                   Marker;
+
+  if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
+    //
+    // Only S3 boot script is supported for now.
+    //
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Build script according to opcode.
+  //
+  switch (OpCode) {
+
+  case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptIoWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptIoReadWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptMemWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptMemReadWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptPciCfgWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptPciCfgReadWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptSmbusExecute (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_STALL_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptStall (Marker);
+    VA_END (Marker);
+
+    break;
+
+  case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptDispatch (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptDispatch2 (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptInformation (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptMemPoll (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptPciCfg2Write (Marker);
+    VA_END (Marker);
+    break;
+
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
+    VA_START (Marker, OpCode);
+    Status = BootScriptPciCfg2ReadWrite (Marker);
+    VA_END (Marker);
+    break;
+
+  default:
+    Status = EFI_INVALID_PARAMETER;
+    break;
+  }
+
+  return Status;
+}
+
+/**
+  Closes the specified script table.
+
+  This function closes the specified boot script table and returns the base address
+  of the table. It allocates a new pool to duplicate all the boot scripts in the specified
+  table. Once this function is called, the specified table will be destroyed after it is
+  copied into the allocated pool. As a result, any attempts to add a script record into a
+  closed table will cause a new table to be created. The base address of the allocated pool
+  will be returned in Address. After using the boot script table, the caller is responsible
+  for freeing the pool that is allocated by this function. If the boot script table,
+  such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed
+  memory region, the caller should copy the table into the nonperturbed memory region by itself.
+
+  @param  This                  A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
+  @param  TableName             Name of the script table. Currently, the only meaningful value is
+                                 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+  @param  Address               A pointer to the physical address where the table begins.
+
+  @retval EFI_SUCCESS           The table was successfully returned.
+  @retval EFI_NOT_FOUND         The specified table was not created previously.
+  @retval EFI_OUT_OF_RESOURCE   Memory is insufficient to hold the reorganized boot script table.
+  @retval EFI_UNSUPPORTED       The table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
+
+**/
+EFI_STATUS
+EFIAPI
+BootScriptCloseTable (
+  IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL    *This,
+  IN UINT16                           TableName,
+  OUT EFI_PHYSICAL_ADDRESS            *Address
+  )
+{
+  if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
+    //
+    // Only S3 boot script is supported for now.
+    //
+    return EFI_NOT_FOUND;
+  }
+  *Address = (EFI_PHYSICAL_ADDRESS)(UINTN)S3BootScriptCloseTable ();
+
+  if (*Address == 0) {
+    return  EFI_NOT_FOUND;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine is entry point of ScriptSave driver.
+
+  @param  ImageHandle           Handle for this drivers loaded image protocol.
+  @param  SystemTable           EFI system table.
+
+  @retval EFI_OUT_OF_RESOURCES  No enough resource.
+  @retval EFI_SUCCESS           Succesfully installed the ScriptSave driver.
+  @retval other                 Errors occured.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeScriptSave (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return  gBS->InstallProtocolInterface (
+                  &mHandle,
+                  &gEfiBootScriptSaveProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mS3ScriptSave
+                  );
+
+}
+

+ 200 - 0
Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.bat

@@ -0,0 +1,200 @@
+@REM @file
+@REM   Windows batch file to build BIOS ROM
+@REM
+@REM Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+
+SetLocal EnableDelayedExpansion EnableExtensions
+
+@REM Go to work space directory.
+cd ..
+cd ..
+
+:: Assign initial values
+set exitCode=0
+set "Build_Flags= "
+set "Stitch_Flags= "
+set Arch=X64
+set PLATFORM_PACKAGE=Vlv2TbltDevicePkg
+
+set PLATFORM_PATH=%WORKSPACE%
+if not exist %PLATFORM_PATH%\%PLATFORM_PACKAGE% (
+  if defined PACKAGES_PATH (
+    for %%i IN (%PACKAGES_PATH%) DO (
+      if exist %%~fi\%PLATFORM_PACKAGE% (
+        set PLATFORM_PATH=%%~fi
+        goto PlatformPackageFound
+      )
+    )
+  ) else (
+    echo.
+    echo !!! ERROR !!! Cannot find %PLATFORM_PACKAGE% !!!
+    echo.
+    goto Exit
+  )
+)
+:PlatformPackageFound
+
+:: Parse Optional arguments
+:OptLoop
+if /i "%~1"=="/?" goto Usage
+
+if /i "%~1"=="/q" (
+    set Build_Flags=%Build_Flags% /q
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/l" (
+    set Build_Flags=%Build_Flags% /l
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/y" (
+    set Build_Flags=%Build_Flags% /y
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/m" (
+    set Build_Flags=%Build_Flags% /m
+    shift
+    goto OptLoop
+)
+if /i "%~1" == "/c" (
+    set Build_Flags=%Build_Flags% /c
+    shift
+    goto OptLoop
+)
+if /i "%~1" == "/ECP" (
+    set Build_Flags=%Build_Flags% /ecp
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/s" (
+    set Build_Flags=%Build_Flags% /s
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/x64" (
+    set Arch=X64
+    set Build_Flags=%Build_Flags% /x64
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/IA32" (
+    set Arch=IA32
+    set Build_Flags=%Build_Flags% /IA32
+    shift
+    goto OptLoop
+)
+
+if /i "%~1"=="/nG" (
+    set Stitch_Flags=%Stitch_Flags% /nG
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/nM" (
+    set Stitch_Flags=%Stitch_Flags% /nM
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/nB" (
+    set Stitch_Flags=%Stitch_Flags% /nB
+    shift
+    goto OptLoop
+)
+if /i "%~1"=="/yL" (
+    set Stitch_Flags=%Stitch_Flags% /yL
+    shift
+    goto OptLoop
+)
+
+
+:: Require 2 input parameters
+if "%~2"=="" goto Usage
+
+:: Assign required arguments
+set Platform_Type=%~1
+set Build_Target=%~2
+
+if "%~3"=="" (
+    set "IFWI_Suffix= "
+) else set "IFWI_Suffix=/S %~3"
+
+:: Build BIOS
+echo ======================================================================
+echo Build_IFWI:  Calling BIOS build Script...
+
+call %PLATFORM_PATH%\%PLATFORM_PACKAGE%\bld_vlv.bat %Build_Flags%  %Platform_Type% %Build_Target%
+
+if %ERRORLEVEL% NEQ 0 (
+    echo echo  -- Error Building BIOS  & echo.
+    set exitCode=1
+    goto exit
+)
+echo.
+echo Finished Building BIOS.
+@REM Set BIOS_ID environment variable here.
+call %WORKSPACE%\Conf\BiosId.bat
+echo BIOS_ID=%BIOS_ID%
+
+:: Set the Board_Id, Build_Type, Version_Major, and Version_Minor environment variables
+find /v "#" %WORKSPACE%\Conf\BiosId.env > ver_strings
+for /f "tokens=1,3" %%i in (ver_strings) do set %%i=%%j
+del /f/q ver_strings >nul
+set BIOS_Name=%BOARD_ID%_%Arch%_%BUILD_TYPE%_%VERSION_MAJOR%_%VERSION_MINOR%.ROM
+
+:: Start Integration process
+echo ======================================================================
+echo Build_IFWI:  Calling IFWI Stitching Script...
+pushd %PLATFORM_PATH%\%PLATFORM_PACKAGE%\Stitch
+
+  :: IFWIStitch.bat [/nG] [/nM] [/nB] [/B BIOS.rom] [/C StitchConfig] [/S IFWISuffix]
+  call IFWIStitch.bat %Stitch_Flags% /B %BIOS_Name% %IFWI_Suffix%
+   
+ @echo off
+popd
+if %ERRORLEVEL% NEQ 0 (
+    echo echo  -- Error Stitching %BIOS_Nam% & echo.
+    set exitCode=1
+)
+echo.
+echo Build_IFWI is finished.
+echo The final IFWI file is located in %ROOT_DIR%\Vlv2TbltDevicePkg\Stitch\
+echo ======================================================================
+goto Exit
+
+:Usage
+echo Script to build BIOS firmware and stitch the entire IFWI.
+echo.
+echo Usage: Build_IFWI.bat [options]  PlatformType  BuildTarget  [IFWI Suffix]
+echo.
+echo        /c     CleanAll before building
+echo        /x64   Set Arch to X64  (default: X64)
+echo        /IA32  Set Arch to IA32 (default: X64)
+echo        /yL    Enable SPI lock
+echo. 
+echo        Platform Types:   MNW2
+echo        Build Targets:    Release, Debug
+echo        IFWI Suffix:      Suffix to append to end of IFWI filename (default: MM_DD_YYYY)
+echo.
+echo        See  Stitch/Stitch_Config.txt  for additional stitching settings.
+echo.
+echo        If capsule update is needed, please update CAPSULE_ENABLE = TRUE in Config.dsc.
+echo        If recovery is needed, please update RECOVERY_ENABLE = TRUE in Config.dsc.
+echo        If either of above is TRUE, please set OPENSSL_PATH in windows evironment
+echo        and put openssl.exe there, to generate final capsule image.
+echo.
+set exitCode=1
+
+:Exit
+@REM  CD to platform package.
+cd %PLATFORM_PATH%
+exit /b %exitCode%
+
+EndLocal

+ 104 - 0
Platform/Intel/Vlv2TbltDevicePkg/Build_IFWI.sh

@@ -0,0 +1,104 @@
+#!/usr/bin/env bash
+##**********************************************************************
+## Function define
+##**********************************************************************
+function Usage ( ) {
+  echo
+  echo "Script to build BIOS firmware and stitch the entire IFWI."
+  echo
+  echo "Usage: Build_IFWI.bat [options]  PlatformType  BuildTarget  "
+  echo
+  echo 
+  echo "       /yL [option]  :   Enable SPI lock"
+  echo "       Platform Types:   MNW2"
+  echo "       Build Targets:    Release, Debug"
+  echo
+  echo "       See  Stitch/Stitch_Config.txt  for additional stitching settings."
+  echo
+  echo
+  exit 0
+}
+
+## Assign initial values
+exitCode=0
+Build_Flags=
+Stitch_Flags=
+Arch=X64
+PLATFORM_PACKAGE=Vlv2TbltDevicePkg
+
+## Parse Optional arguments
+if [ "$1" == "/?" ]; then
+  Usage
+fi
+
+for (( i=1; i<=$#; ))
+  do
+    if [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/Q" ]; then
+      Build_Flags="$Build_Flags /q"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/L" ]; then
+      Build_Flags="$Build_Flags /l"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/C" ]; then
+      Build_Flags="$Build_Flags /c"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/ECP" ]; then
+      Build_Flags="$Build_Flags /ecp"
+      shift
+    elif [ "$(echo $1 | tr 'a-z' 'A-Z')" == "/X64" ]; then
+      Arch=X64
+      Build_Flags="$Build_Flags /x64"
+      shift
+    elif [ "$1" == "/nG" ]; then
+      Stitch_Flags="$Stitch_Flags /nG"
+      shift
+    elif [ "$1" == "/nM" ]; then
+      Stitch_Flags="$Stitch_Flags /nM"
+      shift
+    elif [ "$1" == "/nB" ]; then
+      Stitch_Flags="$Stitch_Flags /nB"
+      shift
+    elif [ "$1" == "/nV" ]; then
+      Stitch_Flags="$Stitch_Flags /nV"
+      shift
+    elif [ "$1" == "/yL" ]; then
+      Build_Flags="$Build_Flags /yL"
+      shift
+    else
+      break
+    fi
+  done
+
+## Require 2 input parameters
+if [ "$2" == "" ]; then
+  Usage
+fi
+
+## Assign required arguments
+Platform_Type=$1
+Build_Target=$2
+if [ "$3" == "" ]; then
+  IFWI_Suffix=
+else
+  IFWI_Suffix="/S $3"
+fi
+
+## Go to root directory
+cd ..
+
+## Build BIOS
+echo "======================================================================"
+echo "Build_IFWI:  Calling BIOS build Script..."
+./$PLATFORM_PACKAGE/bld_vlv.sh $Build_Flags $Platform_Type $Build_Target
+
+echo
+echo Finished Building BIOS.
+
+## Start Integration process
+echo ======================================================================
+echo Skip "Build_IFWI:  Calling IFWI Stitching Script..."
+
+echo
+echo Build_IFWI is finished.
+echo The final IFWI file is located in Stitch
+echo ======================================================================

BIN
Platform/Intel/Vlv2TbltDevicePkg/FCE.exe


+ 35 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.bat

@@ -0,0 +1,35 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for system firmware and
+@REM   firmware for sample devices
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+cd /d %~dp0
+
+rmdir /s /q %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules
+mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules
+mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+mkdir %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment\CapsuleApp.efi
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment\CapsuleAppRelease.efi
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\CapsuleApp.efi
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\CapsuleAppRelease.efi
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\CapsuleApp.efi
+copy %WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\X64\CapsuleApp.efi %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\CapsuleAppRelease.efi
+
+call GenCapsuleMinnowMax.bat
+call GenCapsuleMinnowMaxRelease.bat
+call GenCapsuleSampleColor.bat Blue  149da854-7d19-4faa-a91e-862ea1324be6
+call GenCapsuleSampleColor.bat Green 79179bfd-704d-4c90-9e02-0ab8d968c18a
+call GenCapsuleSampleColor.bat Red   72e2945a-00da-448e-9aa7-075ad840f9d4
+
+call LvfsGenCapsuleMinnowMax.bat
+call LvfsGenCapsuleMinnowMaxRelease.bat
+call LvfsGenCapsuleSampleColor.bat Blue  149da854-7d19-4faa-a91e-862ea1324be6
+call LvfsGenCapsuleSampleColor.bat Green 79179bfd-704d-4c90-9e02-0ab8d968c18a
+call LvfsGenCapsuleSampleColor.bat Red   72e2945a-00da-448e-9aa7-075ad840f9d4

+ 28 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.sh

@@ -0,0 +1,28 @@
+# @file
+#   Linux script file to generate UEFI capsules for system firmware and
+#   firmware for sample devices
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+cd $(dirname $0)
+
+rm -R $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules
+mkdir $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules
+mkdir $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/SampleDevelopment
+mkdir $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert
+mkdir $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/DEBUG_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/SampleDevelopment/CapsuleApp.efi
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/RELEASE_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/SampleDevelopment/CapsuleAppRelease.efi
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/DEBUG_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert/CapsuleApp.efi
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/RELEASE_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert/CapsuleAppRelease.efi
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/DEBUG_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert/CapsuleApp.efi
+cp $WORKSPACE/Build/Vlv2TbltDevicePkg/RELEASE_GCC49/X64/CapsuleApp.efi $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert/CapsuleAppRelease.efi
+
+. GenCapsuleMinnowMax.sh
+. GenCapsuleMinnowMaxRelease.sh
+. GenCapsuleSampleColor.sh Blue  149DA854-7D19-4FAA-A91E-862EA1324BE6
+. GenCapsuleSampleColor.sh Green 79179BFD-704D-4C90-9E02-0AB8D968C18A
+. GenCapsuleSampleColor.sh Red   72E2945A-00DA-448E-9AA7-075AD840F9D4

+ 131 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.bat

@@ -0,0 +1,131 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for system firmware
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=4096267B-DA0A-42EB-B5EB-FEF31D207CB4
+set FMP_CAPSULE_FILE=MinnowMax.cap
+set FMP_CAPSULE_VERSION=0x0000000C
+set FMP_CAPSULE_STRING=0.0.0.12
+set FMP_CAPSULE_NAME="Intel MinnowMax DEBUG UEFI %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=%WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\FV\Vlv.ROM
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit /b
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment\MinnowMaxWindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\MinnowMaxWindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+if exist "%WINDOWS_CAPSULE_KEY%" (
+  CreateWindowsCapsule.py ^
+    UEFI ^
+    %FMP_CAPSULE_STRING% ^
+    %FMP_CAPSULE_GUID% ^
+    %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_VERSION% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+  xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\MinnowMaxWindowsCapsule
+  rmdir /s /q WindowsCapsule
+)
+
+erase %FMP_CAPSULE_FILE%

+ 65 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMax.sh

@@ -0,0 +1,65 @@
+# @file
+#   Linux script file to generate UEFI capsules for system firmware
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+FMP_CAPSULE_VENDOR=Intel
+FMP_CAPSULE_GUID=4096267B-DA0A-42EB-B5EB-FEF31D207CB4
+FMP_CAPSULE_FILE=MinnowMax.cap
+FMP_CAPSULE_VERSION=0x0000000C
+FMP_CAPSULE_STRING=0.0.0.12
+FMP_CAPSULE_NAME="Intel MinnowMax DEBUG UEFI $FMP_CAPSULE_STRING"
+FMP_CAPSULE_LSV=0x00000000
+FMP_CAPSULE_PAYLOAD=$WORKSPACE/Build/Vlv2TbltDevicePkg/DEBUG_GCC49/FV/Vlv.ROM
+
+if [ ! -e "$FMP_CAPSULE_PAYLOAD" ] ; then
+  return
+fi
+
+if [ -e NewCert.pem ]; then
+  #
+  # Sign capsule using OpenSSL with a new certificate
+  #
+  GenerateCapsule \
+    --encode \
+    -v \
+    --guid $FMP_CAPSULE_GUID \
+    --fw-version $FMP_CAPSULE_VERSION \
+    --lsv $FMP_CAPSULE_LSV \
+    --capflag PersistAcrossReset \
+    --capflag InitiateReset \
+    --signer-private-cert=NewCert.pem \
+    --other-public-cert=NewSub.pub.pem \
+    --trusted-public-cert=NewRoot.pub.pem \
+    -o $FMP_CAPSULE_FILE \
+    $FMP_CAPSULE_PAYLOAD
+
+  cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert
+
+  rm $FMP_CAPSULE_FILE
+fi
+
+#
+# Sign capsule using OpenSSL with EDK II Test Certificate
+#
+GenerateCapsule \
+  --encode \
+  -v \
+  --guid $FMP_CAPSULE_GUID \
+  --fw-version $FMP_CAPSULE_VERSION \
+  --lsv $FMP_CAPSULE_LSV \
+  --capflag PersistAcrossReset \
+  --capflag InitiateReset \
+  --signer-private-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestCert.pem \
+  --other-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.pem \
+  --trusted-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pub.pem \
+  -o $FMP_CAPSULE_FILE \
+  $FMP_CAPSULE_PAYLOAD
+
+cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
+
+rm $FMP_CAPSULE_FILE
+

+ 131 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.bat

@@ -0,0 +1,131 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for system firmware
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=4096267B-DA0A-42EB-B5EB-FEF31D207CB4
+set FMP_CAPSULE_FILE=MinnowMaxRelease.cap
+set FMP_CAPSULE_VERSION=0x0000000C
+set FMP_CAPSULE_STRING=0.0.0.12
+set FMP_CAPSULE_NAME="Intel MinnowMax RELEASE UEFI %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=%WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\FV\Vlv.ROM
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit /b
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment\MinnowMaxReleaseWindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\MinnowMaxReleaseWindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+if exist "%WINDOWS_CAPSULE_KEY%" (
+  CreateWindowsCapsule.py ^
+    UEFI ^
+    %FMP_CAPSULE_STRING% ^
+    %FMP_CAPSULE_GUID% ^
+    %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_VERSION% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+  xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\MinnowMaxReleaseWindowsCapsule
+  rmdir /s /q WindowsCapsule
+)
+
+erase %FMP_CAPSULE_FILE%

+ 65 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleMinnowMaxRelease.sh

@@ -0,0 +1,65 @@
+# @file
+#   Linux script file to generate UEFI capsules for system firmware
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+FMP_CAPSULE_VENDOR=Intel
+FMP_CAPSULE_GUID=4096267B-DA0A-42EB-B5EB-FEF31D207CB4
+FMP_CAPSULE_FILE=MinnowMaxRelease.cap
+FMP_CAPSULE_VERSION=0x0000000C
+FMP_CAPSULE_STRING=0.0.0.12
+FMP_CAPSULE_NAME="Intel MinnowMax RELEASE UEFI $FMP_CAPSULE_STRING"
+FMP_CAPSULE_LSV=0x00000000
+FMP_CAPSULE_PAYLOAD=$WORKSPACE/Build/Vlv2TbltDevicePkg/RELEASE_GCC49/FV/Vlv.ROM
+
+if [ ! -e "$FMP_CAPSULE_PAYLOAD" ] ; then
+  return
+fi
+
+if [ -e NewCert.pem ]; then
+  #
+  # Sign capsule using OpenSSL with a new certificate
+  #
+  GenerateCapsule \
+    --encode \
+    -v \
+    --guid $FMP_CAPSULE_GUID \
+    --fw-version $FMP_CAPSULE_VERSION \
+    --lsv $FMP_CAPSULE_LSV \
+    --capflag PersistAcrossReset \
+    --capflag InitiateReset \
+    --signer-private-cert=NewCert.pem \
+    --other-public-cert=NewSub.pub.pem \
+    --trusted-public-cert=NewRoot.pub.pem \
+    -o $FMP_CAPSULE_FILE \
+    $FMP_CAPSULE_PAYLOAD
+
+  cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert
+
+  rm $FMP_CAPSULE_FILE
+fi
+
+#
+# Sign capsule using OpenSSL with EDK II Test Certificate
+#
+GenerateCapsule \
+  --encode \
+  -v \
+  --guid $FMP_CAPSULE_GUID \
+  --fw-version $FMP_CAPSULE_VERSION \
+  --lsv $FMP_CAPSULE_LSV \
+  --capflag PersistAcrossReset \
+  --capflag InitiateReset \
+  --signer-private-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestCert.pem \
+  --other-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.pem \
+  --trusted-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pub.pem \
+  -o $FMP_CAPSULE_FILE \
+  $FMP_CAPSULE_PAYLOAD
+
+cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
+
+rm $FMP_CAPSULE_FILE
+

+ 137 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.bat

@@ -0,0 +1,137 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for a sample device
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set COLOR=%1
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=%2
+set FMP_CAPSULE_FILE=%COLOR%.cap
+set FMP_CAPSULE_VERSION=0x00000010
+set FMP_CAPSULE_STRING=0.0.0.16
+set FMP_CAPSULE_NAME="%COLOR% Progress Bar %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=Payload.bin
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+echo "%COLOR% Progress Bar" > %FMP_CAPSULE_PAYLOAD%
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment\%COLOR%WindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  if exist "%WINDOWS_CAPSULE_KEY%" (
+    CreateWindowsCapsule.py ^
+      UEFI ^
+      %FMP_CAPSULE_STRING% ^
+      %FMP_CAPSULE_GUID% ^
+      %FMP_CAPSULE_FILE% ^
+      %FMP_CAPSULE_VERSION% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_VENDOR% ^
+      %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+    xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert\%COLOR%WindowsCapsule
+    rmdir /s /q WindowsCapsule
+  )
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+if exist "%WINDOWS_CAPSULE_KEY%" (
+  CreateWindowsCapsule.py ^
+    UEFI ^
+    %FMP_CAPSULE_STRING% ^
+    %FMP_CAPSULE_GUID% ^
+    %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_VERSION% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_VENDOR% ^
+    %FMP_CAPSULE_NAME% %WINDOWS_CAPSULE_KEY%
+
+  xcopy /s/e/v/i/y WindowsCapsule %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%COLOR%WindowsCapsule
+  rmdir /s /q WindowsCapsule
+)
+
+erase %FMP_CAPSULE_FILE%
+
+erase %FMP_CAPSULE_PAYLOAD%

+ 70 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleSampleColor.sh

@@ -0,0 +1,70 @@
+# @file
+#   Linux script file to generate UEFI capsules for a sample device
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+COLOR=$1
+
+FMP_CAPSULE_VENDOR=Intel
+FMP_CAPSULE_GUID=$2
+FMP_CAPSULE_FILE=$COLOR.cap
+FMP_CAPSULE_VERSION=0x00000010
+FMP_CAPSULE_STRING=0.0.0.16
+FMP_CAPSULE_NAME="$COLOR Progress Bar $FMP_CAPSULE_STRING"
+FMP_CAPSULE_LSV=0x00000000
+FMP_CAPSULE_PAYLOAD=Payload.bin
+
+echo "$COLOR Progress Bar" > $FMP_CAPSULE_PAYLOAD
+
+if [ ! -e "$FMP_CAPSULE_PAYLOAD" ] ; then
+  return
+fi
+
+if [ -e NewCert.pem ]; then
+  #
+  # Sign capsule using OpenSSL with a new certificate
+  #
+  GenerateCapsule \
+    --encode \
+    -v \
+    --guid $FMP_CAPSULE_GUID \
+    --fw-version $FMP_CAPSULE_VERSION \
+    --lsv $FMP_CAPSULE_LSV \
+    --capflag PersistAcrossReset \
+    --capflag InitiateReset \
+    --signer-private-cert=NewCert.pem \
+    --other-public-cert=NewSub.pub.pem \
+    --trusted-public-cert=NewRoot.pub.pem \
+    -o $FMP_CAPSULE_FILE \
+    $FMP_CAPSULE_PAYLOAD
+
+  cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/NewCert
+
+  rm $FMP_CAPSULE_FILE
+fi
+
+#
+# Sign capsule using OpenSSL with EDK II Test Certificate
+#
+GenerateCapsule \
+  --encode \
+  -v \
+  --guid $FMP_CAPSULE_GUID \
+  --fw-version $FMP_CAPSULE_VERSION \
+  --lsv $FMP_CAPSULE_LSV \
+  --capflag PersistAcrossReset \
+  --capflag InitiateReset \
+  --signer-private-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestCert.pem \
+  --other-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestSub.pub.pem \
+  --trusted-public-cert=$WORKSPACE/edk2/BaseTools/Source/Python/Pkcs7Sign/TestRoot.pub.pem \
+  -o $FMP_CAPSULE_FILE \
+  $FMP_CAPSULE_PAYLOAD
+
+cp $FMP_CAPSULE_FILE $WORKSPACE/Build/Vlv2TbltDevicePkg/Capsules/TestCert
+
+rm $FMP_CAPSULE_FILE
+
+rm $FMP_CAPSULE_PAYLOAD

+ 14 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/Lvfs.ddf

@@ -0,0 +1,14 @@
+.OPTION EXPLICIT ; Generate errors on variable typos
+
+.Set CabinetNameTemplate=firmware.cab ; The name of the file
+.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
+.Set Cabinet=on ;
+.Set Compress=on ;
+.Set DiskDirectory1=.
+.Set MaxDiskSize=99999744               ; multiple of 512
+
+;*** Files to zip ;
+;
+firmware.bin
+firmware.metainfo.xml
+;***

+ 139 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMax.bat

@@ -0,0 +1,139 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for system firmware
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=4096267b-da0a-42eb-b5eb-fef31d207cb4
+set FMP_CAPSULE_BASE_NAME=MinnowMax
+set FMP_CAPSULE_FILE=%FMP_CAPSULE_BASE_NAME%.cap
+set FMP_CAPSULE_VERSION=0x0000000C
+set FMP_CAPSULE_VERSION_DECIMAL=12
+set FMP_CAPSULE_STRING=0.0.0.12
+set FMP_CAPSULE_NAME="Intel %FMP_CAPSULE_BASE_NAME% DEBUG UEFI %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=%WORKSPACE%\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\FV\Vlv.ROM
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit /b
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+copy %FMP_CAPSULE_FILE% firmware.bin
+copy template.metainfo.xml firmware.metainfo.xml
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+makecab /f Lvfs.ddf
+copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+erase firmware.cab
+erase setup.inf
+erase setup.rpt
+
+erase firmware.metainfo.xml
+erase firmware.bin
+erase %FMP_CAPSULE_FILE%

+ 139 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleMinnowMaxRelease.bat

@@ -0,0 +1,139 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for system firmware
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=4096267b-da0a-42eb-b5eb-fef31d207cb4
+set FMP_CAPSULE_BASE_NAME=MinnowMaxRelease
+set FMP_CAPSULE_FILE=%FMP_CAPSULE_BASE_NAME%.cap
+set FMP_CAPSULE_VERSION=0x0000000C
+set FMP_CAPSULE_VERSION_DECIMAL=12
+set FMP_CAPSULE_STRING=0.0.0.12
+set FMP_CAPSULE_NAME="Intel %FMP_CAPSULE_BASE_NAME% RELEASE UEFI %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=%WORKSPACE%\Build\Vlv2TbltDevicePkg\RELEASE_VS2015x86\FV\Vlv.ROM
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit /b
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+copy %FMP_CAPSULE_FILE% firmware.bin
+copy template.metainfo.xml firmware.metainfo.xml
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+makecab /f Lvfs.ddf
+copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+erase firmware.cab
+erase setup.inf
+erase setup.rpt
+
+erase firmware.metainfo.xml
+erase firmware.bin
+erase %FMP_CAPSULE_FILE%

+ 145 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/LvfsGenCapsuleSampleColor.bat

@@ -0,0 +1,145 @@
+@REM @file
+@REM   Windows batch file to generate UEFI capsules for a sample device
+@REM
+@REM Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+setlocal
+
+set COLOR=%1
+
+set FMP_CAPSULE_VENDOR=Intel
+set FMP_CAPSULE_GUID=%2
+set FMP_CAPSULE_BASE_NAME=%COLOR%
+set FMP_CAPSULE_FILE=%FMP_CAPSULE_BASE_NAME%.cap
+set FMP_CAPSULE_VERSION=0x00000010
+set FMP_CAPSULE_VERSION_DECIMAL=16
+set FMP_CAPSULE_STRING=0.0.0.16
+set FMP_CAPSULE_NAME="%FMP_CAPSULE_BASE_NAME% Progress Bar %FMP_CAPSULE_STRING%"
+set FMP_CAPSULE_LSV=0x00000000
+set FMP_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+set FMP_CAPSULE_PAYLOAD=Payload.bin
+set WINDOWS_CAPSULE_KEY=SAMPLE_DEVELOPMENT.pfx
+
+echo "%COLOR% Progress Bar" > %FMP_CAPSULE_PAYLOAD%
+
+if not exist "%FMP_CAPSULE_PAYLOAD%" exit
+
+if exist "%FMP_CAPSULE_KEY%" (
+  REM
+  REM Sign capsule using signtool
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signing-tool-path="c:\Program Files (x86)\Windows Kits\8.1\bin\x86" ^
+    --pfx-file %FMP_CAPSULE_KEY% ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\SampleDevelopment
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+if exist "NewCert.pem" (
+  REM
+  REM Sign capsule using OpenSSL with a new certificate
+  REM
+  call GenerateCapsule ^
+    --encode ^
+    -v ^
+    --guid %FMP_CAPSULE_GUID% ^
+    --fw-version %FMP_CAPSULE_VERSION% ^
+    --lsv %FMP_CAPSULE_LSV% ^
+    --capflag PersistAcrossReset ^
+    --capflag InitiateReset ^
+    --signer-private-cert=NewCert.pem ^
+    --other-public-cert=NewSub.pub.pem ^
+    --trusted-public-cert=NewRoot.pub.pem ^
+    -o %FMP_CAPSULE_FILE% ^
+    %FMP_CAPSULE_PAYLOAD%
+
+  copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\NewCert
+
+  copy %FMP_CAPSULE_FILE% firmware.bin
+  copy template.metainfo.xml firmware.metainfo.xml
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+  makecab /f Lvfs.ddf
+  copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+  erase firmware.cab
+  erase setup.inf
+  erase setup.rpt
+
+  erase firmware.metainfo.xml
+  erase firmware.bin
+  erase %FMP_CAPSULE_FILE%
+)
+
+REM
+REM Sign capsule using OpenSSL with EDK II Test Certificate
+REM
+call GenerateCapsule ^
+  --encode ^
+  -v ^
+  --guid %FMP_CAPSULE_GUID% ^
+  --fw-version %FMP_CAPSULE_VERSION% ^
+  --lsv %FMP_CAPSULE_LSV% ^
+  --capflag PersistAcrossReset ^
+  --capflag InitiateReset ^
+  --signer-private-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestCert.pem ^
+  --other-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestSub.pub.pem ^
+  --trusted-public-cert=%WORKSPACE%\edk2\BaseTools\Source\Python\Pkcs7Sign\TestRoot.pub.pem ^
+  -o %FMP_CAPSULE_FILE% ^
+  %FMP_CAPSULE_PAYLOAD%
+
+copy %FMP_CAPSULE_FILE% %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert
+
+copy %FMP_CAPSULE_FILE% firmware.bin
+copy template.metainfo.xml firmware.metainfo.xml
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_GUID', '%FMP_CAPSULE_GUID%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_BASE_NAME', '%FMP_CAPSULE_BASE_NAME%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_VERSION_DECIMAL', '%FMP_CAPSULE_VERSION_DECIMAL%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_STRING', '%FMP_CAPSULE_STRING%' | Out-File firmware.metainfo.xml -encoding ASCII"
+powershell -Command "(gc firmware.metainfo.xml) -replace 'FMP_CAPSULE_DATE', '%date%' | Out-File firmware.metainfo.xml -encoding ASCII"
+makecab /f Lvfs.ddf
+copy firmware.cab %WORKSPACE%\Build\Vlv2TbltDevicePkg\Capsules\TestCert\%FMP_CAPSULE_BASE_NAME%-%FMP_CAPSULE_STRING%.cab
+
+erase firmware.cab
+erase setup.inf
+erase setup.rpt
+
+erase firmware.metainfo.xml
+erase firmware.bin
+erase %FMP_CAPSULE_FILE%
+
+erase %FMP_CAPSULE_PAYLOAD%

+ 1 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc

@@ -0,0 +1 @@
+

+ 1 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc

@@ -0,0 +1 @@
+

+ 1 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc

@@ -0,0 +1 @@
+

+ 27 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/template.metainfo.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component type="firmware">
+  <id>com.intel.FMP_CAPSULE_BASE_NAME.firmware</id>
+  <name>FMP_CAPSULE_BASE_NAME</name>
+  <summary>System firmware for the FMP_CAPSULE_BASE_NAME</summary>
+  <description>
+    Description of System firmware for the FMP_CAPSULE_BASE_NAME
+  </description>
+  <provides>
+    <firmware type="flashed">FMP_CAPSULE_GUID</firmware>
+  </provides>
+  <url type="homepage">http://www.tianocore.org</url>
+  <metadata_license>CC0-1.0</metadata_license>
+  <project_license>BSD</project_license>
+  <developer_name>Tianocore</developer_name>
+  <releases>
+    <release version="FMP_CAPSULE_VERSION_DECIMAL" date="FMP_CAPSULE_DATE">
+      <description>
+        Build FMP_CAPSULE_STRING
+      </description>
+    </release>
+  </releases>
+  <!-- most OEMs do not need to do this... -->
+  <custom>
+    <value key="LVFS::InhibitDownload"/>
+  </custom>
+</component>

+ 589 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c

@@ -0,0 +1,589 @@
+/**
+
+Copyright (c) 2016, Microsoft Corporation.  All rights reserved.
+Copyright (c) 2019, Intel Corporation.  All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/FmpDeviceLib.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Library/PlatformFlashAccessLib.h>
+
+//#include <Protocol/FirmwareManagement.h>
+
+//#include <Guid/SystemResourceTable.h>
+
+typedef struct {
+  PLATFORM_FIRMWARE_TYPE          FirmwareType;
+  FLASH_ADDRESS_TYPE              AddressType;
+  EFI_PHYSICAL_ADDRESS            BaseAddress;
+  UINTN                           Length;
+  UINTN                           ImageOffset;
+} UPDATE_CONFIG_DATA;
+
+UPDATE_CONFIG_DATA mUpdateConfigData[] = {
+  { PlatformFirmwareTypeSystemFirmware, FlashAddressTypeRelativeAddress, 0x00000000, 0x00040000, 0x00000000 },
+  { PlatformFirmwareTypeSystemFirmware, FlashAddressTypeRelativeAddress, 0x000C0000, 0x00050000, 0x000C0000 },
+  { PlatformFirmwareTypeSystemFirmware, FlashAddressTypeRelativeAddress, 0x00110000, 0x00210000, 0x00110000 },
+  { PlatformFirmwareTypeSystemFirmware, FlashAddressTypeRelativeAddress, 0x00320000, 0x00070000, 0x00320000 },
+  { PlatformFirmwareTypeSystemFirmware, FlashAddressTypeRelativeAddress, 0x00390000, 0x00070000, 0x00390000 }
+};
+
+/**
+  Used to pass the FMP install function to this lib.  This allows the library to
+  have control of the handle that the FMP instance is installed on.  This allows
+  the library to use DriverBinding protocol model to locate its device(s) in the
+  system.
+
+  @param[in] Func  Function pointer to FMP install function.
+
+  @retval EFI_SUCCESS       Library has saved function pointer and will call
+                            function pointer on each DriverBinding Start.
+  @retval EFI_UNSUPPORTED   Library doesn't use driver binding and only supports
+                            a single instance.
+  @retval other error       Error occurred.  Don't install FMP
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpInstaller (
+  IN FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER Func
+  )
+{
+  //
+  // This is a system firmware update that does not use Driver Binding Protocol
+  //
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Returns the size, in bytes, of the firmware image currently stored in the
+  firmware device.  This function is used to by the GetImage() and
+  GetImageInfo() services of the Firmware Management Protocol.  If the image
+  size can not be determined from the firmware device, then 0 must be returned.
+
+  @param[out] Size  Pointer to the size, in bytes, of the firmware image
+                    currently stored in the firmware device.
+
+  @retval EFI_SUCCESS            The size of the firmware image currently
+                                 stored in the firmware device was returned.
+  @retval EFI_INVALID_PARAMETER  Size is NULL.
+  @retval EFI_UNSUPPORTED        The firmware device does not support reporting
+                                 the size of the currently stored firmware image.
+  @retval EFI_DEVICE_ERROR       An error occured attempting to determine the
+                                 size of the firmware image currently stored in
+                                 in the firmware device.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetSize (
+  IN UINTN  *Size
+  )
+{
+  if (Size == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Size = PcdGet32 (PcdBiosRomBase);
+  return EFI_SUCCESS;
+}
+
+/**
+  Used to return a library supplied guid that will be the ImageTypeId guid of
+  the FMP descriptor.  This is optional but can be used if at runtime the guid
+  needs to be determined.
+
+  @param[out] Guid  Double Guid Ptr that will be updated to point to guid.
+                    This should be from static memory and will not be freed.
+
+  @return EFI_UNSUPPORTED  Library instance doesn't need dynamic guid.
+  @return Error            Any error will cause the wrapper to use the GUID
+                           defined by PCD.
+  @return EFI_SUCCESS      Guid ptr should be updated to point to static memeory
+                           which contains a valid guid.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImageTypeIdGuidPtr (
+  OUT EFI_GUID  **Guid
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Returns values used to fill in the AttributesSupported and AttributesSettings
+  fields of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+  GetImageInfo() service of the Firmware Management Protocol.  The following
+  bit values from the Firmware Management Protocol may be combined:
+    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
+    IMAGE_ATTRIBUTE_RESET_REQUIRED
+    IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
+    IMAGE_ATTRIBUTE_IN_USE
+    IMAGE_ATTRIBUTE_UEFI_IMAGE
+
+  @param[out] Supported  Attributes supported by this firmware device.
+  @param[out] Setting    Attributes settings for this firmware device.
+
+  @retval EFI_SUCCESS            The attributes supported by the firmware
+                                 device were returned.
+  @retval EFI_INVALID_PARAMETER  Supported is NULL.
+  @retval EFI_INVALID_PARAMETER  Setting is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetAttributes (
+  IN OUT UINT64  *Supported,
+  IN OUT UINT64  *Setting
+  )
+{
+  if (Supported == NULL || Setting == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Supported = (IMAGE_ATTRIBUTE_IMAGE_UPDATABLE         |
+                IMAGE_ATTRIBUTE_RESET_REQUIRED          |
+                IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
+                IMAGE_ATTRIBUTE_IN_USE
+                );
+  *Setting   = (IMAGE_ATTRIBUTE_IMAGE_UPDATABLE         |
+                IMAGE_ATTRIBUTE_RESET_REQUIRED          |
+                IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
+                IMAGE_ATTRIBUTE_IN_USE
+                );
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the current Lowest Supported Version.
+
+  This is a protection mechanism so that a previous version with known issue is
+  not applied.  ONLY implement this if your running firmware has a method to
+  return this at runtime.  If EFI_UNSUPPORTED is returned, then the Lowest
+  Supported Version is stored in a UEFI Variable.
+
+  @param[out] Version  On return this value represents the current Lowest
+                       Supported Version (in same format as GetVersion).
+
+  @retval EFI_SUCCESS       The Lowest Supported Version was correctly retrieved
+  @retval EFI_UNSUPPORTED   Device firmware doesn't support reporting LSV
+  @retval EFI_DEVICE_ERROR  Error occurred when trying to get the LSV
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetLowestSupportedVersion (
+  IN OUT UINT32  *LowestSupportedVersion
+  )
+{
+  //
+  // Retrieve the lowest support version from a PCD
+  // NOTE: This method of using a PCD can only be used for the system firmware
+  //       FMP instance that is updated every time the system firmware is
+  //       updated.  If system firmware updates support partial updates that
+  //       would not include the system firmware FMP instance, then a PCD can
+  //       not be used and the value must come from the currently running system
+  //       firmware image.
+  //
+  *LowestSupportedVersion = PcdGet32 (PcdSystemFirmwareFmpLowestSupportedVersion);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Returns the Null-terminated Unicode string that is used to fill in the
+  VersionName field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is
+  returned by the GetImageInfo() service of the Firmware Management Protocol.
+  The returned string must be allocated using EFI_BOOT_SERVICES.AllocatePool().
+
+  @note It is recommended that all firmware devices support a method to report
+        the VersionName string from the currently stored firmware image.
+
+  @param[out] VersionString  The version string retrieved from the currently
+                             stored firmware image.
+
+  @retval EFI_SUCCESS            The version string of currently stored
+                                 firmware image was returned in Version.
+  @retval EFI_INVALID_PARAMETER  VersionString is NULL.
+  @retval EFI_UNSUPPORTED        The firmware device does not support a method
+                                 to report the version string of the currently
+                                 stored firmware image.
+  @retval EFI_DEVICE_ERROR       An error occurred attempting to retrieve the
+                                 version string of the currently stored
+                                 firmware image.
+  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to allocate the
+                                 buffer for the version string of the currently
+                                 stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersionString (
+  OUT CHAR16  **VersionString
+  )
+{
+  if (VersionString == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Retrieve the version string from a PCD
+  // NOTE: This method of using a PCD can only be used for the system firmware
+  //       FMP instance that is updated every time the system firmware is
+  //       updated.  If system firmware updates support partial updates that
+  //       would not include the system firmware FMP instance, then a PCD can
+  //       not be used and the value must come from the currently running system
+  //       firmware image.
+  //
+  *VersionString = (CHAR16 *)AllocateCopyPool (
+                               PcdGetSize (PcdSystemFirmwareFmpVersionString),
+                               PcdGetPtr (PcdSystemFirmwareFmpVersionString)
+                               );
+  if (*VersionString == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the current running version.
+
+  ONLY implement this if your running firmware has a method to return this at
+  runtime.
+
+  @param[out] Version  On return this value represents the current running
+                       version.
+
+  @retval EFI_SUCCESS       The version was correctly retrieved.
+  @retval EFI_UNSUPPORTED   Device firmware doesn't support reporting current
+                            version.
+  @retval EFI_DEVICE_ERROR  Error occurred when trying to get the version.
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersion (
+  IN OUT UINT32  *Version
+  )
+{
+  //
+  // Retrieve the version string from a PCD
+  // NOTE: This method of using a PCD can only be used for the system firmware
+  //       FMP instance that is updated every time the system firmware is
+  //       updated.  If system firmware updates support partial updates that
+  //       would not include the system firmware FMP instance, then a PCD can
+  //       not be used and the value must come from the currently running system
+  //       firmware image.
+  //
+  *Version = PcdGet32 (PcdSystemFirmwareFmpVersion);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Retrieves a copy of the current firmware image of the device.
+
+  This function allows a copy of the current firmware image to be created and
+  saved.  The saved copy could later been used, for example, in firmware image
+  recovery or rollback.
+
+  @param[out] Image      Points to the buffer where the current image is copied
+                         to.
+  @param[out] ImageSize  On entry, points to the size of the buffer pointed to
+                         by Image, in bytes.  On return, points to the length of
+                         the image, in bytes.
+
+  @retval EFI_SUCCESS            The image was successfully read from the device.
+  @retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small
+                                 to hold the image. The current buffer size
+                                 needed to hold the image is returned in
+                                 ImageSize.
+  @retval EFI_INVALID_PARAMETER  The Image was NULL.
+  @retval EFI_NOT_FOUND          The current image is not copied to the buffer.
+  @retval EFI_UNSUPPORTED        The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImage (
+  IN OUT VOID   *Image,
+  IN OUT UINTN  *ImageSize
+  )
+{
+  //
+  // Check for invalid p;arameters
+  //
+  if (Image == NULL || ImageSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Make sure the buffer is big enough to hold the device image
+  //
+  if (*ImageSize < PcdGet32 (PcdBiosRomSize)) {
+    *ImageSize = PcdGet32 (PcdBiosRomSize);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  //
+  // Copy the device image to the buffer
+  //
+  *ImageSize = PcdGet32 (PcdBiosRomSize);
+  CopyMem (
+    Image,
+    (VOID *)(UINTN)PcdGet32 (PcdBiosRomBase),
+    *ImageSize
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Updates the firmware image of the device.
+
+  This function updates the hardware with the new firmware image.  This function
+  returns EFI_UNSUPPORTED if the firmware image is not updatable.  If the
+  firmware image is updatable, the function should perform the following minimal
+  validations before proceeding to do the firmware image update.
+    - Validate the image is a supported image for this device.  The function
+      returns EFI_ABORTED if the image is unsupported.  The function can
+      optionally provide more detailed information on why the image is not a
+      supported image.
+    - Validate the data from VendorCode if not null.  Image validation must be
+      performed before VendorCode data validation.  VendorCode data is ignored
+      or considered invalid if image validation failed.  The function returns
+      EFI_ABORTED if the data is invalid.
+
+  VendorCode enables vendor to implement vendor-specific firmware image update
+  policy.  Null if the caller did not specify the policy or use the default
+  policy.  As an example, vendor can implement a policy to allow an option to
+  force a firmware image update when the abort reason is due to the new firmware
+  image version is older than the current firmware image version or bad image
+  checksum.  Sensitive operations such as those wiping the entire firmware image
+  and render the device to be non-functional should be encoded in the image
+  itself rather than passed with the VendorCode.  AbortReason enables vendor to
+  have the option to provide a more detailed description of the abort reason to
+  the caller.
+
+  @param[in]  Image             Points to the new image.
+  @param[in]  ImageSize         Size of the new image in bytes.
+  @param[in]  VendorCode        This enables vendor to implement vendor-specific
+                                firmware image update policy. Null indicates the
+                                caller did not specify the policy or use the
+                                default policy.
+  @param[in]  Progress          A function used by the driver to report the
+                                progress of the firmware update.
+  @param[in]  CapsuleFwVersion  FMP Payload Header version of the image.
+  @param[out] AbortReason       A pointer to a pointer to a null-terminated
+                                string providing more details for the aborted
+                                operation. The buffer is allocated by this
+                                function with AllocatePool(), and it is the
+                                caller's responsibility to free it with a call
+                                to FreePool().
+
+  @retval EFI_SUCCESS            The device was successfully updated with the
+                                 new image.
+  @retval EFI_ABORTED            The operation is aborted.
+  @retval EFI_INVALID_PARAMETER  The Image was NULL.
+  @retval EFI_UNSUPPORTED        The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetImage (
+  IN  CONST VOID                                     *Image,
+  IN  UINTN                                          ImageSize,
+  IN  CONST VOID                                     *VendorCode,
+  IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,
+  IN  UINT32                                         CapsuleFwVersion,
+  OUT CHAR16                                         **AbortReason
+  )
+{
+  EFI_STATUS          Status;
+  UINT32              Updateable;
+  UINTN               Percentage;
+  UINTN               Index;
+  UPDATE_CONFIG_DATA  *ConfigData;
+  UINTN               TotalSize;
+  UINTN               BytesWritten;
+
+  Updateable = 0;
+  Status = FmpDeviceCheckImage (Image, ImageSize, &Updateable);
+  if (EFI_ERROR (Status)) {
+    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image failed with %r.\n", Status));
+    return Status;
+  }
+
+  if (Updateable != IMAGE_UPDATABLE_VALID) {
+    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image returned that the Image was not valid for update.  Updatable value = 0x%X.\n", Updateable));
+    return EFI_ABORTED;
+  }
+
+  if (Progress == NULL) {
+    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Invalid progress callback\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = Progress (15);
+  if (EFI_ERROR (Status)) {
+    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));
+  }
+
+  //
+  // Write the image to the firmware device
+  //
+  Progress (20);
+  if (EFI_ERROR (Status)) {
+    DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));
+  }
+
+  //
+  // Simulate update with delays between progress updates
+  //
+  for (Percentage = 20; Percentage <= 100; Percentage++) {
+    //
+    // Wait 0.05 seconds
+    //
+//    gBS->Stall (50000);
+
+//    Progress (Percentage);
+//    if (EFI_ERROR (Status)) {
+//      DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status));
+//    }
+  }
+
+  DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %d Images ...\n", ARRAY_SIZE (mUpdateConfigData)));
+
+  if (ARRAY_SIZE (mUpdateConfigData) == 0) {
+    DEBUG((DEBUG_INFO, "PlatformUpdate: BaseAddress - 0x%lx ImageOffset - 0x%x Length - 0x%x\n", 0, 0, ImageSize));
+    Status = PerformFlashWriteWithProgress (
+               PlatformFirmwareTypeSystemFirmware,  // FirmwareType
+               0x00000000,                          // FlashAddress
+               FlashAddressTypeRelativeAddress,     // FlashAddressType
+               (VOID *)(UINTN)Image,                // Buffer
+               ImageSize,                           // BufferLength
+               Progress,                            // Progress
+               20,                                  // StartPercentage
+               100                                  // EndPercentage
+               );
+  }
+
+
+  //
+  // Compute total size of update
+  //
+  for (Index = 0, TotalSize = 0; Index < ARRAY_SIZE (mUpdateConfigData); Index++) {
+    TotalSize += mUpdateConfigData[Index].Length;
+  }
+
+  BytesWritten = 0;
+  for (Index = 0, ConfigData = mUpdateConfigData; Index < ARRAY_SIZE (mUpdateConfigData); Index++, ConfigData++) {
+    DEBUG((DEBUG_INFO, "PlatformUpdate(%d): BaseAddress - 0x%lx ImageOffset - 0x%x Length - 0x%x\n",
+      Index,
+      ConfigData->BaseAddress,
+      ConfigData->ImageOffset,
+      ConfigData->Length
+      ));
+    Status = PerformFlashWriteWithProgress (
+               ConfigData->FirmwareType,                                     // FirmwareType
+               ConfigData->BaseAddress,                                      // FlashAddress
+               ConfigData->AddressType,                                      // FlashAddressType
+               (VOID *)((UINTN)Image + (UINTN)ConfigData->ImageOffset),      // Buffer
+               ConfigData->Length,                                           // BufferLength
+               Progress,                                                     // Progress
+               20 + (BytesWritten * 80) / TotalSize,                         // StartPercentage
+               20 + ((BytesWritten + ConfigData->Length) * 80) / TotalSize   // EndPercentage
+               );
+    if (EFI_ERROR(Status)) {
+      break;
+    }
+    BytesWritten += ConfigData->Length;
+  }
+
+  DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %r\n", Status));
+
+  return Status;
+}
+
+/**
+Checks if the firmware image is valid for the device.
+
+This function allows firmware update application to validate the firmware image without
+invoking the SetImage() first.
+
+@param[in]  Image              Points to the new image.
+@param[in]  ImageSize          Size of the new image in bytes.
+@param[out] ImageUpdatable     Indicates if the new image is valid for update. It also provides,
+if available, additional information if the image is invalid.
+
+@retval EFI_SUCCESS            The image was successfully checked.
+@retval EFI_INVALID_PARAMETER  The Image was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceCheckImage (
+  IN  CONST VOID  *Image,
+  IN  UINTN       ImageSize,
+  OUT UINT32      *ImageUpdateable
+  )
+{
+  if (ImageUpdateable == NULL) {
+    DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  //Set to valid and then if any tests fail it will update this flag.
+  //
+  *ImageUpdateable = IMAGE_UPDATABLE_VALID;
+
+  if (Image == NULL) {
+    DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n"));
+    //
+    // Not sure if this is needed
+    //
+    *ImageUpdateable = IMAGE_UPDATABLE_INVALID;
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Make sure the image size is correct
+  //
+  if (ImageSize != PcdGet32 (PcdBiosRomSize)) {
+    *ImageUpdateable = IMAGE_UPDATABLE_INVALID;
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Device firmware should trigger lock mechanism so that device fw can not be
+  updated or tampered with. This lock mechanism is generally only cleared by a
+  full system reset (not just sleep state/low power mode)
+
+  @retval EFI_SUCCESS           The device was successfully locked.
+  @retval EFI_UNSUPPORTED       The hardware device/firmware doesn't support locking
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceLock (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_INFO, "VLV2: FmpDeviceLock() for system FLASH\n"));
+  // TODO: Add lock logic
+  return EFI_UNSUPPORTED;
+}

+ 46 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf

@@ -0,0 +1,46 @@
+##
+# Copyright (c) 2016, Microsoft Corporation
+
+# All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Vlv2FmpDeviceLib
+  FILE_GUID                      = 83723F51-39B5-4D99-A974-90132AB55F83
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FmpDeviceLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FmpDeviceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  FmpDevicePkg/FmpDevicePkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  PlatformFlashAccessLib
+
+[Pcd]
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomBase
+  gPlatformModuleTokenSpaceGuid.PcdBiosRomSize
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupportedVersion
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion
+  gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString
+

+ 412 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c

@@ -0,0 +1,412 @@
+/**
+
+Copyright (c) 2016, Microsoft Corporation
+
+All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareManagement.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FmpDeviceLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+  Used to pass the FMP install function to this lib.
+  This allows the library to have control of the handle
+  that the FMP instance is installed on.  This allows the library
+  to use DriverBinding protocol model to locate its device(s) in the
+  system.
+
+  @param[in]  Function pointer to FMP install function.
+
+  @retval EFI_SUCCESS      Library has saved function pointer and will call function pointer on each DriverBinding Start.
+  @retval EFI_UNSUPPORTED  Library doesn't use driver binding and only supports a single instance.
+  @retval other error      Error occurred.  Don't install FMP
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpInstaller(
+IN FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER Func
+)
+{
+  // Because this is a sample lib with very simple fake device we don't use
+  // the driverbinding protocol to locate our device.
+  //
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+Used to get the size of the image in bytes.
+NOTE - Do not return zero as that will identify the device as
+not updatable.
+
+@retval UINTN that represents the size of the firmware.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetSize (
+  IN UINTN  *Size
+  )
+{
+  if (Size == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Size = 0x1000;
+  return EFI_SUCCESS;
+}
+
+/**
+Used to return a library supplied guid that will be the ImageTypeId guid of the FMP descriptor.
+This is optional but can be used if at runtime the guid needs to be determined.
+
+@param  Guid:  Double Guid Ptr that will be updated to point to guid.  This should be from static memory
+and will not be freed.
+@return EFI_UNSUPPORTED: if you library instance doesn't need dynamic guid return this.
+@return Error: Any error will cause the wrapper to use the GUID defined by PCD
+@return EFI_SUCCESS:  Guid ptr should be updated to point to static memeory which contains a valid guid
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImageTypeIdGuidPtr(
+  OUT EFI_GUID** Guid)
+{
+  //this instance doesn't need dynamic guid detection.
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Returns values used to fill in the AttributesSupported and AttributesSettings
+  fields of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+  GetImageInfo() service of the Firmware Management Protocol.  The following
+  bit values from the Firmware Management Protocol may be combined:
+    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
+    IMAGE_ATTRIBUTE_RESET_REQUIRED
+    IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
+    IMAGE_ATTRIBUTE_IN_USE
+    IMAGE_ATTRIBUTE_UEFI_IMAGE
+
+  @param[out] Supported  Attributes supported by this firmware device.
+  @param[out] Setting    Attributes settings for this firmware device.
+
+  @retval EFI_SUCCESS            The attributes supported by the firmware
+                                 device were returned.
+  @retval EFI_INVALID_PARAMETER  Supported is NULL.
+  @retval EFI_INVALID_PARAMETER  Setting is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetAttributes (
+  IN OUT UINT64  *Supported,
+  IN OUT UINT64  *Setting
+  )
+{
+  if (Supported == NULL || Setting == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *Supported = (IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_IN_USE);
+  *Setting   = (IMAGE_ATTRIBUTE_IMAGE_UPDATABLE | IMAGE_ATTRIBUTE_IN_USE);
+  return EFI_SUCCESS;
+}
+
+/**
+Gets the current Lowest Supported Version.
+This is a protection mechanism so that a previous version with known issue is not
+applied.
+
+ONLY implement this if your running firmware has a method to return this at runtime.
+
+@param[out] Version           On return this value represents the
+current Lowest Supported Version (in same format as GetVersion).
+
+@retval EFI_SUCCESS           The Lowest Supported Version was correctly retrieved
+@retval EFI_UNSUPPORTED       Device firmware doesn't support reporting LSV
+@retval EFI_DEVICE_ERROR      Error occurred when trying to get the LSV
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetLowestSupportedVersion (
+  IN OUT UINT32* LowestSupportedVersion
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Returns the Null-terminated Unicode string that is used to fill in the
+  VersionName field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is
+  returned by the GetImageInfo() service of the Firmware Management Protocol.
+  The returned string must be allocated using EFI_BOOT_SERVICES.AllocatePool().
+
+  @note It is recommended that all firmware devices support a method to report
+        the VersionName string from the currently stored firmware image.
+
+  @param[out] VersionString  The version string retrieved from the currently
+                             stored firmware image.
+
+  @retval EFI_SUCCESS            The version string of currently stored
+                                 firmware image was returned in Version.
+  @retval EFI_INVALID_PARAMETER  VersionString is NULL.
+  @retval EFI_UNSUPPORTED        The firmware device does not support a method
+                                 to report the version string of the currently
+                                 stored firmware image.
+  @retval EFI_DEVICE_ERROR       An error occurred attempting to retrieve the
+                                 version string of the currently stored
+                                 firmware image.
+  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to allocate the
+                                 buffer for the version string of the currently
+                                 stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersionString (
+  OUT CHAR16  **VersionString
+  )
+{
+  if (VersionString == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  *VersionString = NULL;
+  return EFI_UNSUPPORTED;
+}
+
+/**
+Gets the current running version.
+ONLY implement this if your running firmware has a method to return this at runtime.
+
+@param[out] Version           On return this value represents the current running version
+
+@retval EFI_SUCCESS           The version was correctly retrieved
+@retval EFI_UNSUPPORTED       Device firmware doesn't support reporting current version
+@retval EFI_DEVICE_ERROR      Error occurred when trying to get the version
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersion(
+IN OUT UINT32* Version
+)
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+Retrieves a copy of the current firmware image of the device.
+
+This function allows a copy of the current firmware image to be created and saved.
+The saved copy could later been used, for example, in firmware image recovery or rollback.
+
+@param[out] Image              Points to the buffer where the current image is copied to.
+@param[out] ImageSize          On entry, points to the size of the buffer pointed to by Image, in bytes.
+On return, points to the length of the image, in bytes.
+
+@retval EFI_SUCCESS            The device was successfully updated with the new image.
+@retval EFI_BUFFER_TOO_SMALL   The buffer specified by ImageSize is too small to hold the
+image. The current buffer size needed to hold the image is returned
+in ImageSize.
+@retval EFI_INVALID_PARAMETER  The Image was NULL.
+@retval EFI_NOT_FOUND          The current image is not copied to the buffer.
+@retval EFI_UNSUPPORTED        The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImage(
+IN  OUT  VOID                         *Image,
+IN  OUT  UINTN                        *ImageSize
+)
+/*++
+
+Routine Description:
+
+    This is a function used to read the current firmware from the device into memory.
+    This is an optional function and can return EFI_UNSUPPORTED.  This is useful for
+    test and diagnostics.
+
+Arguments:
+    Image               -- Buffer to place the image into.
+    ImageSize           -- Size of the Image buffer.
+
+Return Value:
+
+    EFI_STATUS code.
+    If not possible or not practical return EFI_UNSUPPORTED.
+
+--*/
+{
+  return EFI_UNSUPPORTED;
+}//GetImage()
+
+
+/**
+Updates the firmware image of the device.
+
+This function updates the hardware with the new firmware image.
+This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
+If the firmware image is updatable, the function should perform the following minimal validations
+before proceeding to do the firmware image update.
+- Validate the image is a supported image for this device.  The function returns EFI_ABORTED if
+the image is unsupported.  The function can optionally provide more detailed information on
+why the image is not a supported image.
+- Validate the data from VendorCode if not null.  Image validation must be performed before
+VendorCode data validation.  VendorCode data is ignored or considered invalid if image
+validation failed.  The function returns EFI_ABORTED if the data is invalid.
+
+VendorCode enables vendor to implement vendor-specific firmware image update policy.  Null if
+the caller did not specify the policy or use the default policy.  As an example, vendor can implement
+a policy to allow an option to force a firmware image update when the abort reason is due to the new
+firmware image version is older than the current firmware image version or bad image checksum.
+Sensitive operations such as those wiping the entire firmware image and render the device to be
+non-functional should be encoded in the image itself rather than passed with the VendorCode.
+AbortReason enables vendor to have the option to provide a more detailed description of the abort
+reason to the caller.
+
+@param[in]  Image              Points to the new image.
+@param[in]  ImageSize          Size of the new image in bytes.
+@param[in]  VendorCode         This enables vendor to implement vendor-specific firmware image update policy.
+Null indicates the caller did not specify the policy or use the default policy.
+@param[in]  Progress           A function used by the driver to report the progress of the firmware update.
+@param[in]  CapsuleFwVersion   FMP Payload Header version of the image
+@param[out] AbortReason        A pointer to a pointer to a null-terminated string providing more
+details for the aborted operation. The buffer is allocated by this function
+with AllocatePool(), and it is the caller's responsibility to free it with a
+call to FreePool().
+
+@retval EFI_SUCCESS            The device was successfully updated with the new image.
+@retval EFI_ABORTED            The operation is aborted.
+@retval EFI_INVALID_PARAMETER  The Image was NULL.
+@retval EFI_UNSUPPORTED        The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetImage (
+IN  CONST VOID                                       *Image,
+IN  UINTN                                            ImageSize,
+IN  CONST VOID                                       *VendorCode,
+IN  EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS    Progress,
+IN  UINT32                                           CapsuleFwVersion,
+OUT CHAR16                                           **AbortReason
+)
+{
+    EFI_STATUS Status                         = EFI_SUCCESS;
+    UINT32 Updateable                         = 0;
+
+    Status = FmpDeviceCheckImage(Image, ImageSize, &Updateable);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((DEBUG_ERROR, "SetImage - Check Image failed with %r.\n", Status));
+        goto cleanup;
+    }
+
+    if (Updateable != IMAGE_UPDATABLE_VALID)
+    {
+        DEBUG((DEBUG_ERROR, "SetImage - Check Image returned that the Image was not valid for update.  Updatable value = 0x%X.\n", Updateable));
+        Status = EFI_ABORTED;
+        goto cleanup;
+    }
+
+    if (Progress == NULL)
+    {
+        DEBUG((DEBUG_ERROR, "SetImage - Invalid progress callback\n"));
+        Status = EFI_INVALID_PARAMETER;
+        goto cleanup;
+    }
+
+    Status = Progress(15);
+    if (EFI_ERROR(Status))
+    {
+        DEBUG((DEBUG_ERROR, "SetImage - Progress Callback failed with Status %r.\n", Status));
+    }
+
+    {
+      UINTN  p;
+
+      for (p = 20; p < 100; p++) {
+        gBS->Stall (100000);  //us  = 0.1 seconds
+        Progress (p);
+      }
+    }
+
+    //TODO: add support for VendorCode, and AbortReason
+cleanup:
+    return Status;
+}// SetImage()
+
+
+
+/**
+Checks if the firmware image is valid for the device.
+
+This function allows firmware update application to validate the firmware image without
+invoking the SetImage() first.
+
+@param[in]  Image              Points to the new image.
+@param[in]  ImageSize          Size of the new image in bytes.
+@param[out] ImageUpdatable     Indicates if the new image is valid for update. It also provides,
+if available, additional information if the image is invalid.
+
+@retval EFI_SUCCESS            The image was successfully checked.
+@retval EFI_INVALID_PARAMETER  The Image was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceCheckImage(
+IN  CONST VOID                        *Image,
+IN  UINTN                             ImageSize,
+OUT UINT32                            *ImageUpdateable
+)
+{
+    EFI_STATUS status = EFI_SUCCESS;
+
+    if (ImageUpdateable == NULL)
+    {
+        DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n"));
+        status = EFI_INVALID_PARAMETER;
+        goto cleanup;
+    }
+
+    //
+    //Set to valid and then if any tests fail it will update this flag.
+    //
+    *ImageUpdateable = IMAGE_UPDATABLE_VALID;
+
+    if (Image == NULL)
+    {
+        DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n"));
+        *ImageUpdateable = IMAGE_UPDATABLE_INVALID; //not sure if this is needed
+        return EFI_INVALID_PARAMETER;
+    }
+
+cleanup:
+    return status;
+}// CheckImage()
+
+/**
+Device firmware should trigger lock mechanism so that device fw can not be updated or tampered with.
+This lock mechanism is generally only cleared by a full system reset (not just sleep state/low power mode)
+
+@retval EFI_SUCCESS           The device was successfully locked.
+@retval EFI_UNSUPPORTED       The hardware device/firmware doesn't support locking
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceLock(
+)
+{
+  return EFI_SUCCESS;
+}

+ 34 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf

@@ -0,0 +1,34 @@
+##
+# Copyright (c) 2016, Microsoft Corporation
+
+# All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Vlv2FmpDeviceLibSample
+  FILE_GUID                      = 582DF9AB-E626-42A8-A11C-3FEA098FF3FA
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FmpDeviceLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FmpDeviceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+  DebugLib
+  BaseLib
+  UefiBootServicesTableLib   #for stall...remove later as stall is only needed to show progress
+

+ 685 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c

@@ -0,0 +1,685 @@
+/** @file
+  Platform Flash Access library.
+
+  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PlatformFlashAccessLib.h>
+//#include <Library/FlashDeviceLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/Spi.h>
+#include <Library/CacheMaintenanceLib.h>
+#include "PchAccess.h"
+#include <Library/IoLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/PrintLib.h>
+
+//#define SECTOR_SIZE_64KB  0x10000      // Common 64kBytes sector size
+//#define ALINGED_SIZE  SECTOR_SIZE_64KB
+
+#define BLOCK_SIZE 0x1000
+#define ALINGED_SIZE BLOCK_SIZE
+
+#define R_PCH_LPC_BIOS_CNTL                       0xDC
+#define B_PCH_LPC_BIOS_CNTL_SMM_BWP               0x20            ///< SMM BIOS write protect disable
+
+//
+// Prefix Opcode Index on the host SPI controller
+//
+typedef enum {
+  SPI_WREN,             // Prefix Opcode 0: Write Enable
+  SPI_EWSR,             // Prefix Opcode 1: Enable Write Status Register
+} PREFIX_OPCODE_INDEX;
+//
+// Opcode Menu Index on the host SPI controller
+//
+typedef enum {
+  SPI_READ_ID,        // Opcode 0: READ ID, Read cycle with address
+  SPI_READ,           // Opcode 1: READ, Read cycle with address
+  SPI_RDSR,           // Opcode 2: Read Status Register, No address
+  SPI_WRDI_SFDP,      // Opcode 3: Write Disable or Discovery Parameters, No address
+  SPI_SERASE,         // Opcode 4: Sector Erase (4KB), Write cycle with address
+  SPI_BERASE,         // Opcode 5: Block Erase (32KB), Write cycle with address
+  SPI_PROG,           // Opcode 6: Byte Program, Write cycle with address
+  SPI_WRSR,           // Opcode 7: Write Status Register, No address
+} SPI_OPCODE_INDEX;
+
+STATIC EFI_PHYSICAL_ADDRESS     mInternalFdAddress;
+
+EFI_SPI_PROTOCOL  *mSpiProtocol;
+
+/**
+  Read NumBytes bytes of data from the address specified by
+  PAddress into Buffer.
+
+  @param[in]      Address       The starting physical address of the read.
+  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
+                                of bytes actually read.
+  @param[out]     Buffer        The destination data buffer for the read.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashRead (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+     OUT UINT8     *Buffer
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+  UINTN         Offset = 0;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+
+
+  //if (Address >= (UINTN)PcdGet32 (PcdGbeRomBase) && Address < (UINTN)PcdGet32 (PcdPDRRomBase)) {
+    Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+    Status = mSpiProtocol->Execute (
+                               mSpiProtocol,
+                               1, //SPI_READ,
+                               0, //SPI_WREN,
+                               TRUE,
+                               TRUE,
+                               FALSE,
+                               Offset,
+                               BLOCK_SIZE,
+                               Buffer,
+                               EnumSpiRegionAll
+                               );
+    return Status;
+}
+
+/**
+  Write NumBytes bytes of data from Buffer to the address specified by
+  PAddresss.
+
+  @param[in]      Address         The starting physical address of the write.
+  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
+                                  the actual number of bytes written.
+  @param[in]      Buffer          The source data buffer for the write.
+
+  @retval         EFI_SUCCESS       Opertion is successful.
+  @retval         EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashWrite (
+  IN     UINTN     Address,
+  IN OUT UINT32    *NumBytes,
+  IN     UINT8     *Buffer
+  )
+{
+  EFI_STATUS                Status;
+  UINTN                     Offset;
+  UINT32                    Length;
+  UINT32                    RemainingBytes;
+
+  ASSERT ((NumBytes != NULL) && (Buffer != NULL));
+  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
+
+  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+  while (RemainingBytes > 0) {
+    if (RemainingBytes > SIZE_4KB) {
+      Length = SIZE_4KB;
+    } else {
+      Length = RemainingBytes;
+    }
+    Status = mSpiProtocol->Execute (
+                             mSpiProtocol,
+                             SPI_PROG,
+                             SPI_WREN,
+                             TRUE,
+                             TRUE,
+                             TRUE,
+                             (UINT32) Offset,
+                             Length,
+                             Buffer,
+                             EnumSpiRegionAll
+                             );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    RemainingBytes -= Length;
+    Offset += Length;
+    Buffer += Length;
+  }
+
+  //
+  // Actual number of bytes written
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+
+EFI_STATUS
+InternalReadBlock (
+  IN  EFI_PHYSICAL_ADDRESS  BaseAddress,
+  OUT VOID                  *ReadBuffer
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        BlockSize;
+
+  BlockSize = BLOCK_SIZE;
+
+  Status = SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer);
+
+  return Status;
+}
+
+/**
+  Erase the block starting at Address.
+
+  @param[in]  Address         The starting physical address of the block to be erased.
+                              This library assume that caller garantee that the PAddress
+                              is at the starting address of this block.
+  @param[in]  NumBytes        On input, the number of bytes of the logical block to be erased.
+                              On output, the actual number of bytes erased.
+
+  @retval     EFI_SUCCESS.      Opertion is successful.
+  @retval     EFI_DEVICE_ERROR  If there is any device errors.
+
+**/
+EFI_STATUS
+EFIAPI
+SpiFlashBlockErase (
+  IN UINTN    Address,
+  IN UINTN    *NumBytes
+  )
+{
+  EFI_STATUS          Status;
+  UINTN               Offset;
+  UINTN               RemainingBytes;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
+
+  Offset    = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+  ASSERT ((*NumBytes % SIZE_4KB) == 0);
+  ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
+
+  Status = EFI_SUCCESS;
+  RemainingBytes = *NumBytes;
+
+  //
+  // To adjust the Offset with Bios/Gbe
+  //
+//  if (Address >= (UINTN)PcdGet32 (PcdFlashChipBase)) {
+//    Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
+
+    while (RemainingBytes > 0) {
+      Status = mSpiProtocol->Execute (
+                               mSpiProtocol,
+                               SPI_SERASE,
+                               SPI_WREN,
+                               FALSE,
+                               TRUE,
+                               FALSE,
+                               (UINT32) Offset,
+                               0,
+                               NULL,
+                               EnumSpiRegionAll
+                               );
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+      RemainingBytes -= SIZE_4KB;
+      Offset         += SIZE_4KB;
+    }
+//  }
+
+  //
+  // Actual number of bytes erased
+  //
+  *NumBytes -= RemainingBytes;
+
+  return Status;
+}
+
+/**
+
+Routine Description:
+
+  Erase the whole block.
+
+Arguments:
+
+  BaseAddress  - Base address of the block to be erased.
+
+Returns:
+
+  EFI_SUCCESS - The command completed successfully.
+  Other       - Device error or wirte-locked, operation failed.
+
+**/
+EFI_STATUS
+InternalEraseBlock (
+  IN  EFI_PHYSICAL_ADDRESS BaseAddress
+  )
+{
+  EFI_STATUS                              Status;
+  UINTN                                   NumBytes;
+
+  NumBytes = BLOCK_SIZE;
+
+  Status = SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes);
+
+  return Status;
+}
+
+EFI_STATUS
+InternalCompareBlock (
+  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN  UINT8                       *Buffer
+  )
+{
+  EFI_STATUS                              Status;
+  VOID                                    *CompareBuffer;
+  UINT32                                  NumBytes;
+  INTN                                    CompareResult;
+
+  NumBytes = BLOCK_SIZE;
+  CompareBuffer = AllocatePool (NumBytes);
+  if (CompareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Done;
+  }
+
+  Status = SpiFlashRead ((UINTN) BaseAddress, &NumBytes, CompareBuffer);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+  CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE);
+  if (CompareResult != 0) {
+    Status = EFI_VOLUME_CORRUPTED;
+  }
+
+Done:
+  if (CompareBuffer != NULL) {
+    FreePool (CompareBuffer);
+  }
+
+  return Status;
+}
+
+/**
+
+Routine Description:
+
+  Write a block of data.
+
+Arguments:
+
+  BaseAddress  - Base address of the block.
+  Buffer       - Data buffer.
+  BufferSize   - Size of the buffer.
+
+Returns:
+
+  EFI_SUCCESS           - The command completed successfully.
+  EFI_INVALID_PARAMETER - Invalid parameter, can not proceed.
+  Other                 - Device error or wirte-locked, operation failed.
+
+**/
+EFI_STATUS
+InternalWriteBlock (
+  IN  EFI_PHYSICAL_ADDRESS        BaseAddress,
+  IN  UINT8                       *Buffer,
+  IN  UINT32                      BufferSize
+  )
+{
+  EFI_STATUS                              Status;
+
+  Status = SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG((DEBUG_ERROR, "\nFlash write error."));
+    return Status;
+  }
+
+  WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress, BLOCK_SIZE);
+
+  Status = InternalCompareBlock (BaseAddress, Buffer);
+  if (EFI_ERROR (Status)) {
+    DEBUG((DEBUG_ERROR, "\nError when writing to BaseAddress %x with different at offset %x.", BaseAddress, Status));
+  } else {
+    DEBUG((DEBUG_INFO, "\nVerified data written to Block at %x is correct.", BaseAddress));
+  }
+
+  return Status;
+
+}
+
+/**
+  Perform flash write operation with progress indicator.  The start and end
+  completion percentage values are passed into this function.  If the requested
+  flash write operation is broken up, then completion percentage between the
+  start and end values may be passed to the provided Progress function.  The
+  caller of this function is required to call the Progress function for the
+  start and end completion percentage values.  This allows the Progress,
+  StartPercentage, and EndPercentage parameters to be ignored if the requested
+  flash write operation can not be broken up
+
+  @param[in] FirmwareType      The type of firmware.
+  @param[in] FlashAddress      The address of flash device to be accessed.
+  @param[in] FlashAddressType  The type of flash device address.
+  @param[in] Buffer            The pointer to the data buffer.
+  @param[in] Length            The length of data buffer in bytes.
+  @param[in] Progress          A function used report the progress of the
+                               firmware update.  This is an optional parameter
+                               that may be NULL.
+  @param[in] StartPercentage   The start completion percentage value that may
+                               be used to report progress during the flash
+                               write operation.
+  @param[in] EndPercentage     The end completion percentage value that may
+                               be used to report progress during the flash
+                               write operation.
+
+  @retval EFI_SUCCESS           The operation returns successfully.
+  @retval EFI_WRITE_PROTECTED   The flash device is read only.
+  @retval EFI_UNSUPPORTED       The flash device access is unsupported.
+  @retval EFI_INVALID_PARAMETER The input parameter is not valid.
+**/
+EFI_STATUS
+EFIAPI
+PerformFlashWriteWithProgress (
+  IN PLATFORM_FIRMWARE_TYPE                         FirmwareType,
+  IN EFI_PHYSICAL_ADDRESS                           FlashAddress,
+  IN FLASH_ADDRESS_TYPE                             FlashAddressType,
+  IN VOID                                           *Buffer,
+  IN UINTN                                          Length,
+  IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS  Progress,        OPTIONAL
+  IN UINTN                                          StartPercentage,
+  IN UINTN                                          EndPercentage
+  )
+{
+  EFI_STATUS            Status = EFI_SUCCESS;
+  UINTN               Index;
+  EFI_PHYSICAL_ADDRESS  Address;
+  UINTN                 CountOfBlocks;
+  EFI_TPL               OldTpl;
+  BOOLEAN               FlashError;
+  UINT8                 *Buf;
+  UINTN                 LpcBaseAddress;
+  UINT8                 Data8Or;
+  UINT8                 Data8And;
+  UINT8                 BiosCntl;
+
+  Index             = 0;
+  Address           = 0;
+  CountOfBlocks     = 0;
+  FlashError        = FALSE;
+  Buf               = Buffer;
+
+  DEBUG((DEBUG_INFO | DEBUG_ERROR, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));
+  if (FlashAddressType == FlashAddressTypeRelativeAddress) {
+    FlashAddress = FlashAddress + mInternalFdAddress;
+  }
+
+  CountOfBlocks = (UINTN) (Length / BLOCK_SIZE);
+  Address = FlashAddress;
+
+  LpcBaseAddress = MmPciAddress (0,
+                    DEFAULT_PCI_BUS_NUMBER_PCH,
+                    PCI_DEVICE_NUMBER_PCH_LPC,
+                    PCI_FUNCTION_NUMBER_PCH_LPC,
+                    0
+                    );
+  BiosCntl = MmioRead8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL);
+  if ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) {
+    ///
+    /// Clear SMM_BWP bit (D31:F0:RegDCh[5])
+    ///
+    Data8And  = (UINT8) ~B_PCH_LPC_BIOS_CNTL_SMM_BWP;
+    Data8Or   = 0x00;
+
+    MmioAndThenOr8 (
+      LpcBaseAddress + R_PCH_LPC_BIOS_CNTL,
+      Data8And,
+      Data8Or
+      );
+    DEBUG((DEBUG_INFO, "PerformFlashWrite Clear SMM_BWP bit\n"));
+  }
+
+    //
+    // Raise TPL to TPL_NOTIFY to block any event handler,
+    // while still allowing RaiseTPL(TPL_NOTIFY) within
+    // output driver during Print()
+    //
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+    for (Index = 0; Index < CountOfBlocks; Index++) {
+      if (Progress != NULL) {
+        Progress (StartPercentage + ((Index * (EndPercentage - StartPercentage)) / CountOfBlocks));
+      }
+      //
+      // Handle block based on address and contents.
+      //
+      if (!EFI_ERROR (InternalCompareBlock (Address, Buf))) {
+        DEBUG((DEBUG_INFO, "Skipping block at 0x%lx (already programmed)\n", Address));
+      } else {
+        //
+        // Make updating process uninterruptable,
+        // so that the flash memory area is not accessed by other entities
+        // which may interfere with the updating process
+        //
+        Status  = InternalEraseBlock (Address);
+        if (EFI_ERROR(Status)) {
+          gBS->RestoreTPL (OldTpl);
+          FlashError = TRUE;
+          goto Done;
+        }
+        Status = InternalWriteBlock (
+                  Address,
+                  Buf,
+                  (UINT32)(Length > BLOCK_SIZE ? BLOCK_SIZE : Length)
+                  );
+        if (EFI_ERROR(Status)) {
+          gBS->RestoreTPL (OldTpl);
+          FlashError = TRUE;
+          goto Done;
+        }
+      }
+
+      //
+      // Move to next block to update.
+      //
+      Address += BLOCK_SIZE;
+      Buf += BLOCK_SIZE;
+      if (Length > BLOCK_SIZE) {
+        Length -= BLOCK_SIZE;
+      } else {
+        Length = 0;
+      }
+    }
+    gBS->RestoreTPL (OldTpl);
+
+Done:
+  if ((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) {
+    //
+    // Restore original control setting
+    //
+    MmioWrite8 (LpcBaseAddress + R_PCH_LPC_BIOS_CNTL, BiosCntl);
+  }
+
+  if (Progress != NULL) {
+    Progress (EndPercentage);
+  }
+
+  if (FlashError) {
+    return EFI_WRITE_PROTECTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Perform flash write operation.
+
+  @param[in] FirmwareType      The type of firmware.
+  @param[in] FlashAddress      The address of flash device to be accessed.
+  @param[in] FlashAddressType  The type of flash device address.
+  @param[in] Buffer            The pointer to the data buffer.
+  @param[in] Length            The length of data buffer in bytes.
+
+  @retval EFI_SUCCESS           The operation returns successfully.
+  @retval EFI_WRITE_PROTECTED   The flash device is read only.
+  @retval EFI_UNSUPPORTED       The flash device access is unsupported.
+  @retval EFI_INVALID_PARAMETER The input parameter is not valid.
+**/
+EFI_STATUS
+EFIAPI
+PerformFlashWrite (
+  IN PLATFORM_FIRMWARE_TYPE       FirmwareType,
+  IN EFI_PHYSICAL_ADDRESS         FlashAddress,
+  IN FLASH_ADDRESS_TYPE           FlashAddressType,
+  IN VOID                         *Buffer,
+  IN UINTN                        Length
+  )
+{
+  return PerformFlashWriteWithProgress (
+           FirmwareType,
+           FlashAddress,
+           FlashAddressType,
+           Buffer,
+           Length,
+           NULL,
+           0,
+           0
+           );
+}
+
+/**
+  Perform microcode write operation.
+
+  @param[in] FlashAddress      The address of flash device to be accessed.
+  @param[in] Buffer            The pointer to the data buffer.
+  @param[in] Length            The length of data buffer in bytes.
+
+  @retval EFI_SUCCESS           The operation returns successfully.
+  @retval EFI_WRITE_PROTECTED   The flash device is read only.
+  @retval EFI_UNSUPPORTED       The flash device access is unsupported.
+  @retval EFI_INVALID_PARAMETER The input parameter is not valid.
+**/
+EFI_STATUS
+EFIAPI
+MicrocodeFlashWrite (
+  IN EFI_PHYSICAL_ADDRESS         FlashAddress,
+  IN VOID                         *Buffer,
+  IN UINTN                        Length
+  )
+{
+  EFI_PHYSICAL_ADDRESS         AlignedFlashAddress;
+  VOID                         *AlignedBuffer;
+  UINTN                        AlignedLength;
+  UINTN                        OffsetHead;
+  UINTN                        OffsetTail;
+  EFI_STATUS                   Status;
+
+  DEBUG((DEBUG_INFO, "MicrocodeFlashWrite - 0x%x - 0x%x\n", (UINTN)FlashAddress, Length));
+
+  //
+  // Need make buffer 64K aligned to support ERASE
+  //
+  // [Aligned]    FlashAddress    [Aligned]
+  // |              |                     |
+  // V              V                     V
+  // +--------------+========+------------+
+  // | OffsetHeader | Length | OffsetTail |
+  // +--------------+========+------------+
+  // ^
+  // |<-----------AlignedLength----------->
+  // |
+  // AlignedFlashAddress
+  //
+  OffsetHead = FlashAddress & (ALINGED_SIZE - 1);
+  OffsetTail = (FlashAddress + Length) & (ALINGED_SIZE - 1);
+  if (OffsetTail != 0) {
+    OffsetTail = ALINGED_SIZE - OffsetTail;
+  }
+
+  if ((OffsetHead != 0) || (OffsetTail != 0)) {
+    AlignedFlashAddress = FlashAddress - OffsetHead;
+    AlignedLength = Length + OffsetHead + OffsetTail;
+
+    AlignedBuffer = AllocatePool(AlignedLength);
+    if (AlignedBuffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    //
+    // Save original buffer
+    //
+    if (OffsetHead != 0) {
+      CopyMem((UINT8 *)AlignedBuffer, (VOID *)(UINTN)AlignedFlashAddress, OffsetHead);
+    }
+    if (OffsetTail != 0) {
+      CopyMem((UINT8 *)AlignedBuffer + OffsetHead + Length, (VOID *)(UINTN)(AlignedFlashAddress + OffsetHead + Length), OffsetTail);
+    }
+    //
+    // Override new buffer
+    //
+    CopyMem((UINT8 *)AlignedBuffer + OffsetHead, Buffer, Length);
+  } else {
+    AlignedFlashAddress = FlashAddress;
+    AlignedBuffer = Buffer;
+    AlignedLength = Length;
+  }
+
+  Status = PerformFlashWrite(
+             PlatformFirmwareTypeSystemFirmware,
+             AlignedFlashAddress,
+             FlashAddressTypeAbsoluteAddress,
+             AlignedBuffer,
+             AlignedLength
+             );
+  if ((OffsetHead != 0) || (OffsetTail != 0)) {
+    FreePool (AlignedBuffer);
+  }
+  return Status;
+}
+
+/**
+  Platform Flash Access Lib Constructor.
+**/
+EFI_STATUS
+EFIAPI
+PerformFlashAccessLibConstructor (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  mInternalFdAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32(PcdFlashAreaBaseAddress);
+  DEBUG((DEBUG_INFO, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress));
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSpiProtocolGuid,
+                  NULL,
+                  (VOID **) &mSpiProtocol
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  return EFI_SUCCESS;
+}

+ 54 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf

@@ -0,0 +1,54 @@
+## @file
+#  Platform Flash Access library.
+#
+#  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformFlashAccessLib
+  FILE_GUID                      = 31CF9CEC-DA4E-4505-AA20-33364A291A95
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformFlashAccessLib
+  LIBRARY_CLASS                  = MicrocodeFlashAccessLib
+  CONSTRUCTOR                    = PerformFlashAccessLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  PlatformFlashAccessLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  IoLib
+  PcdLib
+  DebugLib
+  MemoryAllocationLib
+  CacheMaintenanceLib
+
+[Guids]
+  gEdkiiSystemFmpCapsuleConfigFileGuid          ## SOMETIMES_CONSUMES ## GUID
+
+[Protocols]
+  gEfiSpiProtocolGuid                          ## CONSUMES
+
+[Pcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress  ## SOMETIMES_CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipBase         ## SOMETIMES_CONSUMES
+  gPlatformModuleTokenSpaceGuid.PcdFlashChipSize         ## SOMETIMES_CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress      ## SOMETIMES_CONSUMES
+

+ 83 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.aslc

@@ -0,0 +1,83 @@
+/** @file
+  System Firmware descriptor.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Protocol/FirmwareManagement.h>
+#include <Guid/EdkiiSystemFmpCapsule.h>
+
+#define PACKAGE_VERSION                     0xFFFFFFFF
+#define PACKAGE_VERSION_STRING              L"Unknown"
+
+#define CURRENT_FIRMWARE_VERSION            0x00000002
+#define CURRENT_FIRMWARE_VERSION_STRING     L"0x00000002"
+#define LOWEST_SUPPORTED_FIRMWARE_VERSION   0x00000001
+
+#define IMAGE_ID                            SIGNATURE_64('V', 'L', 'V', '2', '_', '_', 'F', 'd')
+#define IMAGE_ID_STRING                     L"Vlv2Fd"
+
+// PcdSystemFmpCapsuleImageTypeIdGuid
+#define IMAGE_TYPE_ID_GUID                  { 0x4096267b, 0xda0a, 0x42eb, { 0xb5, 0xeb, 0xfe, 0xf3, 0x1d, 0x20, 0x7c, 0xb4 } }
+
+typedef struct {
+  EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR  Descriptor;
+  // real string data
+  CHAR16                                  ImageIdNameStr[sizeof(IMAGE_ID_STRING)/sizeof(CHAR16)];
+  CHAR16                                  VersionNameStr[sizeof(CURRENT_FIRMWARE_VERSION_STRING)/sizeof(CHAR16)];
+  CHAR16                                  PackageVersionNameStr[sizeof(PACKAGE_VERSION_STRING)/sizeof(CHAR16)];
+} IMAGE_DESCRIPTOR;
+
+IMAGE_DESCRIPTOR mImageDescriptor =
+{
+  {
+    EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE,
+    sizeof(EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR),
+    sizeof(IMAGE_DESCRIPTOR),
+    PACKAGE_VERSION,                                       // PackageVersion
+    OFFSET_OF (IMAGE_DESCRIPTOR, PackageVersionNameStr),   // PackageVersionName
+    1,                                                     // ImageIndex;
+    {0x0},                                                 // Reserved
+    IMAGE_TYPE_ID_GUID,                                    // ImageTypeId;
+    IMAGE_ID,                                              // ImageId;
+    OFFSET_OF (IMAGE_DESCRIPTOR, ImageIdNameStr),          // ImageIdName;
+    CURRENT_FIRMWARE_VERSION,                              // Version;
+    OFFSET_OF (IMAGE_DESCRIPTOR, VersionNameStr),          // VersionName;
+    {0x0},                                                 // Reserved2
+    FixedPcdGet32(PcdFlashAreaSize),                       // Size;
+    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+      IMAGE_ATTRIBUTE_RESET_REQUIRED |
+      IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
+      IMAGE_ATTRIBUTE_IN_USE,                              // AttributesSupported;
+    IMAGE_ATTRIBUTE_IMAGE_UPDATABLE |
+      IMAGE_ATTRIBUTE_RESET_REQUIRED |
+      IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED |
+      IMAGE_ATTRIBUTE_IN_USE,                              // AttributesSetting;
+    0x0,                                                   // Compatibilities;
+    LOWEST_SUPPORTED_FIRMWARE_VERSION,                     // LowestSupportedImageVersion;
+    0x00000000,                                            // LastAttemptVersion;
+    0,                                                     // LastAttemptStatus;
+    {0x0},                                                 // Reserved3
+    0,                                                     // HardwareInstance;
+  },
+  // real string data
+  {IMAGE_ID_STRING},
+  {CURRENT_FIRMWARE_VERSION_STRING},
+  {PACKAGE_VERSION_STRING},
+};
+
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from
+  // removing the data structure from the executable
+  //
+  return (VOID*)&mImageDescriptor;
+}

+ 40 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptor.inf

@@ -0,0 +1,40 @@
+## @file
+#  System Firmware descriptor.
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SystemFirmwareDescriptor
+  FILE_GUID                      = 90B2B846-CA6D-4D6E-A8D3-C140A8E110AC
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SystemFirmwareDescriptorPeimEntry
+
+[Sources]
+  SystemFirmwareDescriptorPei.c
+  SystemFirmwareDescriptor.aslc
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SignedCapsulePkg/SignedCapsulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  PeiServicesLib
+  DebugLib
+  PeimEntryPoint
+
+[FixedPcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize
+
+[Pcd]
+  gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor
+
+[Depex]
+  TRUE

+ 60 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareDescriptor/SystemFirmwareDescriptorPei.c

@@ -0,0 +1,60 @@
+/** @file
+  System Firmware descriptor producer.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/FirmwareManagement.h>
+#include <Guid/EdkiiSystemFmpCapsule.h>
+
+/**
+  Entrypoint for SystemFirmwareDescriptor PEIM.
+
+  @param[in]  FileHandle  Handle of the file being invoked.
+  @param[in]  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS            PPI successfully installed.
+**/
+EFI_STATUS
+EFIAPI
+SystemFirmwareDescriptorPeimEntry (
+  IN EFI_PEI_FILE_HANDLE     FileHandle,
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  EFI_STATUS                              Status;
+  EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR  *Descriptor;
+  UINTN                                   Size;
+  UINTN                                   Index;
+  UINT32                                  AuthenticationStatus;
+
+  //
+  // Search RAW section.
+  //
+  Index = 0;
+  while (TRUE) {
+    Status = PeiServicesFfsFindSectionData3(EFI_SECTION_RAW, Index, FileHandle, (VOID **)&Descriptor, &AuthenticationStatus);
+    if (EFI_ERROR(Status)) {
+      // Should not happen, must something wrong in FDF.
+      ASSERT(FALSE);
+      return EFI_NOT_FOUND;
+    }
+    if (Descriptor->Signature == EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR_SIGNATURE) {
+      break;
+    }
+    Index++;
+  }
+
+  DEBUG((DEBUG_INFO, "EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR size - 0x%x\n", Descriptor->Length));
+
+  Size = Descriptor->Length;
+  PcdSetPtrS (PcdEdkiiSystemFirmwareImageDescriptor, &Size, Descriptor);
+
+  return EFI_SUCCESS;
+}

+ 66 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfig.ini

@@ -0,0 +1,66 @@
+## @file
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Head]
+NumOfUpdate = 6
+NumOfRecovery = 1
+Update0 = Vlv2FvMicrocode
+Update1 = Vlv2FvBinary
+Update2 = Vlv2FvMain
+Update3 = Vlv2FvRecovery2
+Update4 = Vlv2FvRecovery
+Update5 = Vlv2FvNvRam
+Recovery0 = Vlv2FvMain
+
+[Vlv2FvMicrocode]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00000000    # Base address offset on flash
+Length      = 0x00040000    # Length
+ImageOffset = 0x00000000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvNvRam]
+FirmwareType = 1            # NvRam
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00040000    # Base address offset on flash
+Length      = 0x00080000    # Length
+ImageOffset = 0x00040000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvBinary]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x000C0000    # Base address offset on flash
+Length      = 0x00050000    # Length
+ImageOffset = 0x000C0000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvMain]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00110000    # Base address offset on flash
+Length      = 0x00210000    # Length
+ImageOffset = 0x00110000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvRecovery2]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00320000    # Base address offset on flash
+Length      = 0x00070000    # Length
+ImageOffset = 0x00320000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvRecovery]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00390000    # Base address offset on flash
+Length      = 0x00070000    # Length
+ImageOffset = 0x00390000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+

+ 66 - 0
Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/SystemFirmwareUpdateConfig/SystemFirmwareUpdateConfigGcc.ini

@@ -0,0 +1,66 @@
+## @file
+#
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Head]
+NumOfUpdate = 6
+NumOfRecovery = 1
+Update0 = Vlv2FvMicrocode
+Update1 = Vlv2FvBinary
+Update2 = Vlv2FvMain
+Update3 = Vlv2FvRecovery2
+Update4 = Vlv2FvRecovery
+Update5 = Vlv2FvNvRam
+Recovery0 = Vlv2FvMain
+
+[Vlv2FvMicrocode]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00000000    # Base address offset on flash
+Length      = 0x00040000    # Length
+ImageOffset = 0x00000000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvNvRam]
+FirmwareType = 1            # NvRam
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00040000    # Base address offset on flash
+Length      = 0x00080000    # Length
+ImageOffset = 0x00040000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvBinary]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x000C0000    # Base address offset on flash
+Length      = 0x00050000    # Length
+ImageOffset = 0x000C0000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvMain]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00110000    # Base address offset on flash
+Length      = 0x00215000    # Length
+ImageOffset = 0x00110000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvRecovery2]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00325000    # Base address offset on flash
+Length      = 0x0006B000    # Length
+ImageOffset = 0x00325000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+
+[Vlv2FvRecovery]
+FirmwareType = 0            # SystemFirmware
+AddressType = 0             # 0 - relative address, 1 - absolute address.
+BaseAddress = 0x00390000    # Base address offset on flash
+Length      = 0x00070000    # Length
+ImageOffset = 0x00390000    # Image offset of this SystemFirmware image
+FileGuid    = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215  # PcdEdkiiSystemFirmwareFileGuid
+

+ 55 - 0
Platform/Intel/Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc

@@ -0,0 +1,55 @@
+#/** @file
+# FmpDxe driver for Blue Sample device firmware update.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+  FmpDevicePkg/FmpDxe/FmpDxe.inf {
+    <Defines>
+      #
+      # ESRT and FMP GUID for sample device capsule update
+      #
+      FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE)
+    <PcdsFixedAtBuild>
+      #
+      # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device"
+
+      #
+      # ESRT and FMP Lowest Support Version for this capsule update module
+      # 000.000.000.000
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000
+
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2
+
+      #
+      # Capsule Update Progress Bar Color.  Set to Blue (RGB) (0, 0, 255)
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x000000FF
+
+      #
+      # Certificates used to authenticate capsule update image
+      #
+      !include Vlv2TbltDevicePkg/FmpCertificate.dsc
+
+    <LibraryClasses>
+      #
+      # Generic libraries that are used "as is" by all FMP modules
+      #
+      FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+      #
+      # Platform specific capsule policy library
+      #
+      CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+      #
+      # Device specific library that processes a capsule and updates the FW storage device
+      #
+      FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
+  }

+ 22 - 0
Platform/Intel/Vlv2TbltDevicePkg/FmpCertificate.dsc

@@ -0,0 +1,22 @@
+#/** @file
+# FMP Certificates shared by multiple FmpDxe drivers for firmware update.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+!if $(CAPSULE_PKCS7_CERT) == SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION
+  !include Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT_SAMPLE_PRODUCTION.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+!endif
+!if $(CAPSULE_PKCS7_CERT) == SAMPLE_DEVELOPMENT
+  !include Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/SAMPLE_DEVELOPMENT.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+!endif
+!if $(CAPSULE_PKCS7_CERT) == EDKII_TEST
+  !include BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+!endif
+!if $(CAPSULE_PKCS7_CERT) == NEW_ROOT
+  !include Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/NewRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+!endif

+ 55 - 0
Platform/Intel/Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc

@@ -0,0 +1,55 @@
+#/** @file
+# FmpDxe driver for Green Sample device firmware update.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+  FmpDevicePkg/FmpDxe/FmpDxe.inf {
+    <Defines>
+      #
+      # ESRT and FMP GUID for sample device capsule update
+      #
+      FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE)
+    <PcdsFixedAtBuild>
+      #
+      # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device"
+
+      #
+      # ESRT and FMP Lowest Support Version for this capsule update module
+      # 000.000.000.000
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000
+
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2
+
+      #
+      # Capsule Update Progress Bar Color.  Set to Green (RGB) (0, 255, 0)
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x0000FF00
+
+      #
+      # Certificates used to authenticate capsule update image
+      #
+      !include Vlv2TbltDevicePkg/FmpCertificate.dsc
+
+    <LibraryClasses>
+      #
+      # Generic libraries that are used "as is" by all FMP modules
+      #
+      FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+      #
+      # Platform specific capsule policy library
+      #
+      CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+      #
+      # Device specific library that processes a capsule and updates the FW storage device
+      #
+      FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
+  }

+ 59 - 0
Platform/Intel/Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc

@@ -0,0 +1,59 @@
+#/** @file
+# FmpDxe driver for Minnow Max system firmware update.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+  FmpDevicePkg/FmpDxe/FmpDxe.inf {
+    <Defines>
+      #
+      # ESRT and FMP GUID for system firmware capsule update
+      #
+      FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM)
+    <PcdsFixedAtBuild>
+      #
+      # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Minnow Max System Firmware Device"
+
+      #
+      # ESRT and FMP Lowest Support Version for this capsule update module
+      # 000.000.000.000
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000
+
+      gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupportedVersion|0x00000000
+      gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion|0x00000000
+      gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString|"000.000.000.000"
+
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|4
+
+      #
+      # Capsule Update Progress Bar Color.  Set to Purple (RGB) (255, 0, 255)
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x00FF00FF
+
+      #
+      # Certificates used to authenticate capsule update image
+      #
+      !include Vlv2TbltDevicePkg/FmpCertificate.dsc
+
+    <LibraryClasses>
+      #
+      # Generic libraries that are used "as is" by all FMP modules
+      #
+      FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+      #
+      # Platform specific capsule policy library
+      #
+      CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+      #
+      # Device specific library that processes a capsule and updates the FW storage device
+      #
+      FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf
+  }

+ 55 - 0
Platform/Intel/Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc

@@ -0,0 +1,55 @@
+#/** @file
+# FmpDxe driver for Red Sample device firmware update.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+  FmpDevicePkg/FmpDxe/FmpDxe.inf {
+    <Defines>
+      #
+      # ESRT and FMP GUID for sample device capsule update
+      #
+      FILE_GUID = $(FMP_RED_SAMPLE_DEVICE)
+    <PcdsFixedAtBuild>
+      #
+      # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device"
+
+      #
+      # ESRT and FMP Lowest Support Version for this capsule update module
+      # 000.000.000.000
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000
+
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2
+
+      #
+      # Capsule Update Progress Bar Color.  Set to Blue (RGB) (255, 0, 0)
+      #
+      gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x00FF0000
+
+      #
+      # Certificates used to authenticate capsule update image
+      #
+      !include Vlv2TbltDevicePkg/FmpCertificate.dsc
+
+    <LibraryClasses>
+      #
+      # Generic libraries that are used "as is" by all FMP modules
+      #
+      FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+      FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+      #
+      # Platform specific capsule policy library
+      #
+      CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+      #
+      # Device specific library that processes a capsule and updates the FW storage device
+      #
+      FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf
+  }

BIN
Platform/Intel/Vlv2TbltDevicePkg/FspAzaliaConfigData/AzaliaConfig.bin


+ 42 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.c

@@ -0,0 +1,42 @@
+/** @file
+  This PEIM will parse the hoblist from fsp and report them into pei core.
+  This file contains the main entrypoint of the PEIM.
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiPei.h>
+#include <Ppi/MasterBootMode.h>
+
+static EFI_PEI_PPI_DESCRIPTOR       mPpiList[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiMasterBootModePpiGuid,
+    NULL
+  },
+};
+
+/**
+  This is the entrypoint of PEIM
+
+  @param  FileHandle  Handle of the file being invoked.
+  @param  PeiServices Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS if it completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+BootModePeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  (*PeiServices)->SetBootMode(PeiServices, BOOT_WITH_FULL_CONFIGURATION);
+
+  (*PeiServices)->InstallPpi (PeiServices, &mPpiList[0]);
+
+  return EFI_SUCCESS;
+}

+ 40 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/BootModePei/BootModePei.inf

@@ -0,0 +1,40 @@
+## @file
+# FSP PEI Module
+#
+# Parses the hoblist from fsp and report them into pei core. It will install
+# the memory as required.
+#
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BootModePeim
+  FILE_GUID                      = 2B1D0832-2184-4C8F-A90D-8E4AF9DE5BCD
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = BootModePeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32
+#
+
+[Sources]
+  BootModePei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+
+[Ppis]
+  gEfiPeiMasterBootModePpiGuid
+
+[Depex]
+  TRUE

+ 421 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.c

@@ -0,0 +1,421 @@
+/** @file
+  Null instance of Platform Sec Lib.
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspPlatformInfoLib.h>
+
+#include <Guid/GuidHobFsp.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/Capsule.h>
+
+#include <PlatformFspLib.h>
+#include <Guid/SmramMemoryReserve.h>
+EFI_GUID gFspReservedMemoryResourceHobTsegGuid = {0xd038747c, 0xd00c, 0x4980, {0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}};
+
+//
+// Additional pages are used by DXE memory manager.
+// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
+//
+#define PEI_ADDITIONAL_MEMORY_SIZE    (16 * EFI_PAGE_SIZE)
+
+/**
+  Get the mem size in memory type infromation table.
+
+  @param PeiServices  PEI Services table.
+
+  @return the mem size in memory type infromation table.
+**/
+UINT64
+GetMemorySizeInMemoryTypeInformation (
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  EFI_PEI_HOB_POINTERS        Hob;
+  EFI_MEMORY_TYPE_INFORMATION *MemoryData;
+  UINT8                       Index;
+  UINTN                       TempPageNum;
+
+  MemoryData = NULL;
+  (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES **)PeiServices, (VOID **) &Hob.Raw);
+  while (!END_OF_HOB_LIST (Hob)) {
+    if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
+      CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {
+      MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
+      break;
+    }
+
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  if (MemoryData == NULL) {
+    return 0;
+  }
+
+  TempPageNum = 0;
+  for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
+    //
+    // Accumulate default memory size requirements
+    //
+    TempPageNum += MemoryData[Index].NumberOfPages;
+  }
+
+  return TempPageNum * EFI_PAGE_SIZE;
+}
+
+/**
+  Get the mem size need to be reserved in PEI phase.
+
+  @param PeiServices  PEI Services table.
+
+  @return the mem size need to be reserved in PEI phase.
+**/
+UINT64
+RetrieveRequiredMemorySize (
+  IN EFI_PEI_SERVICES **PeiServices
+  )
+{
+  UINT64                      Size;
+
+  Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
+  return Size + PEI_ADDITIONAL_MEMORY_SIZE;
+}
+
+/**
+  Get the mem size need to be consumed and reserved in PEI phase.
+
+  @param PeiServices  PEI Services table.
+  @param BootMode     Current boot mode.
+
+  @return the mem size need to be consumed and reserved in PEI phase.
+**/
+UINT64
+GetPeiMemSize (
+  IN EFI_PEI_SERVICES **PeiServices,
+  IN UINT32           BootMode
+  )
+{
+  UINT64                      Size;
+  UINT64                      MinSize;
+
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    return PcdGet32 (PcdPeiRecoveryMinMemSize);
+  }
+
+  Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
+
+  if (BootMode == BOOT_ON_FLASH_UPDATE) {
+    //
+    // Maybe more size when in CapsuleUpdate phase ?
+    //
+    MinSize = PcdGet32 (PcdPeiMinMemSize);
+  } else {
+    MinSize = PcdGet32 (PcdPeiMinMemSize);
+  }
+
+  return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
+}
+
+/**
+  BIOS process FspBobList.
+
+  @param FspHobList  Pointer to the HOB data structure produced by FSP.
+
+  @return If platform process the FSP hob list successfully.
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcessForMemoryResource (
+  IN VOID                 *FspHobList
+  )
+{
+  EFI_PEI_HOB_POINTERS Hob;
+  UINT64               LowMemorySize;
+  UINT64               FspMemorySize;
+  EFI_PHYSICAL_ADDRESS FspMemoryBase;
+  UINT64               PeiMemSize;
+  EFI_PHYSICAL_ADDRESS PeiMemBase;
+  UINT64               S3PeiMemSize;
+  EFI_PHYSICAL_ADDRESS S3PeiMemBase;
+  BOOLEAN              FoundFspMemHob;
+  EFI_STATUS           Status;
+  EFI_BOOT_MODE        BootMode;
+  PEI_CAPSULE_PPI      *Capsule;
+  VOID                 *CapsuleBuffer;
+  UINTN                CapsuleBufferLength;
+  UINT64               RequiredMemSize;
+  EFI_PEI_SERVICES     **PeiServices;
+  UINT64               TsegSize;
+  EFI_PHYSICAL_ADDRESS TsegBase;
+  BOOLEAN              FoundTsegHob;
+
+  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
+
+  PeiServicesGetBootMode (&BootMode);
+
+  PeiMemBase = 0;
+  LowMemorySize = 0;
+  FspMemorySize = 0;
+  FspMemoryBase = 0;
+  FoundFspMemHob = FALSE;
+  TsegSize      = 0;
+  TsegBase      = 0;
+  FoundTsegHob   = FALSE;
+
+  //
+  // Parse the hob list from fsp
+  // Report all the resource hob except the memory between 1M and 4G
+  //
+  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
+  DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
+    DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+        (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
+      DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
+      DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
+      DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
+      DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
+    }
+
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)  // Found the low memory length below 4G
+        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
+        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
+        LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
+      Hob.Raw = GET_NEXT_HOB (Hob);
+      continue;
+    }
+
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)  // Found the low memory length below 4G
+        && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
+        && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
+        && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
+      FoundFspMemHob = TRUE;
+      FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
+      FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
+      DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
+    }
+
+    if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)  // Found the low memory length below 4G
+      && (Hob.ResourceDescriptor->PhysicalStart >= 0x100000)
+      && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= 0x100000000)
+      && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobTsegGuid))) {
+        FoundTsegHob = TRUE;
+        TsegBase = Hob.ResourceDescriptor->PhysicalStart;
+
+
+        if ((Hob.ResourceDescriptor->ResourceLength == 0  ) || (Hob.ResourceDescriptor->ResourceLength > 0x800000)){
+          Hob.ResourceDescriptor->ResourceLength = 0x800000;
+        }
+
+
+        TsegSize = Hob.ResourceDescriptor->ResourceLength;
+        DEBUG((EFI_D_ERROR, "Find Tseg mem hob, base 0x%lx, len 0x%lx\n", TsegBase, TsegSize));
+      }
+
+    //
+    // Report the resource hob
+    //
+    BuildResourceDescriptorHob (
+      Hob.ResourceDescriptor->ResourceType,
+      Hob.ResourceDescriptor->ResourceAttribute,
+      Hob.ResourceDescriptor->PhysicalStart,
+      Hob.ResourceDescriptor->ResourceLength
+      );
+
+    Hob.Raw = GET_NEXT_HOB (Hob);
+  }
+
+  if (!FoundFspMemHob) {
+    DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
+    //ASSERT(FALSE);
+  }
+
+  DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
+  DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
+  DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
+
+  if (BootMode == BOOT_ON_S3_RESUME) {
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      (
+         EFI_RESOURCE_ATTRIBUTE_PRESENT |
+         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+         // EFI_RESOURCE_ATTRIBUTE_TESTED |
+         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+      ),
+      BASE_1MB,
+      LowMemorySize
+      );
+
+    Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);
+    ASSERT_EFI_ERROR (Status);
+    DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
+
+    //
+    // Make sure Stack and PeiMemory are not overlap - JYAO1
+    //
+
+    Status = PeiServicesInstallPeiMemory (
+               S3PeiMemBase,
+               S3PeiMemSize
+               );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
+    DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
+
+    //
+    // Capsule mode
+    //
+    Capsule = NULL;
+    CapsuleBuffer = NULL;
+    CapsuleBufferLength = 0;
+    if (BootMode == BOOT_ON_FLASH_UPDATE) {
+      Status = PeiServicesLocatePpi (
+                 &gPeiCapsulePpiGuid,
+                 0,
+                 NULL,
+                 (VOID **) &Capsule
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      if (Status == EFI_SUCCESS) {
+        //
+        // Make sure Stack and CapsuleBuffer are not overlap - JYAO1
+        //
+        CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
+        CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
+        //
+        // Call the Capsule PPI Coalesce function to coalesce the capsule data.
+        //
+        Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
+      }
+    }
+
+    RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
+    DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
+
+    //
+    // Report the main memory
+    //
+    BuildResourceDescriptorHob (
+      EFI_RESOURCE_SYSTEM_MEMORY,
+      (
+         EFI_RESOURCE_ATTRIBUTE_PRESENT |
+         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+         EFI_RESOURCE_ATTRIBUTE_TESTED |
+         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
+      ),
+      BASE_1MB,
+      LowMemorySize
+      );
+
+    //
+    // Make sure Stack and CapsuleBuffer are not overlap - JYAO1
+    //
+
+    //
+    // Install efi memory
+    //
+    PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
+    Status = PeiServicesInstallPeiMemory (
+               PeiMemBase,
+               PeiMemSize - RequiredMemSize
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    if (Capsule != NULL) {
+      Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
+    }
+  }
+
+  //
+  // Report GUIDed HOB for reserving SMRAM regions
+  //
+  if (FoundTsegHob) {
+    EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *SmramHobDescriptorBlock;
+
+    SmramHobDescriptorBlock = BuildGuidHob (
+             &gEfiSmmPeiSmramMemoryReserveGuid,
+             sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK)
+             );
+    ASSERT (SmramHobDescriptorBlock != NULL);
+
+    SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1;
+
+    SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = TsegBase;
+    SmramHobDescriptorBlock->Descriptor[0].CpuStart      = TsegBase;
+    SmramHobDescriptorBlock->Descriptor[0].PhysicalSize  = TsegSize;
+    SmramHobDescriptorBlock->Descriptor[0].RegionState   = EFI_SMRAM_CLOSED;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  BIOS process FspBobList for other data (not Memory Resource Descriptor).
+
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.
+
+  @return If platform process the FSP hob list successfully.
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcessForOtherData (
+  IN VOID                 *FspHobList
+  )
+{
+  EFI_PEI_SERVICES     **PeiServices;
+
+  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
+
+  //
+  // Other hob for platform
+  //
+  PlatformHobCreateFromFsp ((CONST EFI_PEI_SERVICES **) PeiServices,  FspHobList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  BIOS process FspBobList.
+
+  @param[in] FspHobList  Pointer to the HOB data structure produced by FSP.
+
+  @return If platform process the FSP hob list successfully.
+**/
+EFI_STATUS
+EFIAPI
+FspHobProcess (
+  IN VOID                 *FspHobList
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = FspHobProcessForMemoryResource (FspHobList);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = FspHobProcessForOtherData (FspHobList);
+
+  return Status;
+}

+ 74 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/PeiFspHobProcessLibVlv2/FspHobProcessLibVlv2.inf

@@ -0,0 +1,74 @@
+## @file
+#
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PeiFspHobProcessLibVlv2
+  FILE_GUID                      = C7B7070B-E5A8-4b86-9110-BDCA1095F496
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FspHobProcessLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  FspHobProcessLibVlv2.c
+
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  IntelFspPkg/IntelFspPkg.dec
+  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  HobLib
+  DebugLib
+  FspPlatformInfoLib
+  PeiServicesLib
+  PeiServicesTablePointerLib
+  PlatformFspLib
+
+[Pcd]
+  gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize
+  gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize
+
+[Guids]
+  gFspReservedMemoryResourceHobGuid
+  gEfiMemoryTypeInformationGuid
+  gEfiSmmPeiSmramMemoryReserveGuid
+
+[Ppis]
+  gPeiCapsulePpiGuid

+ 144 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.c

@@ -0,0 +1,144 @@
+/** @file
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/SecPerformance.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+#include <Library/LocalApicLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param  PeiServices               Pointer to the PEI Services Table.
+  @param  StructureSize             Pointer to the variable describing size of the input buffer.
+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS               The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL      The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  );
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS      The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  );
+
+/**
+  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+  permanent memory.
+
+  @param PeiServices            Pointer to the PEI Services Table.
+  @param TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
+                                Temporary RAM contents.
+  @param PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
+                                Temporary RAM contents.
+  @param CopySize               Amount of memory to migrate from temporary to permanent memory.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+                                TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  );
+
+EFI_SEC_PLATFORM_INFORMATION_PPI  mSecPlatformInformationPpi = {
+  SecPlatformInformation
+};
+
+PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {
+  SecGetPerformance
+};
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
+  SecTemporaryRamSupport
+};
+
+EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gEfiSecPlatformInformationPpiGuid,
+    &mSecPlatformInformationPpi
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &gPeiSecPerformancePpiGuid,
+    &mSecPerformancePpi
+  },
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiTemporaryRamSupportPpiGuid,
+    &gSecTemporaryRamSupportPpi
+  },
+};
+
+/**
+  A developer supplied function to perform platform specific operations.
+
+  It's a developer supplied function to perform any operations appropriate to a
+  given platform. It's invoked just before passing control to PEI core by SEC
+  core. Platform developer may modify the SecCoreData passed to PEI Core.
+  It returns a platform specific PPI list that platform wishes to pass to PEI core.
+  The Generic SEC core module will merge this list to join the final list passed to
+  PEI core.
+
+  @param  SecCoreData           The same parameter as passing to PEI core. It
+                                could be overridden by this function.
+
+  @return The platform specific PPI list to be passed to PEI core or
+          NULL if there is no need of such platform specific PPI list.
+
+**/
+EFI_PEI_PPI_DESCRIPTOR *
+EFIAPI
+SecPlatformMain (
+  IN OUT   EFI_SEC_PEI_HAND_OFF        *SecCoreData
+  )
+{
+  EFI_PEI_PPI_DESCRIPTOR      *PpiList;
+
+  InitializeApicTimer (0, (UINT32) -1, TRUE, 5);
+
+  PpiList = &mPeiSecPlatformPpi[0];
+
+  return PpiList;
+}

+ 82 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/FspPlatformSecLibVlv2.inf

@@ -0,0 +1,82 @@
+## @file
+#
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SecPeiFspPlatformSecLibVlv2
+  FILE_GUID                      = 6653876C-F6A1-45BB-A027-20455093BC6D
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FspPlatformSecLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources]
+  FspPlatformSecLibVlv2.c
+  SecRamInitData.c
+  SaveSecContext.c
+  SecPlatformInformation.c
+  SecGetPerformance.c
+  SecTempRamSupport.c
+  PlatformInit.c
+  UartInit.c
+
+[Sources.IA32]
+  Ia32/SecEntry.asm
+  Ia32/PeiCoreEntry.asm
+  Ia32/AsmSaveSecContext.asm
+  Ia32/Stack.asm
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+#                              this module.
+#
+################################################################################
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  IntelFspWrapperPkg/IntelFspWrapperPkg.dec
+
+[LibraryClasses]
+  LocalApicLib
+  SerialPortLib
+
+[Ppis]
+  gEfiSecPlatformInformationPpiGuid
+  gPeiSecPerformancePpiGuid
+  gEfiTemporaryRamSupportPpiGuid
+
+[Pcd]
+  gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase
+  gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize
+
+[FixedPcd]
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress
+  gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize
+  gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress
+  gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize

+ 45 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/AsmSaveSecContext.asm

@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  SecEntry.asm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, calls two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+.686p
+.xmm
+.model flat,c
+.code
+
+;----------------------------------------------------------------------------
+;  MMX Usage:
+;              MM0 = BIST State
+;              MM5 = Save time-stamp counter value high32bit
+;              MM6 = Save time-stamp counter value low32bit.
+;
+;  It should be same as SecEntry.asm and PeiCoreEntry.asm.
+;----------------------------------------------------------------------------
+
+AsmSaveBistValue   PROC PUBLIC
+  mov     eax, [esp+4]
+  movd    mm0, eax
+  ret
+AsmSaveBistValue   ENDP
+
+AsmSaveTickerValue   PROC PUBLIC
+  mov     eax, [esp+4]
+  movd    mm6, eax
+  mov     eax, [esp+8]
+  movd    mm5, eax
+  ret
+AsmSaveTickerValue   ENDP
+
+END

+ 45 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Fsp.inc

@@ -0,0 +1,45 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   Fsp.inc
+;
+; Abstract:
+;
+;   Fsp related definitions
+;
+;------------------------------------------------------------------------------
+
+
+;
+; Fv Header
+;
+FVH_SIGINATURE_OFFSET       EQU  028h
+FVH_SIGINATURE_VALID_VALUE  EQU  04856465Fh    ; valid signature:_FVH
+FVH_HEADER_LENGTH_OFFSET    EQU  030h
+FVH_EXTHEADER_OFFSET_OFFSET EQU  034h
+FVH_EXTHEADER_SIZE_OFFSET   EQU  010h
+
+;
+; Ffs Header
+;
+FSP_HEADER_GUID_DWORD1      EQU  0912740BEh
+FSP_HEADER_GUID_DWORD2      EQU  047342284h
+FSP_HEADER_GUID_DWORD3      EQU  0B08471B9h
+FSP_HEADER_GUID_DWORD4      EQU  00C3F3527h
+FFS_HEADER_SIZE_VALUE       EQU  018h
+
+;
+; Section Header
+;
+SECTION_HEADER_TYPE_OFFSET  EQU  03h
+RAW_SECTION_HEADER_SIZE_VALUE  EQU  04h
+
+;
+; Fsp Header
+;
+FSP_HEADER_IMAGEBASE_OFFSET   EQU  01Ch
+FSP_HEADER_TEMPRAMINIT_OFFSET EQU  030h

+ 135 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/PeiCoreEntry.asm

@@ -0,0 +1,135 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  SecEntry.asm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, calls two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+
+.686p
+.xmm
+.model flat, c
+.code
+
+EXTRN   SecStartup:NEAR
+EXTRN   PlatformInit:NEAR
+
+CallPeiCoreEntryPoint   PROC PUBLIC
+  ;
+  ; Obtain the hob list pointer
+  ;
+  mov     eax, [esp+4]
+  ;
+  ; Obtain the stack information
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ecx, [esp+8]
+  mov     edx, [esp+0Ch]
+
+  ;
+  ; Platform init
+  ;
+  pushad
+  push edx
+  push ecx
+  push eax
+  call PlatformInit
+  pop  eax
+  pop  eax
+  pop  eax
+  popad
+
+  ;
+  ; Set stack top pointer
+  ;
+  mov     esp, edx
+
+  ;
+  ; Push the hob list pointer
+  ;
+  push    eax
+
+  ;
+  ; Save the value
+  ;   ECX: start of range
+  ;   EDX: end of range
+  ;
+  mov     ebp, esp
+  push    ecx
+  push    edx
+
+  ;
+  ; Push processor count to stack first, then BIST status (AP then BSP)
+  ;
+  mov     eax, 1
+  cpuid
+  shr     ebx, 16
+  and     ebx, 0000000FFh
+  cmp     bl, 1
+  jae     PushProcessorCount
+
+  ;
+  ; Some processors report 0 logical processors.  Effectively 0 = 1.
+  ; So we fix up the processor count
+  ;
+  inc     ebx
+
+PushProcessorCount:
+  push    ebx
+
+  ;
+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST
+  ; for all processor threads
+  ;
+  xor     ecx, ecx
+  mov     cl, bl
+PushBist:
+  movd    eax, mm0
+  push    eax
+  loop    PushBist
+
+  ; Save Time-Stamp Counter
+  movd eax, mm5
+  push eax
+
+  movd eax, mm6
+  push eax
+
+  ;
+  ; Pass entry point of the PEI core
+  ;
+  mov     edi, 0FFFFFFE0h
+  push    DWORD PTR ds:[edi]
+
+  ;
+  ; Pass BFV into the PEI Core
+  ;
+  mov     edi, 0FFFFFFFCh
+  push    DWORD PTR ds:[edi]
+
+  ;
+  ; Pass stack size into the PEI Core
+  ;
+  mov     ecx, [ebp - 4]
+  mov     edx, [ebp - 8]
+  push    ecx       ; RamBase
+
+  sub     edx, ecx
+  push    edx       ; RamSize
+
+  ;
+  ; Pass Control into the PEI Core
+  ;
+  call SecStartup
+CallPeiCoreEntryPoint   ENDP
+
+END

+ 338 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/SecEntry.asm

@@ -0,0 +1,338 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;  SecEntry.asm
+;
+; Abstract:
+;
+;  This is the code that goes from real-mode to protected mode.
+;  It consumes the reset vector, calls two basic APIs from FSP binary.
+;
+;------------------------------------------------------------------------------
+  INCLUDE Fsp.inc
+
+.686p
+.xmm
+.model small, c
+
+EXTRN   CallPeiCoreEntryPoint:NEAR
+EXTRN   TempRamInitParams:FAR
+
+; Pcds
+EXTRN   PcdGet32 (PcdFlashFvFspBase):DWORD
+EXTRN   PcdGet32 (PcdFlashFvFspSize):DWORD
+
+_TEXT_REALMODE      SEGMENT PARA PUBLIC USE16 'CODE'
+                    ASSUME  CS:_TEXT_REALMODE, DS:_TEXT_REALMODE
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    _ModuleEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+;   Transition to non-paged flat-model protected mode from a
+;   hard-coded GDT that provides exactly two descriptors.
+;   This is a bare bones transition to protected mode only
+;   used for a while in PEI and possibly DXE.
+;
+;   After enabling protected mode, a far jump is executed to
+;   transfer to PEI using the newly loaded GDT.
+;
+; Return:       None
+;
+;  MMX Usage:
+;              MM0 = BIST State
+;              MM5 = Save time-stamp counter value high32bit
+;              MM6 = Save time-stamp counter value low32bit.
+;
+;----------------------------------------------------------------------------
+
+align 4
+_ModuleEntryPoint PROC NEAR C PUBLIC
+  fninit                                ; clear any pending Floating point exceptions
+  ;
+  ; Store the BIST value in mm0
+  ;
+  movd    mm0, eax
+
+  ;
+  ; Save time-stamp counter value
+  ; rdtsc load 64bit time-stamp counter to EDX:EAX
+  ;
+  rdtsc
+  movd    mm5, edx
+  movd    mm6, eax
+
+  ;
+  ; Load the GDT table in GdtDesc
+  ;
+  mov     esi,  OFFSET GdtDesc
+  DB      66h
+  lgdt    fword ptr cs:[si]
+
+  ;
+  ; Transition to 16 bit protected mode
+  ;
+  mov     eax, cr0                   ; Get control register 0
+  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
+  mov     cr0, eax                   ; Activate protected mode
+
+  mov     eax, cr4                   ; Get control register 4
+  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+  mov     cr4, eax
+
+  ;
+  ; Now we're in 16 bit protected mode
+  ; Set up the selectors for 32 bit protected mode entry
+  ;
+  mov     ax, SYS_DATA_SEL
+  mov     ds, ax
+  mov     es, ax
+  mov     fs, ax
+  mov     gs, ax
+  mov     ss, ax
+
+  ;
+  ; Transition to Flat 32 bit protected mode
+  ; The jump to a far pointer causes the transition to 32 bit mode
+  ;
+  mov esi, offset ProtectedModeEntryLinearAddress
+  jmp     fword ptr cs:[si]
+
+_ModuleEntryPoint   ENDP
+_TEXT_REALMODE      ENDS
+
+_TEXT_PROTECTED_MODE      SEGMENT PARA PUBLIC USE32 'CODE'
+                          ASSUME  CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE
+
+;----------------------------------------------------------------------------
+;
+; Procedure:    ProtectedModeEntryPoint
+;
+; Input:        None
+;
+; Output:       None
+;
+; Destroys:     Assume all registers
+;
+; Description:
+;
+; This function handles:
+;   Call two basic APIs from FSP binary
+;   Initializes stack with some early data (BIST, PEI entry, etc)
+;
+; Return:       None
+;
+;----------------------------------------------------------------------------
+
+align 4
+ProtectedModeEntryPoint PROC NEAR PUBLIC
+
+  ; Find the fsp info header
+  mov  edi, PcdGet32 (PcdFlashFvFspBase)
+  mov  ecx, PcdGet32 (PcdFlashFvFspSize)
+
+  mov  eax, dword ptr [edi + FVH_SIGINATURE_OFFSET]
+  cmp  eax, FVH_SIGINATURE_VALID_VALUE
+  jnz  FspHeaderNotFound
+
+  xor  eax, eax
+  mov  ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET]
+  cmp  ax, 0
+  jnz  FspFvExtHeaderExist
+
+  xor  eax, eax
+  mov  ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header
+  add  edi, eax
+  jmp  FspCheckFfsHeader
+
+FspFvExtHeaderExist:
+  add  edi, eax
+  mov  eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header
+  add  edi, eax
+
+  ; Round up to 8 byte alignment
+  mov  eax, edi
+  and  al,  07h
+  jz FspCheckFfsHeader
+
+  and  edi, 0FFFFFFF8h
+  add  edi, 08h
+
+FspCheckFfsHeader:
+  ; Check the ffs guid
+  mov  eax, dword ptr [edi]
+  cmp  eax, FSP_HEADER_GUID_DWORD1
+  jnz FspHeaderNotFound
+
+  mov  eax, dword ptr [edi + 4]
+  cmp  eax, FSP_HEADER_GUID_DWORD2
+  jnz FspHeaderNotFound
+
+  mov  eax, dword ptr [edi + 8]
+  cmp  eax, FSP_HEADER_GUID_DWORD3
+  jnz FspHeaderNotFound
+
+  mov  eax, dword ptr [edi + 0Ch]
+  cmp  eax, FSP_HEADER_GUID_DWORD4
+  jnz FspHeaderNotFound
+
+  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header
+
+  ; Check the section type as raw section
+  mov  al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET]
+  cmp  al, 019h
+  jnz FspHeaderNotFound
+
+  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
+  jmp FspHeaderFound
+
+FspHeaderNotFound:
+  jmp  $
+
+FspHeaderFound:
+  ; Get the fsp TempRamInit Api address
+  mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET]
+  add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
+
+  ; Setup the hardcode stack
+  mov esp, OFFSET TempRamInitStack
+
+  ; Call the fsp TempRamInit Api
+  jmp eax
+
+TempRamInitDone:
+  cmp eax, 0
+  jnz FspApiFailed
+
+  ;   ECX: start of range
+  ;   EDX: end of range
+  mov     esp, edx
+  push    edx
+  push    ecx
+  push    eax ; zero - no hob list yet
+  call CallPeiCoreEntryPoint
+
+FspApiFailed:
+  jmp $
+
+align 10h
+TempRamInitStack:
+    DD  OFFSET TempRamInitDone
+    DD  OFFSET TempRamInitParams
+
+ProtectedModeEntryPoint ENDP
+
+;
+; ROM-based Global-Descriptor Table for the Tiano PEI Phase
+;
+align 16
+PUBLIC  BootGdtTable
+
+;
+; GDT[0]: 0x00: Null entry, never used.
+;
+NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]
+GDT_BASE:
+BootGdtTable        DD  0
+                    DD  0
+;
+; Linear data segment descriptor
+;
+LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  092h                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Linear code segment descriptor
+;
+LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+
+;
+; System code segment descriptor
+;
+SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  09Ah                            ; present, ring 0, data, expand-up, writable
+    DB  0CFh                            ; page-granular, 32-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]
+    DW  0FFFFh                          ; limit 0xFFFFF
+    DW  0                               ; base 0
+    DB  0Eh                             ; Changed from F000 to E000.
+    DB  09Bh                            ; present, ring 0, code, expand-up, writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+;
+; Spare segment descriptor
+;
+SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]
+    DW  0FFFFh                          ; limit 0xFFFF
+    DW  0                               ; base 0
+    DB  0
+    DB  093h                            ; present, ring 0, data, expand-up, not-writable
+    DB  00h                             ; byte-granular, 16-bit
+    DB  0
+
+;
+; Spare segment descriptor
+;
+SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]
+    DW  0                               ; limit 0
+    DW  0                               ; base 0
+    DB  0
+    DB  0                               ; present, ring 0, data, expand-up, writable
+    DB  0                               ; page-granular, 32-bit
+    DB  0
+GDT_SIZE            EQU $ - BootGdtTable    ; Size, in bytes
+
+;
+; GDT Descriptor
+;
+GdtDesc:                                ; GDT descriptor
+    DW  GDT_SIZE - 1                    ; GDT limit
+    DD  OFFSET BootGdtTable             ; GDT base address
+
+
+ProtectedModeEntryLinearAddress   LABEL   FWORD
+ProtectedModeEntryLinearOffset    LABEL   DWORD
+  DD      OFFSET ProtectedModeEntryPoint  ; Offset of our 32 bit code
+  DW      LINEAR_CODE_SEL
+
+_TEXT_PROTECTED_MODE    ENDS
+END

+ 71 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.S

@@ -0,0 +1,71 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Abstract:
+#
+#   Switch the stack from temporary memory to permenent memory.
+#
+#------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# SecSwitchStack (
+#   UINT32   TemporaryMemoryBase,
+#   UINT32   PermenentMemoryBase
+#   )#
+#------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX (SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+    #
+    # Save standard registers so they can be used to change stack
+    #
+    pushl %eax
+    pushl %ebx
+    pushl %ecx
+    pushl %edx
+
+    #
+    # !!CAUTION!! this function address's is pushed into stack after
+    # migration of whole temporary memory, so need save it to permenent
+    # memory at first!
+    #
+    movl  20(%esp), %ebx         # Save the first parameter
+    movl  24(%esp), %ecx         # Save the second parameter
+
+    #
+    # Save this function's return address into permenent memory at first.
+    # Then, Fixup the esp point to permenent memory
+    #
+    movl  %esp, %eax
+    subl  %ebx, %eax
+    addl  %ecx, %eax
+    movl  0(%esp), %edx          # copy pushed register's value to permenent memory
+    movl  %edx, 0(%eax)
+    movl  4(%esp), %edx
+    movl  %edx, 4(%eax)
+    movl  8(%esp), %edx
+    movl  %edx, 8(%eax)
+    movl  12(%esp), %edx
+    movl  %edx, 12(%eax)
+    movl  16(%esp), %edx        # Update this function's return address into permenent memory
+    movl  %edx, 16(%eax)
+    movl  %eax, %esp            # From now, esp is pointed to permenent memory
+
+    #
+    # Fixup the ebp point to permenent memory
+    #
+    movl  %ebp, %eax
+    subl  %ebx, %eax
+    addl  %ecx, %eax
+    movl  %eax, %ebp            # From now, ebp is pointed to permenent memory
+
+    popl  %edx
+    popl  %ecx
+    popl  %ebx
+    popl  %eax
+    ret
+

+ 76 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/Ia32/Stack.asm

@@ -0,0 +1,76 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Abstract:
+;
+;   Switch the stack from temporary memory to permenent memory.
+;
+;------------------------------------------------------------------------------
+
+    .586p
+    .model  flat,C
+    .code
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; SecSwitchStack (
+;   UINT32   TemporaryMemoryBase,
+;   UINT32   PermenentMemoryBase
+;   );
+;------------------------------------------------------------------------------
+SecSwitchStack   PROC
+    ;
+    ; Save three register: eax, ebx, ecx
+    ;
+    push  eax
+    push  ebx
+    push  ecx
+    push  edx
+
+    ;
+    ; !!CAUTION!! this function address's is pushed into stack after
+    ; migration of whole temporary memory, so need save it to permenent
+    ; memory at first!
+    ;
+
+    mov   ebx, [esp + 20]          ; Save the first parameter
+    mov   ecx, [esp + 24]          ; Save the second parameter
+
+    ;
+    ; Save this function's return address into permenent memory at first.
+    ; Then, Fixup the esp point to permenent memory
+    ;
+    mov   eax, esp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   edx, dword ptr [esp]         ; copy pushed register's value to permenent memory
+    mov   dword ptr [eax], edx
+    mov   edx, dword ptr [esp + 4]
+    mov   dword ptr [eax + 4], edx
+    mov   edx, dword ptr [esp + 8]
+    mov   dword ptr [eax + 8], edx
+    mov   edx, dword ptr [esp + 12]
+    mov   dword ptr [eax + 12], edx
+    mov   edx, dword ptr [esp + 16]    ; Update this function's return address into permenent memory
+    mov   dword ptr [eax + 16], edx
+    mov   esp, eax                     ; From now, esp is pointed to permenent memory
+
+    ;
+    ; Fixup the ebp point to permenent memory
+    ;
+    mov   eax, ebp
+    sub   eax, ebx
+    add   eax, ecx
+    mov   ebp, eax                ; From now, ebp is pointed to permenent memory
+
+    pop   edx
+    pop   ecx
+    pop   ebx
+    pop   eax
+    ret
+SecSwitchStack   ENDP
+
+    END

+ 36 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/PlatformInit.c

@@ -0,0 +1,36 @@
+/** @file
+  This PEIM will parse the hoblist from fsp and report them into pei core.
+  This file contains the main entrypoint of the PEIM.
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+
+VOID EnableInternalUart ();
+
+VOID
+EFIAPI
+PlatformInit (
+  IN VOID                 *FspHobList,
+  IN VOID                 *StartOfRange,
+  IN VOID                 *EndOfRange
+  )
+{
+  //
+  // Platform initialization
+  // Enable Serial port here
+  //
+  EnableInternalUart ();
+  SerialPortInitialize ();
+
+  DEBUG ((DEBUG_INFO, "PlatformInit\n"));
+  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
+  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
+  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
+}

+ 108 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SaveSecContext.c

@@ -0,0 +1,108 @@
+/** @file
+  This PEIM will parse the hoblist from fsp and report them into pei core.
+  This file contains the main entrypoint of the PEIM.
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+
+#include <Ppi/TopOfTemporaryRam.h>
+#include <Ppi/SecPlatformInformation.h>
+
+/**
+  Save BIST value before call FspInit.
+
+  @param Bist   BIST value.
+**/
+VOID
+AsmSaveBistValue (
+  IN UINT32  Bist
+  );
+
+/**
+  Save Ticker value before call FspInit.
+
+  @param Ticker   Ticker value.
+**/
+VOID
+AsmSaveTickerValue (
+  IN UINT64  Ticker
+  );
+
+/**
+  Save SEC context before call FspInit.
+
+  @param PeiServices  Pointer to PEI Services Table.
+**/
+VOID
+EFIAPI
+SaveSecContext (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices
+  )
+{
+  UINT32      *Bist;
+  UINT64      *Ticker;
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return ;
+  }
+
+  DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi));
+
+  //
+  // The entries of BIST information, together with the number of them,
+  // reside in the bottom of stack, left untouched by normal stack operation.
+  // This routine copies the BIST information to the buffer pointed by
+  // PlatformInformationRecord for output.
+  //
+  // |--------------| <- TopOfTemporaryRam
+  // |Number of BSPs|
+  // |--------------|
+  // |     BIST     |
+  // |--------------|
+  // |     ....     |
+  // |--------------|
+  // |  TSC[63:32]  |
+  // |--------------|
+  // |  TSC[31:00]  |
+  // |--------------|
+  //
+
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam));
+  Count             = *(UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32));
+  DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count));
+  Size              = Count * sizeof (IA32_HANDOFF_STATUS);
+  DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size));
+
+  Bist   = (UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size);
+  DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist));
+  Ticker = (UINT64 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size - sizeof(UINT64));
+  DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker));
+
+  //
+  // Just need record BSP
+  //
+  AsmSaveBistValue (*Bist);
+  AsmSaveTickerValue (*Ticker);
+}

+ 83 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecGetPerformance.c

@@ -0,0 +1,83 @@
+/** @file
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPerformance.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys performance information out of the Security (SEC) phase into PEI.
+
+  This service is published by the SEC phase. The SEC phase handoff has an optional
+  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the
+  PEI Foundation. As such, if the platform supports collecting performance data in SEC,
+  this information is encapsulated into the data structure abstracted by this service.
+  This information is collected for the boot-strap processor (BSP) on IA-32.
+
+  @param[in]  PeiServices  The pointer to the PEI Services Table.
+  @param[in]  This         The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI.
+  @param[out] Performance  The pointer to performance data collected in SEC phase.
+
+  @retval EFI_SUCCESS  The data was successfully returned.
+
+**/
+EFI_STATUS
+EFIAPI
+SecGetPerformance (
+  IN CONST EFI_PEI_SERVICES          **PeiServices,
+  IN       PEI_SEC_PERFORMANCE_PPI   *This,
+  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
+  )
+{
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  UINT64      Ticker;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // |--------------| <- TopOfTemporaryRam
+  // |Number of BSPs|
+  // |--------------|
+  // |     BIST     |
+  // |--------------|
+  // |     ....     |
+  // |--------------|
+  // |  TSC[63:32]  |
+  // |--------------|
+  // |  TSC[31:00]  |
+  // |--------------|
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32));
+  Size              = Count * sizeof (UINT64);
+
+  Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2);
+  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
+
+  return EFI_SUCCESS;
+}

+ 77 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecPlatformInformation.c

@@ -0,0 +1,77 @@
+/** @file
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/SecPlatformInformation.h>
+#include <Ppi/TopOfTemporaryRam.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+/**
+  This interface conveys state information out of the Security (SEC) phase into PEI.
+
+  @param  PeiServices               Pointer to the PEI Services Table.
+  @param  StructureSize             Pointer to the variable describing size of the input buffer.
+  @param  PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
+
+**/
+EFI_STATUS
+EFIAPI
+SecPlatformInformation (
+  IN CONST EFI_PEI_SERVICES                     **PeiServices,
+  IN OUT   UINT64                               *StructureSize,
+     OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD  *PlatformInformationRecord
+  )
+{
+  UINT32      *Bist;
+  UINT32      Size;
+  UINT32      Count;
+  UINT32      TopOfTemporaryRam;
+  VOID        *TopOfTemporaryRamPpi;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
+
+  Status = (*PeiServices)->LocatePpi (
+                             PeiServices,
+                             &gTopOfTemporaryRamPpiGuid,
+                             0,
+                             NULL,
+                             (VOID **) &TopOfTemporaryRamPpi
+                             );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // The entries of BIST information, together with the number of them,
+  // reside in the bottom of stack, left untouched by normal stack operation.
+  // This routine copies the BIST information to the buffer pointed by
+  // PlatformInformationRecord for output.
+  //
+  TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32);
+  TopOfTemporaryRam -= sizeof(UINT32) * 2;
+  Count             = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32)));
+  Size              = Count * sizeof (IA32_HANDOFF_STATUS);
+
+  if ((*StructureSize) < (UINT64) Size) {
+    *StructureSize = Size;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *StructureSize  = Size;
+  Bist            = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size);
+
+  CopyMem (PlatformInformationRecord, Bist, Size);
+
+  return EFI_SUCCESS;
+}

+ 16 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecRamInitData.c

@@ -0,0 +1,16 @@
+/** @file
+  Calling Fsp Apis in SEC
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/PcdLib.h>
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = {
+  ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)),
+  ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)),
+  FixedPcdGet32 (PcdFlashCodeCacheAddress),
+  FixedPcdGet32 (PcdFlashCodeCacheSize)
+};

+ 149 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/SecTempRamSupport.c

@@ -0,0 +1,149 @@
+/** @file
+  C functions in SEC
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Ppi/TemporaryRamSupport.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+
+/**
+  Switch the stack in the temporary memory to the one in the permanent memory.
+
+  This function must be invoked after the memory migration immediately. The relative
+  position of the stack in the temporary and permanent memory is same.
+
+  @param TemporaryMemoryBase  Base address of the temporary memory.
+  @param PermenentMemoryBase  Base address of the permanent memory.
+**/
+VOID
+EFIAPI
+SecSwitchStack (
+  UINT32   TemporaryMemoryBase,
+  UINT32   PermenentMemoryBase
+  );
+
+/**
+  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+  permanent memory.
+
+  @param PeiServices            Pointer to the PEI Services Table.
+  @param TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
+                                Temporary RAM contents.
+  @param PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
+                                Temporary RAM contents.
+  @param CopySize               Amount of memory to migrate from temporary to permanent memory.
+
+  @retval EFI_SUCCESS           The data was successfully returned.
+  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+                                TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+  IN CONST EFI_PEI_SERVICES   **PeiServices,
+  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
+  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
+  IN UINTN                    CopySize
+  )
+{
+  IA32_DESCRIPTOR   IdtDescriptor;
+  VOID*             OldHeap;
+  VOID*             NewHeap;
+  VOID*             OldStack;
+  VOID*             NewStack;
+  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
+  BOOLEAN           OldStatus;
+  UINTN             PeiStackSize;
+
+  PeiStackSize = (UINTN)PcdGet32 (PcdPeiTemporaryRamStackSize);
+  if (PeiStackSize == 0) {
+    PeiStackSize = (CopySize >> 1);
+  }
+
+  ASSERT (PeiStackSize < CopySize);
+
+  //
+  // |-------------------|---->
+  // |      Stack        |    PeiStackSize
+  // |-------------------|---->
+  // |      Heap         |    PeiTemporayRamSize
+  // |-------------------|---->  TempRamBase
+  //
+  // |-------------------|---->
+  // |      Heap         |    PeiTemporayRamSize
+  // |-------------------|---->
+  // |      Stack        |    PeiStackSize
+  // |-------------------|---->  PermanentMemoryBase
+  //
+
+  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);
+
+  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize);
+  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+
+  //
+  // Initialize Debug Agent to support source level debug in PEI phase after memory ready.
+  // It will build HOB and fix up the pointer in IDT table.
+  //
+  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
+
+  //
+  // Migrate Heap
+  //
+  CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
+
+  //
+  // Migrate Stack
+  //
+  CopyMem (NewStack, OldStack, PeiStackSize);
+
+
+  //
+  // We need *not* fix the return address because currently,
+  // The PeiCore is executed in flash.
+  //
+
+  //
+  // Rebase IDT table in permanent memory
+  //
+  AsmReadIdtr (&IdtDescriptor);
+  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+  AsmWriteIdtr (&IdtDescriptor);
+
+
+  //
+  // Program MTRR
+  //
+
+  //
+  // SecSwitchStack function must be invoked after the memory migration
+  // immediately, also we need fixup the stack change caused by new call into
+  // permanent memory.
+  //
+  SecSwitchStack (
+    (UINT32) (UINTN) OldStack,
+    (UINT32) (UINTN) NewStack
+    );
+
+  SaveAndSetDebugTimerInterrupt (OldStatus);
+
+  return EFI_SUCCESS;
+}
+

+ 192 - 0
Platform/Intel/Vlv2TbltDevicePkg/FspSupport/Library/SecFspPlatformSecLibVlv2/UartInit.c

@@ -0,0 +1,192 @@
+/** @file
+  This PEIM will parse the hoblist from fsp and report them into pei core.
+  This file contains the main entrypoint of the PEIM.
+
+  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiPei.h>
+#include <Library/IoLib.h>
+#include <Library/SerialPortLib.h>
+
+#define PCI_IDX        0xCF8
+#define PCI_DAT        0xCFC
+
+#define PCI_LPC_BASE    (0x8000F800)
+#define PCI_LPC_REG(x)  (PCI_LPC_BASE + (x))
+
+#define PMC_BASE_ADDRESS                  0xFED03000    // PMC Memory Base Address
+#define R_PCH_LPC_PMC_BASE                        0x44  // PBASE, 32bit, 512 Bytes
+#define B_PCH_LPC_PMC_BASE_EN                     BIT1  // Enable Bit
+#define R_PCH_PMC_GEN_PMCON_1                     0x20  // General PM Configuration 1
+#define B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR           BIT14 // SUS Well Power Failure
+#define B_PCH_PMC_GEN_PMCON_PWROK_FLR             BIT16 // PWROK Failure
+
+#define R_PCH_LPC_UART_CTRL                       0x80  // UART Control
+#define B_PCH_LPC_UART_CTRL_COM1_EN               BIT0  // COM1 Enable
+
+#define ILB_BASE_ADDRESS                  0xFED08000    // ILB Memory Base Address
+#define R_PCH_ILB_IRQE                            0x88  // IRQ Enable Control
+
+#define IO_BASE_ADDRESS                   0xFED0C000    // IO Memory Base Address
+
+#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3  // UART IRQ3 Enable
+#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ4             BIT4  // UART IRQ4 Enable
+#define PCIEX_BASE_ADDRESS                        0xE0000000
+#define PCI_EXPRESS_BASE_ADDRESS                  PCIEX_BASE_ADDRESS
+#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+#define SB_RCBA                                   0xfed1c000
+
+typedef enum {
+  PchA0         = 0,
+  PchA1         = 1,
+  PchB0         = 2,
+  PchB1         = 3,
+  PchB2         = 4,
+  PchB3         = 5,
+  PchC0         = 6,
+  PchSteppingMax
+} PCH_STEPPING;
+
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+
+#define DEFAULT_PCI_BUS_NUMBER_PCH  0
+#define PCI_DEVICE_NUMBER_PCH_LPC                 31
+#define PCI_FUNCTION_NUMBER_PCH_LPC               0
+
+#define R_PCH_LPC_RID_CC                          0x08  // Revision ID & Class Code
+
+#define V_PCH_LPC_RID_0                           0x01  // A0 Stepping (17 x 17)
+#define V_PCH_LPC_RID_1                           0x02  // A0 Stepping (25 x 27)
+#define V_PCH_LPC_RID_2                           0x03  // A1 Stepping (17 x 17)
+#define V_PCH_LPC_RID_3                           0x04  // A1 Stepping (25 x 27)
+#define V_PCH_LPC_RID_4                           0x05  // B0 Stepping (17 x 17)
+#define V_PCH_LPC_RID_5                           0x06  // B0 Stepping (25 x 27)
+#define V_PCH_LPC_RID_6                           0x07  // B1 Stepping (17 x 17)
+#define V_PCH_LPC_RID_7                           0x08  // B1 Stepping (25 x 27)
+#define V_PCH_LPC_RID_8                           0x09  // B2 Stepping (17 x 17)
+#define V_PCH_LPC_RID_9                           0x0A  // B2 Stepping (25 x 27)
+#define V_PCH_LPC_RID_A                           0x0B  // B3 Stepping (17 x 17)
+#define V_PCH_LPC_RID_B                           0x0C  // B3 Stepping (25 x 27)
+#define V_PCH_LPC_RID_C                           0x0D  // C0 Stepping (17 x 17)
+#define V_PCH_LPC_RID_D                           0x0E  // C0 Stepping (25 x 27)
+
+/**
+  Return Pch stepping type
+
+  @param[in] None
+
+  @retval PCH_STEPPING            Pch stepping type
+
+**/
+PCH_STEPPING
+EFIAPI
+PchStepping (
+  VOID
+  )
+{
+  UINT8 RevId;
+
+  RevId = MmioRead8 (
+          MmPciAddress (0,
+            DEFAULT_PCI_BUS_NUMBER_PCH,
+            PCI_DEVICE_NUMBER_PCH_LPC,
+            PCI_FUNCTION_NUMBER_PCH_LPC,
+            R_PCH_LPC_RID_CC)
+          );
+
+  switch (RevId) {
+    case V_PCH_LPC_RID_0:
+    case V_PCH_LPC_RID_1:
+      return PchA0;
+      break;
+
+    case V_PCH_LPC_RID_2:
+    case V_PCH_LPC_RID_3:
+      return PchA1;
+      break;
+
+    case V_PCH_LPC_RID_4:
+    case V_PCH_LPC_RID_5:
+      return PchB0;
+      break;
+
+    case V_PCH_LPC_RID_6:
+    case V_PCH_LPC_RID_7:
+      return PchB1;
+      break;
+
+    case V_PCH_LPC_RID_8:
+    case V_PCH_LPC_RID_9:
+      return PchB2;
+      break;
+
+    case V_PCH_LPC_RID_A:
+    case V_PCH_LPC_RID_B:
+      return PchB3;
+      break;
+
+    case V_PCH_LPC_RID_C:
+    case V_PCH_LPC_RID_D:
+      return PchC0;
+      break;
+
+    default:
+      return PchSteppingMax;
+      break;
+
+  }
+}
+
+/**
+  Enable legacy decoding on ICH6
+
+ @param[in] none
+
+ @retval EFI_SUCCESS     Always returns success.
+
+**/
+VOID
+EnableInternalUart(
+  VOID
+  )
+{
+
+  //
+  // Program and enable PMC Base.
+  //
+  IoWrite32 (PCI_IDX,  PCI_LPC_REG(R_PCH_LPC_PMC_BASE));
+  IoWrite32 (PCI_DAT,  (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));
+
+  //
+  // Enable COM1 for debug message output.
+  //
+  MmioAndThenOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, (UINT32) (~(B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR + B_PCH_PMC_GEN_PMCON_PWROK_FLR)), BIT24);
+
+  //
+  // Silicon Steppings
+  //
+  if (PchStepping()>= PchB0)
+    MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4);
+  else
+    MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);
+  MmioAnd32(IO_BASE_ADDRESS + 0x0520, (UINT32)~(0x00000187));
+  MmioOr32 (IO_BASE_ADDRESS + 0x0520, (UINT32)0x81); // UART3_RXD-L
+  MmioAnd32(IO_BASE_ADDRESS + 0x0530, (UINT32)~(0x00000007));
+  MmioOr32 (IO_BASE_ADDRESS + 0x0530, (UINT32)0x1); // UART3_RXD-L
+  MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);
+
+  SerialPortInitialize ();
+  SerialPortWrite ((UINT8 *)"EnableInternalUart!\r\n", sizeof("EnableInternalUart!\r\n") - 1);
+
+  return  ;
+}

+ 68 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.c

@@ -0,0 +1,68 @@
+/** @file
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+    FvInfoPei.c
+
+Abstract:
+
+    EFI 2.0 PEIM to initialize the cache and program for unlock processor
+
+
+
+--*/
+
+#include <PiPei.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+
+EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mAddtionFVPpi = {
+  EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+  (VOID*)(UINTN)FixedPcdGet32(PcdFlashFvRecovery2Base),
+  FixedPcdGet32(PcdFlashFvRecovery2Size),
+  NULL,
+  NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR  mPpiList[] = {
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiPeiFirmwareVolumeInfoPpiGuid,
+  &mAddtionFVPpi
+};
+
+
+/**
+  Add Recovery Fv Info to the Pei Core.
+
+  @param  PeiServices  General purpose services available to every PEIM.
+
+  @retval  Status
+
+**/
+EFI_STATUS
+EFIAPI
+PeimInitializeFvInfo (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+
+//
+// GC_TODO:    FfsHeader - add argument and description to function comment
+//
+{
+  EFI_STATUS  Status;
+  Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList[0]);
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((EFI_D_INFO, "\nFvInfo Add Fv Info\n"));
+
+  return Status;
+}

+ 49 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf

@@ -0,0 +1,49 @@
+#
+#
+# Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#
+#  Module Name:
+#
+#    CpuPeim.inf
+#
+#  Abstract:
+#
+#    Component description file for CPU module
+#
+#
+#--*/
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FvInfoPei
+  FILE_GUID                      = 64AAEAE0-92DF-4980-8668-6EB5EAAF4393
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PeimInitializeFvInfo
+
+[sources.common]
+  FvInfoPei.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+
+[Pcd.common]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size
+
+[Ppis]
+  gEfiPeiFirmwareVolumeInfoPpiGuid
+
+[Depex]
+  TRUE
+

+ 170 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbInfo.c

@@ -0,0 +1,170 @@
+/**@file
+  Defines data structure that is the volume header found.
+  These data is intent to decouple FVB driver with FV header.
+
+Copyright (c) 2006  - 2015, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+
+#define FIRMWARE_BLOCK_SIZE         0x8000
+#define FVB_MEDIA_BLOCK_SIZE        (FIRMWARE_BLOCK_SIZE * 2)
+
+#define FV_RECOVERY_BASE_ADDRESS    FixedPcdGet32(PcdFlashFvRecoveryBase)
+#define RECOVERY_BIOS_BLOCK_NUM     (FixedPcdGet32(PcdFlashFvRecoverySize) / FVB_MEDIA_BLOCK_SIZE)
+
+#define FV_MAIN_BASE_ADDRESS        FixedPcdGet32(PcdFlashFvMainBase)
+#define MAIN_BIOS_BLOCK_NUM         (FixedPcdGet32(PcdFlashFvMainSize) / FVB_MEDIA_BLOCK_SIZE)
+
+#define NV_STORAGE_BASE_ADDRESS     FixedPcdGet32(PcdFlashNvStorageVariableBase)
+#define SYSTEM_NV_BLOCK_NUM         ((FixedPcdGet32(PcdFlashNvStorageVariableSize)+ FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/ FVB_MEDIA_BLOCK_SIZE)
+
+typedef struct {
+  EFI_PHYSICAL_ADDRESS        BaseAddress;
+  EFI_FIRMWARE_VOLUME_HEADER  FvbInfo;
+  EFI_FV_BLOCK_MAP_ENTRY      End[1];
+} EFI_FVB2_MEDIA_INFO;
+
+//
+// This data structure contains a template of all correct FV headers, which is used to restore
+// Fv header if it's corrupted.
+//
+EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] = {
+  //
+  // Main BIOS FVB
+  //
+  {
+    FV_MAIN_BASE_ADDRESS,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+      FVB_MEDIA_BLOCK_SIZE * MAIN_BIOS_BLOCK_NUM,
+      EFI_FVH_SIGNATURE,
+      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+      0,    //CheckSum which will be calucated dynamically.
+      0,    //ExtHeaderOffset
+      {0,}, //Reserved[1]
+      2,    //Revision
+      {
+        {
+          MAIN_BIOS_BLOCK_NUM,
+          FVB_MEDIA_BLOCK_SIZE,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+
+  //
+  // Systen NvStorage FVB
+  //
+  {
+    NV_STORAGE_BASE_ADDRESS,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_SYSTEM_NV_DATA_FV_GUID,
+      FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM,
+      EFI_FVH_SIGNATURE,
+      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+      0,    //CheckSum which will be calucated dynamically.
+      0,    //ExtHeaderOffset
+      {0,}, //Reserved[1]
+      2,    //Revision
+      {
+        {
+          SYSTEM_NV_BLOCK_NUM,
+          FVB_MEDIA_BLOCK_SIZE,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  },
+
+  //
+  // Recovery BIOS FVB
+  //
+  {
+    FV_RECOVERY_BASE_ADDRESS,
+    {
+      {0,}, //ZeroVector[16]
+      EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+      FVB_MEDIA_BLOCK_SIZE * RECOVERY_BIOS_BLOCK_NUM,
+      EFI_FVH_SIGNATURE,
+      0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for details on EFI_FVB_ATTRIBUTES_2
+      sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+      0,    //CheckSum which will be calucated dynamically.
+      0,    //ExtHeaderOffset
+      {0,}, //Reserved[1]
+      2,    //Revision
+      {
+        {
+          RECOVERY_BIOS_BLOCK_NUM,
+          FVB_MEDIA_BLOCK_SIZE,
+        }
+      }
+    },
+    {
+      {
+        0,
+        0
+      }
+    }
+  }
+};
+
+EFI_STATUS
+GetFvbInfo (
+  IN  EFI_PHYSICAL_ADDRESS         FvBaseAddress,
+  OUT EFI_FIRMWARE_VOLUME_HEADER   **FvbInfo
+  )
+{
+  UINTN                       Index;
+  EFI_FIRMWARE_VOLUME_HEADER  *FvHeader;
+
+  for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB2_MEDIA_INFO); Index += 1) {
+    if (mPlatformFvbMediaInfo[Index].BaseAddress == FvBaseAddress) {
+      FvHeader =  &mPlatformFvbMediaInfo[Index].FvbInfo;
+
+      //
+      // Update the checksum value of FV header.
+      //
+      FvHeader->Checksum = CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
+
+      *FvbInfo = FvHeader;
+
+      DEBUG ((EFI_D_INFO, "\nBaseAddr: 0x%lx \n", FvBaseAddress));
+      DEBUG ((EFI_D_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength));
+      DEBUG ((EFI_D_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLength));
+      DEBUG ((EFI_D_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)->BlockMap[0].NumBlocks));
+      DEBUG ((EFI_D_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInfo)->BlockMap[0].Length));
+      DEBUG ((EFI_D_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n",   (*FvbInfo)->BlockMap[1].NumBlocks));
+      DEBUG ((EFI_D_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbInfo)->BlockMap[1].Length));
+
+      return EFI_SUCCESS;
+    }
+  }
+  return EFI_NOT_FOUND;
+}

+ 80 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf

@@ -0,0 +1,80 @@
+## @file
+# This driver implement the EFI_FIRMWARE_VOLUMEN_PROTOCOL.
+#
+# Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FvbRuntimeDxe
+  FILE_GUID                      = FD3B7E55-FA7B-4e07-AE1D-208B81FB0BAD
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = DxeFvbInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+#  VIRTUAL_ADDRESS_MAP_CALLBACK  =  FvbVirtualddressChangeEvent
+#
+
+[Sources]
+  FvbInfo.c
+  FvbService.h
+  FvbService.c
+  FvbServiceDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  FlashDeviceLib
+  PcdLib
+  MemoryAllocationLib
+  CacheMaintenanceLib
+  IoLib
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  UefiLib
+  UefiRuntimeLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gEfiFirmwareFileSystem2Guid                   # ALWAYS_CONSUMED
+  gEfiSystemNvDataFvGuid                        # ALWAYS_CONSUMED
+  gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_PRODUCED
+  gEfiFirmwareVolumeBlockProtocolGuid           # PROTOCOL ALWAYS_PRODUCED
+
+[FixedPcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
+
+[Pcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+
+[Depex]
+  gEfiSpiProtocolGuid AND gEfiRuntimeArchProtocolGuid
+

+ 1098 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.c

@@ -0,0 +1,1098 @@
+/** @file
+  Firmware Volume Block Driver for Lakeport Platform.
+
+  Firmware volume block driver for FWH or SPI device.
+  It depends on which Flash Device Library to be linked with this driver.
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include "FvbService.h"
+
+//
+// Global variable for this FVB driver  which contains
+// the private data of all firmware volume block instances.
+//
+FWB_GLOBAL   mFvbModuleGlobal;
+
+//
+// This platform driver knows there are 3 FVs on
+// FD, which are FvRecovery, FvMain and FvNvStorage.
+//
+UINT32 mPlatformFvBaseAddress[] = {
+  FixedPcdGet32(PcdFlashNvStorageVariableBase),
+};
+
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_MEMMAP_DP,
+      {
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+      }
+    },
+    EfiMemoryMappedIO,
+    (EFI_PHYSICAL_ADDRESS) 0,
+    (EFI_PHYSICAL_ADDRESS) 0,
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
+  {
+    {
+      MEDIA_DEVICE_PATH,
+      MEDIA_PIWG_FW_VOL_DP,
+      {
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+      }
+    },
+    { 0 }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+//
+// Template structure used when installing FVB protocol.
+//
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+  FVB_DEVICE_SIGNATURE,
+  NULL,
+  0, // Instance
+  {
+    FvbProtocolGetAttributes,
+    FvbProtocolSetAttributes,
+    FvbProtocolGetPhysicalAddress,
+    FvbProtocolGetBlockSize,
+    FvbProtocolRead,
+    FvbProtocolWrite,
+    FvbProtocolEraseBlocks,
+    NULL
+  } // FwVolBlockInstance
+};
+
+
+/**
+  Get the pointer to EFI_FW_VOL_INSTANCE from the buffer pointed
+  by mFvbModuleGlobal.FvInstance based on a index.
+  Each EFI_FW_VOL_INSTANCE is  with variable length as
+  we have a block map at the end of the EFI_FIRMWARE_VOLUME_HEADER.
+
+  @param[in] Instance The index of the EFI_FW_VOL_INSTANCE.
+
+  @return A pointer to EFI_FW_VOL_INSTANCE.
+
+**/
+EFI_FW_VOL_INSTANCE *
+GetFvbInstance (
+  IN  UINTN             Instance
+  )
+{
+  EFI_FW_VOL_INSTANCE   *FwhRecord;
+
+  if ( Instance >= mFvbModuleGlobal.NumFv ) {
+    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+    return NULL;
+  }
+
+  //
+  // Find the right instance of the FVB private data.
+  //
+  FwhRecord = mFvbModuleGlobal.FvInstance;
+  while ( Instance > 0 ) {
+    FwhRecord = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhRecord) +
+                FwhRecord->VolumeHeader.HeaderLength +
+                (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));
+    Instance --;
+  }
+
+  return FwhRecord;
+
+}
+
+
+/**
+  Get the EFI_FVB_ATTRIBUTES_2 of a FV.
+
+  @param[in]  The index of the EFI_FW_VOL_INSTANCE.
+
+  @return     EFI_FVB_ATTRIBUTES_2 of the FV identified by Instance.
+
+**/
+STATIC
+EFI_FVB_ATTRIBUTES_2
+FvbGetVolumeAttributes (
+  IN UINTN                                Instance
+  )
+{
+  EFI_FW_VOL_INSTANCE *    FwInstance = NULL;
+  FwInstance = GetFvbInstance(Instance);
+  ASSERT (FwInstance != NULL);
+
+  if ( FwInstance != NULL ) {
+    return FwInstance->VolumeHeader.Attributes;
+  } else {
+    return 0;
+  }
+}
+
+
+/**
+  Retrieves the starting address of an LBA in an FV. It also
+  return a few other attribut of the FV.
+
+  @param[in]  Instance               The index of the EFI_FW_VOL_INSTANCE.
+  @param[in]  Lba                    The logical block address.
+  @param[out] LbaAddress             On output, contains the physical starting address
+                                     of the Lba.
+  @param[out] LbaLength              On output, contains the length of the block.
+  @param[out] NumOfBlocks            A pointer to a caller allocated UINTN in which the
+                                     number of consecutive blocks starting with Lba is
+                                     returned. All blocks in this range have a size of
+                                     BlockSize.
+
+  @retval  EFI_SUCCESS Successfully  returns.
+  @retval  EFI_INVALID_PARAMETER     Instance not found.
+
+**/
+STATIC
+EFI_STATUS
+FvbGetLbaAddress (
+  IN  UINTN                               Instance,
+  IN  EFI_LBA                             Lba,
+  OUT UINTN                               *LbaAddress,
+  OUT UINTN                               *LbaLength,
+  OUT UINTN                               *NumOfBlocks
+  )
+{
+  UINT32                                  NumBlocks = 0;
+  UINT32                                  BlockLength = 0;
+  UINTN                                   Offset;
+  EFI_LBA                                 StartLba;
+  EFI_LBA                                 NextLba;
+  EFI_FW_VOL_INSTANCE                     *FwhInstance;
+  EFI_FV_BLOCK_MAP_ENTRY                  *BlockMap = NULL;
+
+  //
+  // Find the right instance of the FVB private data.
+  //
+  FwhInstance = GetFvbInstance (Instance);
+
+  StartLba  = 0;
+  Offset    = 0;
+  BlockMap  = &(FwhInstance->VolumeHeader.BlockMap[0]);
+  ASSERT (BlockMap != NULL);
+
+  //
+  // Parse the blockmap of the FV to find which map entry the Lba belongs to.
+  //
+  while (TRUE) {
+    if ( BlockMap != NULL) {
+      NumBlocks   = BlockMap->NumBlocks;
+      BlockLength = BlockMap->Length;
+    }
+
+    if ( NumBlocks == 0 || BlockLength == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    NextLba = StartLba + NumBlocks;
+
+    //
+    // The map entry found.
+    //
+    if (Lba >= StartLba && Lba < NextLba) {
+      Offset = Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLength);
+      if ( LbaAddress && FwhInstance ) {
+        *LbaAddress = FwhInstance->FvBase + Offset;
+      }
+
+      if (LbaLength ) {
+        *LbaLength = BlockLength;
+      }
+
+      if (NumOfBlocks ) {
+        *NumOfBlocks = (UINTN)(NextLba - Lba);
+      }
+      return EFI_SUCCESS;
+    }
+
+    StartLba  = NextLba;
+    Offset    = Offset + NumBlocks * BlockLength;
+    BlockMap++;
+  }
+}
+
+
+/**
+  Reads specified number of bytes into a buffer from the specified block.
+
+  @param[in]      Instance               The FV instance to be read from.
+  @param[in]      Lba                    The logical block address to be read from.
+  @param[in]      BlockOffset            Offset into the block at which to begin reading.
+  @param[in]      NumBytes               Pointer that on input contains the total size of
+                                         the buffer. On output, it contains the total number
+                                         of bytes read.
+  @param[in]      Buffer                 Pointer to a caller allocated buffer that will be
+                                         used to hold the data read.
+
+
+  @retval         EFI_SUCCESS            The firmware volume was read successfully and
+                                         contents are in Buffer.
+  @retval         EFI_BAD_BUFFER_SIZE    Read attempted across a LBA boundary. On output,
+                                         NumBytes contains the total number of bytes returned
+                                         in Buffer.
+  @retval         EFI_ACCESS_DENIED      The firmware volume is in the ReadDisabled state.
+  @retval         EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                         could not be read.
+  @retval         EFI_INVALID_PARAMETER  Instance not found, or NumBytes, Buffer are NULL.
+
+**/
+STATIC
+EFI_STATUS
+FvbReadBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                BlockOffset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer
+  )
+{
+  EFI_FVB_ATTRIBUTES_2                    Attributes;
+  UINTN                                   LbaAddress;
+  UINTN                                   LbaLength;
+  EFI_STATUS                              Status;
+
+  if ( (NumBytes == NULL) || (Buffer == NULL)) {
+    return (EFI_INVALID_PARAMETER);
+  }
+  if (*NumBytes == 0) {
+    return (EFI_INVALID_PARAMETER);
+  }
+
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  Attributes = FvbGetVolumeAttributes (Instance);
+
+  if ( (Attributes & EFI_FVB2_READ_STATUS) == 0) {
+    return (EFI_ACCESS_DENIED);
+  }
+
+  if (BlockOffset > LbaLength) {
+   return (EFI_INVALID_PARAMETER);
+  }
+
+  if (LbaLength < ( *NumBytes + BlockOffset ) ) {
+    *NumBytes = (UINT32) (LbaLength - BlockOffset);
+    Status = EFI_BAD_BUFFER_SIZE;
+  }
+
+  LibFvbFlashDeviceRead (LbaAddress + BlockOffset, NumBytes, Buffer);
+
+  return Status;
+}
+
+
+/**
+  Writes specified number of bytes from the input buffer to the block.
+
+  @param[in]  Instance               The FV instance to be written to.
+  @param[in]  Lba                    The starting logical block index to write to.
+  @param[in]  BlockOffset            Offset into the block at which to begin writing.
+  @param[in]  NumBytes               Pointer that on input contains the total size of
+                                     the buffer. On output, it contains the total number
+                                     of bytes actually written.
+  @param[in]  Buffer                 Pointer to a caller allocated buffer that contains
+                                     the source for the write.
+  @retval     EFI_SUCCESS            The firmware volume was written successfully.
+  @retval     EFI_BAD_BUFFER_SIZE    Write attempted across a LBA boundary. On output,
+                                     NumBytes contains the total number of bytes
+                                     actually writte.
+  @retval     EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled state.
+  @retval     EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                     could not be written.
+  @retval     EFI_INVALID_PARAMETER  Instance not found, or NumBytes, Buffer are NULL.
+
+**/
+EFI_STATUS
+FvbWriteBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                BlockOffset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer
+  )
+{
+  EFI_FVB_ATTRIBUTES_2                    Attributes;
+  UINTN                                   LbaAddress;
+  UINTN                                   LbaLength;
+  EFI_STATUS                              Status;
+  EFI_STATUS                              Status1;
+
+  if ( (NumBytes == NULL) || (Buffer == NULL)) {
+    return (EFI_INVALID_PARAMETER);
+  }
+  if (*NumBytes == 0) {
+    return (EFI_INVALID_PARAMETER);
+  }
+
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //
+  // Check if the FV is write enabled.
+  //
+  Attributes = FvbGetVolumeAttributes (Instance);
+  if ( (Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+    return (EFI_ACCESS_DENIED);
+  }
+
+  //
+  // Perform boundary checks and adjust NumBytes.
+  //
+  if (BlockOffset > LbaLength) {
+    return (EFI_INVALID_PARAMETER);
+  }
+
+  if ( LbaLength < ( *NumBytes + BlockOffset ) ) {
+    DEBUG ((EFI_D_ERROR,
+      "FvWriteBlock: Reducing Numbytes from 0x%x to 0x%x\n",
+      *NumBytes,
+      (UINT32)(LbaLength-BlockOffset))
+      );
+    *NumBytes = (UINT32) (LbaLength - BlockOffset);
+    Status = EFI_BAD_BUFFER_SIZE;
+  }
+
+  LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, FALSE);
+
+  Status1 = LibFvbFlashDeviceWrite (LbaAddress + BlockOffset, NumBytes, Buffer);
+
+  LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, TRUE);
+  WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress + BlockOffset), *NumBytes);
+
+  if ( EFI_ERROR (Status1) ) {
+    return Status1;
+  }
+
+  return Status;
+}
+
+
+/**
+  Erases and initializes a firmware volume block.
+
+  @param[in]    Instance           The FV instance to be erased.
+  @param[in]    Lba                The logical block index to be erased.
+
+  @retval   EFI_SUCCESS            The erase request was successfully completed.
+  @retval   EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled state.
+  @retval   EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                   could not be written. Firmware device may have been
+                                   partially erased.
+  @retval   EFI_INVALID_PARAMETER  Instance not found.
+
+**/
+EFI_STATUS
+FvbEraseBlock (
+  IN UINTN                                Instance,
+  IN EFI_LBA                              Lba
+  )
+{
+  EFI_FVB_ATTRIBUTES_2                    Attributes;
+  UINTN                                   LbaAddress;
+  UINTN                                   LbaLength;
+  EFI_STATUS                              Status;
+
+  //
+  // Check if the FV is write enabled.
+  //
+  Attributes = FvbGetVolumeAttributes (Instance);
+
+  if( (Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+    return (EFI_ACCESS_DENIED);
+  }
+
+  //
+  // Get the starting address of the block for erase.
+  //
+  Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, FALSE);
+
+  Status = LibFvbFlashDeviceBlockErase (LbaAddress, LbaLength);
+
+  LibFvbFlashDeviceBlockLock (LbaAddress, LbaLength, TRUE);
+
+  WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength);
+
+  return Status;
+}
+
+
+/**
+  Modifies the current settings of the firmware volume according to the
+  input parameter, and returns the new setting of the volume.
+
+  @param[in]  Instance              The FV instance whose attributes is going to be
+                                    modified.
+  @param[in]  Attributes            On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
+                                    containing the desired firmware volume settings.
+                                    On successful return, it contains the new settings
+                                    of the firmware volume.
+
+  @retval     EFI_SUCCESS           Successfully returns.
+  @retval     EFI_ACCESS_DENIED     The volume setting is locked and cannot be modified.
+  @retval     EFI_INVALID_PARAMETER Instance not found, or The attributes requested are
+                                    in conflict with the capabilities as declared in the
+                                    firmware volume header.
+
+**/
+STATIC
+EFI_STATUS
+FvbSetVolumeAttributes (
+  IN UINTN                                Instance,
+  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes
+  )
+{
+  EFI_FW_VOL_INSTANCE                       *FwhInstance = NULL;
+  EFI_FVB_ATTRIBUTES_2                      OldAttributes = 0;
+  EFI_FVB_ATTRIBUTES_2                      *AttribPtr = NULL;
+  EFI_FVB_ATTRIBUTES_2                      UnchangedAttributes;
+  UINT32                                    Capabilities;
+  UINT32                                    OldStatus, NewStatus;
+
+  //
+  // Find the right instance of the FVB private data.
+  //
+  FwhInstance = GetFvbInstance (Instance);
+
+  AttribPtr     = (EFI_FVB_ATTRIBUTES_2 *) & (FwhInstance->VolumeHeader.Attributes);
+  ASSERT (AttribPtr != NULL);
+
+  if ( AttribPtr != NULL) {
+    OldAttributes = *AttribPtr;
+  }
+
+  Capabilities  = OldAttributes & EFI_FVB2_CAPABILITIES;
+  OldStatus     = OldAttributes & EFI_FVB2_STATUS;
+  NewStatus     = *Attributes & EFI_FVB2_STATUS;
+
+  UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP  | \
+                        EFI_FVB2_READ_ENABLED_CAP   | \
+                        EFI_FVB2_WRITE_DISABLED_CAP | \
+                        EFI_FVB2_WRITE_ENABLED_CAP  | \
+                        EFI_FVB2_LOCK_CAP           | \
+                        EFI_FVB2_STICKY_WRITE       | \
+                        EFI_FVB2_MEMORY_MAPPED      | \
+                        EFI_FVB2_ERASE_POLARITY     | \
+                        EFI_FVB2_READ_LOCK_CAP      | \
+                        EFI_FVB2_WRITE_LOCK_CAP     | \
+                        EFI_FVB2_ALIGNMENT;
+
+  //
+  // Some attributes of FV is read only can *not* be set.
+  //
+  if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // If firmware volume is locked, no status bit can be updated.
+  //
+  if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) {
+    if ( OldStatus ^ NewStatus ) {
+      return EFI_ACCESS_DENIED;
+    }
+  }
+
+  //
+  // Test read disable.
+  //
+  if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+    if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Test read enable.
+  //
+  if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_READ_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Test write disable.
+  //
+  if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+    if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Test write enable.
+  //
+  if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // Test lock.
+  //
+  if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+    if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  *AttribPtr  = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+  *AttribPtr  = (*AttribPtr) | NewStatus;
+  *Attributes = *AttribPtr;
+
+  return EFI_SUCCESS;
+}
+
+//
+// FVB protocol APIs.
+//
+/**
+  Retrieves the physical address of the device.
+
+  @param[in]  This    A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
+  @param[out] Address Output buffer containing the address.
+
+  retval      EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+  OUT EFI_PHYSICAL_ADDRESS               *Address
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+  EFI_FW_VOL_INSTANCE                   *FvInstance;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  FvInstance = GetFvbInstance(FvbDevice->Instance);
+
+  if (FvInstance != NULL) {
+    *Address = FvInstance->FvBase;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Retrieve the size of a logical block.
+
+  @param[in]  This         Calling context.
+  @param[in]  Lba          Indicates which block to return the size for.
+  @param[out] BlockSize    A pointer to a caller allocated UINTN in which
+                           the size of the block is returned.
+  @param[out] NumOfBlocks  A pointer to a caller allocated UINTN in which the
+                           number of consecutive blocks starting with Lba is
+                           returned. All blocks in this range have a size of
+                           BlockSize.
+
+  @retval     EFI_SUCCESS  The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+  IN  EFI_LBA                            Lba,
+  OUT UINTN                              *BlockSize,
+  OUT UINTN                              *NumOfBlocks
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE                 *FvbDevice;
+
+  DEBUG((EFI_D_INFO,
+    "FvbProtocolGetBlockSize: Lba: 0x%lx BlockSize: 0x%x NumOfBlocks: 0x%x\n",
+    Lba,
+    BlockSize,
+    NumOfBlocks)
+    );
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  return FvbGetLbaAddress (
+           FvbDevice->Instance,
+           Lba,
+           NULL,
+           BlockSize,
+           NumOfBlocks
+           );
+}
+
+
+/**
+  Retrieves Volume attributes.  No polarity translations are done.
+
+  @param[in]    This         Calling context.
+  @param[out]   Attributes   Output buffer which contains attributes.
+
+  @retval       EFI_SUCCESS  The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  OUT EFI_FVB_ATTRIBUTES_2                *Attributes
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  *Attributes = FvbGetVolumeAttributes (FvbDevice->Instance);
+
+  DEBUG ((EFI_D_INFO,
+    "FvbProtocolGetAttributes: This: 0x%x Attributes: 0x%x\n",
+    This,
+    *Attributes)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Sets Volume attributes. No polarity translations are done.
+
+  @param[in]  This         Calling context.
+  @param[out] Attributes   Output buffer which contains attributes.
+
+  @retval     EFI_SUCCESS  The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2             *Attributes
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+
+  DEBUG((EFI_D_INFO,
+    "FvbProtocolSetAttributes: Before SET -  This: 0x%x Attributes: 0x%x\n",
+    This,
+    *Attributes)
+    );
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  Status = FvbSetVolumeAttributes (FvbDevice->Instance, Attributes);
+
+  DEBUG((EFI_D_INFO,
+    "FvbProtocolSetAttributes: After SET -  This: 0x%x Attributes: 0x%x\n",
+    This,
+    *Attributes)
+    );
+
+  return Status;
+}
+
+
+/**
+  The EraseBlock() function erases one or more blocks as denoted by the
+  variable argument list. The entire parameter list of blocks must be verified
+  prior to erasing any blocks.  If a block is requested that does not exist
+  within the associated firmware volume (it has a larger index than the last
+  block of the firmware volume), the EraseBlock() function must return
+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+  @param[in] This            Calling context.
+  @param[in] ...             Starting LBA followed by Number of Lba to erase.
+                             a -1 to terminate the list.
+
+  @retval EFI_SUCCESS        The erase request was successfully completed.
+  @retval EFI_ACCESS_DENIED  The firmware volume is in the WriteDisabled state.
+  @retval EFI_DEVICE_ERROR   The block device is not functioning correctly and
+                             could not be written. Firmware device may have been
+                             partially erased.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+  EFI_FW_VOL_INSTANCE                   *FwhInstance;
+  UINTN                                 NumOfBlocks = 0;
+  VA_LIST                               args;
+  EFI_LBA                               StartingLba;
+  UINTN                                 NumOfLba;
+  EFI_STATUS                            Status;
+
+  DEBUG((EFI_D_INFO, "FvbProtocolEraseBlocks: \n"));
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  FwhInstance  = GetFvbInstance (FvbDevice->Instance);
+
+  if (FwhInstance != NULL) {
+    NumOfBlocks = FwhInstance->NumOfBlocks;
+  }
+
+  VA_START (args, This);
+
+  do {
+    StartingLba = VA_ARG (args, EFI_LBA);
+    if ( StartingLba == EFI_LBA_LIST_TERMINATOR ) {
+      break;
+    }
+
+    NumOfLba = VA_ARG (args, UINTN);
+
+    //
+    // Check input parameters.
+    //
+    if (NumOfLba == 0) {
+      VA_END (args);
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if ( ( StartingLba + NumOfLba ) > NumOfBlocks ) {
+      return EFI_INVALID_PARAMETER;
+    }
+  } while ( 1 );
+
+  VA_END (args);
+
+  VA_START (args, This);
+  do {
+    StartingLba = VA_ARG (args, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+      break;
+    }
+
+    NumOfLba = VA_ARG (args, UINTN);
+
+    while ( NumOfLba > 0 ) {
+      Status = FvbEraseBlock (FvbDevice->Instance, StartingLba);
+      if ( EFI_ERROR(Status)) {
+        VA_END (args);
+        return Status;
+      }
+      StartingLba ++;
+      NumOfLba --;
+    }
+
+  } while ( 1 );
+
+  VA_END (args);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Writes data beginning at Lba:Offset from FV. The write terminates either
+  when *NumBytes of data have been written, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This      Calling context.
+  @param[in]      Lba       Block in which to begin write.
+  @param[in]      Offset    Offset in the block at which to begin write.
+  @param[in,out]  NumBytes  On input, indicates the requested write size. On
+                            output, indicates the actual number of bytes written
+  @param[in]      Buffer    Buffer containing source data for the write.
+
+  @retval EFI_SUCCESS           The firmware volume was written successfully.
+  @retval EFI_BAD_BUFFER_SIZE   Write attempted across a LBA boundary. On output,
+                                NumBytes contains the total number of bytes
+                                actually written.
+  @retval EFI_ACCESS_DENIED     The firmware volume is in the WriteDisabled state.
+  @retval EFI_DEVICE_ERROR      The block device is not functioning correctly and
+                                could not be written.
+  @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                Offset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer
+  )
+{
+
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+  DEBUG((EFI_D_INFO,
+    "FvbProtocolWrite: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0x%x\n",
+    Lba,
+    Offset,
+    *NumBytes,
+    Buffer)
+    );
+
+  return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer);
+}
+
+
+/**
+  Reads data beginning at Lba:Offset from FV. The Read terminates either
+  when *NumBytes of data have been read, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This      Calling context.
+  @param[in]      Lba       Block in which to begin write.
+  @param[in]      Offset    Offset in the block at which to begin write
+  @param[in,out]  NumBytes  On input, indicates the requested write size. On
+                            output, indicates the actual number of bytes written.
+  @param[in]      Buffer    Buffer containing source data for the write.
+
+
+Returns:
+  @retval EFI_SUCCESS            The firmware volume was read successfully and
+                                 contents are in Buffer.
+  @retval EFI_BAD_BUFFER_SIZE    Read attempted across a LBA boundary. On output,
+                                 NumBytes contains the total number of bytes returned
+                                 in Buffer.
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the ReadDisabled state
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                 could not be read.
+  @retval EFI_INVALID_PARAMETER  NumBytes or Buffer are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                Offset,
+  IN OUT UINTN                            *NumBytes,
+  OUT UINT8                                *Buffer
+  )
+{
+
+  EFI_FW_VOL_BLOCK_DEVICE   *FvbDevice;
+  EFI_STATUS                Status;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  Status = FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer);
+  DEBUG((EFI_D_INFO,
+    "FvbProtocolRead: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0x%x\n",
+    Lba,
+    Offset,
+    *NumBytes,
+    Buffer)
+    );
+
+  return Status;
+}
+
+
+/**
+  Check the integrity of firmware volume header.
+
+  @param[in]  FwVolHeader   A pointer to a firmware volume header.
+
+  @retval     TRUE          The firmware volume is consistent.
+  @retval     FALSE         The firmware volume has corrupted.
+
+**/
+BOOLEAN
+IsFvHeaderValid (
+  IN       EFI_PHYSICAL_ADDRESS          FvBase,
+  IN CONST EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
+  )
+{
+  if (FvBase == PcdGet32(PcdFlashNvStorageVariableBase)) {
+    if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, sizeof(EFI_GUID)) != 0 ) {
+      return FALSE;
+    }
+  } else {
+    if (CompareMem (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid, sizeof(EFI_GUID)) != 0 ) {
+      return FALSE;
+    }
+  }
+  if ( (FwVolHeader->Revision != EFI_FVH_REVISION)   ||
+       (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+       (FwVolHeader->FvLength == ((UINTN) -1))       ||
+       ((FwVolHeader->HeaderLength & 0x01 ) !=0) ) {
+    return FALSE;
+  }
+
+  if (CalculateCheckSum16 ((UINT16 *) FwVolHeader, FwVolHeader->HeaderLength) != 0) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+
+/**
+  The function does the necessary initialization work for
+  Firmware Volume Block Driver.
+
+  @retval     EFI_SUCCESS       This funtion always return EFI_SUCCESS.
+                                It will ASSERT on errors.
+
+**/
+EFI_STATUS
+FvbInitialize (
+  VOID
+  )
+{
+  EFI_FW_VOL_INSTANCE                   *FwhInstance;
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
+  EFI_FIRMWARE_VOLUME_HEADER            *FvHeader;
+  EFI_FV_BLOCK_MAP_ENTRY                *PtrBlockMapEntry;
+  EFI_PHYSICAL_ADDRESS                  BaseAddress;
+  EFI_STATUS                            Status;
+  UINTN                                 BufferSize;
+  UINTN                                 TmpHeaderLength;
+  UINTN                                 Idx;
+  UINT32                                MaxLbaSize;
+
+  //
+  // Calculate the total size for all firmware volume block instances.
+  //
+  BufferSize = 0;
+  for (Idx = 0; Idx < 1; Idx++) {
+    FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) mPlatformFvBaseAddress[Idx];
+    BufferSize +=  (FvHeader->HeaderLength +
+                    sizeof (EFI_FW_VOL_INSTANCE) -
+                    sizeof (EFI_FIRMWARE_VOLUME_HEADER)
+                   );
+  }
+
+  mFvbModuleGlobal.FvInstance =  (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize);
+  ASSERT (NULL != mFvbModuleGlobal.FvInstance);
+
+
+  MaxLbaSize      = 0;
+  FwhInstance     = mFvbModuleGlobal.FvInstance;
+  mFvbModuleGlobal.NumFv   = 0;
+
+  for (Idx = 0; Idx < 1; Idx++) {
+    BaseAddress = mPlatformFvBaseAddress[Idx];
+    FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
+
+    if (!IsFvHeaderValid (BaseAddress, FwVolHeader)) {
+      //
+      // If not valid, get FvbInfo from the information carried in
+      // FVB driver.
+      //
+      DEBUG ((EFI_D_ERROR, "Fvb: FV header @ 0x%lx invalid\n", BaseAddress));
+      Status          = GetFvbInfo (BaseAddress, &FwVolHeader);
+      ASSERT_EFI_ERROR(Status);
+      //
+      //  Write back a healthy FV header.
+      //
+      DEBUG ((EFI_D_ERROR, "FwBlockService.c: Writing back healthy FV header\n"));
+      LibFvbFlashDeviceBlockLock ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length, FALSE);
+
+      Status = LibFvbFlashDeviceBlockErase ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length);
+
+      TmpHeaderLength = (UINTN) FwVolHeader->HeaderLength;
+      Status = LibFvbFlashDeviceWrite (
+                 (UINTN)BaseAddress,
+                 &TmpHeaderLength,
+                 (UINT8 *) FwVolHeader
+                 );
+
+      LibFvbFlashDeviceBlockLock ((UINTN)BaseAddress, FwVolHeader->BlockMap->Length, TRUE);
+
+      WriteBackInvalidateDataCacheRange (
+        (VOID *) (UINTN) BaseAddress,
+        FwVolHeader->BlockMap->Length
+        );
+
+    }
+
+    CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength);
+
+    FwVolHeader = &(FwhInstance->VolumeHeader);
+    FwhInstance->FvBase = (UINTN)BaseAddress;
+
+    //
+    // Process the block map for each FV.
+    //
+    FwhInstance->NumOfBlocks = 0;
+    for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+      //
+      // Get the maximum size of a block.
+      //
+      if (MaxLbaSize < PtrBlockMapEntry->Length) {
+        MaxLbaSize  = PtrBlockMapEntry->Length;
+      }
+      FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks;
+    }
+
+    //
+    // Add a FVB Protocol Instance.
+    //
+    mFvbModuleGlobal.NumFv++;
+    InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1);
+
+    //
+    // Move on to the next FwhInstance.
+    //
+    FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) +
+                                          FwVolHeader->HeaderLength +
+                                          (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)));
+
+  }
+
+  return EFI_SUCCESS;
+}
+

+ 182 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbService.h

@@ -0,0 +1,182 @@
+/** @file
+  The header file for Firmware volume block driver.
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H
+#define _FW_BLOCK_SERVICE_H
+
+#include <Guid/EventGroup.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FlashDeviceLib.h>
+#include <Library/DevicePathLib.h>
+
+//
+// Define two helper macro to extract the Capability field or Status field in FVB
+// bit fields.
+//
+#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
+                              EFI_FVB2_READ_ENABLED_CAP | \
+                              EFI_FVB2_WRITE_DISABLED_CAP | \
+                              EFI_FVB2_WRITE_ENABLED_CAP | \
+                              EFI_FVB2_LOCK_CAP \
+                              )
+
+#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+
+typedef struct {
+  UINTN                       FvBase;
+  UINTN                       NumOfBlocks;
+  //
+  // Note!!!: VolumeHeader must be the last element
+  // of the structure.
+  //
+  EFI_FIRMWARE_VOLUME_HEADER  VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+  EFI_FW_VOL_INSTANCE         *FvInstance;
+  UINT32                      NumFv;
+} FWB_GLOBAL;
+
+//
+// Fvb Protocol instance data.
+//
+#define FVB_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR(a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
+#define FVB_DEVICE_SIGNATURE       SIGNATURE_32('F','V','B','C')
+
+typedef struct {
+  MEDIA_FW_VOL_DEVICE_PATH  FvDevPath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
+} FV_PIWG_DEVICE_PATH;
+
+typedef struct {
+  MEMMAP_DEVICE_PATH          MemMapDevPath;
+  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+typedef struct {
+  UINT32                                Signature;
+  EFI_DEVICE_PATH_PROTOCOL              *DevicePath;
+  UINTN                                 Instance;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+EFI_STATUS
+GetFvbInfo (
+  IN  EFI_PHYSICAL_ADDRESS              FvBaseAddress,
+  OUT EFI_FIRMWARE_VOLUME_HEADER        **FvbInfo
+  );
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  OUT EFI_FVB_ATTRIBUTES_2                      *Attributes
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN OUT EFI_FVB_ATTRIBUTES_2                   *Attributes
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+       OUT EFI_PHYSICAL_ADDRESS                *Address
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+  IN  EFI_LBA                            Lba,
+  OUT UINTN                              *BlockSize,
+  OUT UINTN                              *NumOfBlocks
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                Offset,
+  IN OUT UINTN                            *NumBytes,
+  OUT UINT8                                *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN EFI_LBA                              Lba,
+  IN UINTN                                Offset,
+  IN OUT UINTN                            *NumBytes,
+  IN UINT8                                *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  );
+
+EFI_FW_VOL_INSTANCE *
+GetFvbInstance (
+  IN  UINTN                              Instance
+  );
+
+BOOLEAN
+IsFvHeaderValid (
+  IN       EFI_PHYSICAL_ADDRESS          FvBase,
+  IN CONST EFI_FIRMWARE_VOLUME_HEADER    *FwVolHeader
+  );
+
+VOID
+InstallFvbProtocol (
+  IN  EFI_FW_VOL_INSTANCE               *FwhInstance,
+  IN  UINTN                             InstanceNum
+  );
+
+EFI_STATUS
+FvbInitialize (
+  VOID
+  );
+
+extern FWB_GLOBAL              mFvbModuleGlobal;
+extern EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate;
+extern FV_MEMMAP_DEVICE_PATH   mFvMemmapDevicePathTemplate;
+extern FV_PIWG_DEVICE_PATH     mFvPIWGDevicePathTemplate;
+extern UINT32                  mPlatformFvBaseAddress[3];
+
+#endif
+

+ 199 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c

@@ -0,0 +1,199 @@
+/** @file
+  Firmware Volume Block Driver for Lakeport Platform.
+
+  Firmware volume block driver for FWH or SPI device.
+  It depends on which Flash Device Library to be linked with this driver.
+
+Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include <PiDxe.h>
+#include <Library/UefiRuntimeLib.h>
+#include "FvbService.h"
+
+extern FWB_GLOBAL              mFvbModuleGlobal;
+
+/**
+  Call back function on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+
+  Fixup internal data so that the driver is callable in EFI runtime
+  in virtual mode. Convert the mFvbModuleGlobal date items to there
+  virtual address.
+
+  @param  Event     Event whose notification function is being invoked.
+  @param  Context   The context of the Notification context. Not used in
+                    this call back function.
+
+**/
+VOID
+EFIAPI
+FvbVirtualddressChangeEvent (
+  IN EFI_EVENT                          Event,
+  IN VOID                               *Context
+  )
+{
+  EFI_FW_VOL_INSTANCE                   *FwhInstance;
+  UINTN                                 Index;
+
+  //
+  // Convert the base address of all the instances.
+  //
+  for (Index = 0; Index < mFvbModuleGlobal.NumFv; Index++) {
+    FwhInstance = GetFvbInstance (Index);
+    EfiConvertPointer (0, (VOID **) &FwhInstance->FvBase);
+  }
+
+  EfiConvertPointer (0, (VOID **) &mFvbModuleGlobal.FvInstance);
+}
+
+
+/**
+  The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol
+  for each FV in the system.
+
+  @param[in]  FwhInstance   The pointer to a FW volume instance structure,
+                            which contains the information about one FV.
+  @param[in]  InstanceNum   The instance number which can be used as a ID
+                            to locate this FwhInstance in other functions.
+
+  @retval     VOID
+
+**/
+VOID
+InstallFvbProtocol (
+  IN  EFI_FW_VOL_INSTANCE               *FwhInstance,
+  IN  UINTN                             InstanceNum
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
+  EFI_STATUS                            Status;
+  EFI_HANDLE                            FwbHandle;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *OldFwbInterface;
+
+  FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (
+                                            sizeof (EFI_FW_VOL_BLOCK_DEVICE),
+                                            &mFvbDeviceTemplate
+                                            );
+  ASSERT (FvbDevice != NULL);
+
+  FvbDevice->Instance = InstanceNum;
+  FwVolHeader = &FwhInstance->VolumeHeader;
+
+  //
+  // Set up the devicepath.
+  //
+  DEBUG ((EFI_D_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx:\n", FwhInstance->FvBase));
+  if (FwVolHeader->ExtHeaderOffset == 0) {
+    //
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH.
+    //
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase;
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress   = FwhInstance->FvBase + FwVolHeader->FvLength - 1;
+  } else {
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
+    CopyGuid (
+      &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
+      (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)
+      );
+  }
+
+  //
+  // Find a handle with a matching device path that has supports FW Block protocol.
+  //
+  Status = gBS->LocateDevicePath (
+                  &gEfiFirmwareVolumeBlockProtocolGuid,
+                  &FvbDevice->DevicePath,
+                  &FwbHandle
+                  );
+  if (EFI_ERROR (Status) ) {
+    //
+    // LocateDevicePath fails so install a new interface and device path.
+    //
+    DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath failed, install new interface 0x%lx:\n", FwhInstance->FvBase));
+    FwbHandle = NULL;
+    Status =  gBS->InstallMultipleProtocolInterfaces (
+                     &FwbHandle,
+                     &gEfiFirmwareVolumeBlockProtocolGuid,
+                     &FvbDevice->FwVolBlockInstance,
+                     &gEfiDevicePathProtocolGuid,
+                     FvbDevice->DevicePath,
+                     NULL
+                     );
+    ASSERT_EFI_ERROR (Status);
+    DEBUG ((EFI_D_INFO, "FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0x%lx: %r\n", FwhInstance->FvBase, Status));
+
+  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
+    //
+    // Device allready exists, so reinstall the FVB protocol.
+    //
+    DEBUG ((EFI_D_ERROR, "FwBlockService.c: LocateDevicePath succeeded, reinstall interface 0x%lx:\n", FwhInstance->FvBase));
+    Status = gBS->HandleProtocol (
+                    FwbHandle,
+                    &gEfiFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) &OldFwbInterface
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    Status =  gBS->ReinstallProtocolInterface (
+                     FwbHandle,
+                     &gEfiFirmwareVolumeBlockProtocolGuid,
+                     OldFwbInterface,
+                     &FvbDevice->FwVolBlockInstance
+                     );
+    ASSERT_EFI_ERROR (Status);
+
+  } else {
+    //
+    // There was a FVB protocol on an End Device Path node.
+    //
+    ASSERT (FALSE);
+  }
+
+}
+
+
+/**
+  The driver entry point for Firmware Volume Block Driver.
+
+  The function does the necessary initialization work for
+  Firmware Volume Block Driver.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       This funtion always return EFI_SUCCESS.
+                                It will ASSERT on errors.
+
+**/
+EFI_STATUS
+EFIAPI
+DxeFvbInitialize (
+  IN EFI_HANDLE                         ImageHandle,
+  IN EFI_SYSTEM_TABLE                   *SystemTable
+  )
+{
+  EFI_STATUS                            Status;
+  EFI_EVENT                             Event;
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  FvbVirtualddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &Event
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  FvbInitialize ();
+
+  return EFI_SUCCESS;
+}
+

+ 127 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceSmm.c

@@ -0,0 +1,127 @@
+/** @file
+  SMM Firmware Volume Block Driver for Lakeport Platform.
+
+  Firmware volume block driver for FWH or SPI device.
+  It depends on which Flash Device Library to be linked with this driver.
+
+Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include <PiSmm.h>
+#include <Library/SmmServicesTableLib.h>
+#include "FvbSmmCommon.h"
+#include "FvbService.h"
+
+/**
+  The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol
+  for each FV in the system.
+
+  @param[in]  FwhInstance   The pointer to a FW volume instance structure,
+                            which contains the information about one FV.
+  @param[in]  InstanceNum   The instance number which can be used as a ID
+                            to locate this FwhInstance in other functions.
+
+  @retval     VOID
+
+**/
+VOID
+InstallFvbProtocol (
+  IN  EFI_FW_VOL_INSTANCE               *FwhInstance,
+  IN  UINTN                             InstanceNum
+  )
+{
+  EFI_FW_VOL_BLOCK_DEVICE               *FvbDevice;
+  EFI_FIRMWARE_VOLUME_HEADER            *FwVolHeader;
+  EFI_STATUS                            Status;
+  EFI_HANDLE                            FvbHandle;
+
+  FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (
+                                            sizeof (EFI_FW_VOL_BLOCK_DEVICE),
+                                            &mFvbDeviceTemplate
+                                            );
+  ASSERT (FvbDevice != NULL);
+
+  FvbDevice->Instance = InstanceNum;
+  FwVolHeader         = &FwhInstance->VolumeHeader;
+
+  //
+  // Set up the devicepath.
+  //
+  if (FwVolHeader->ExtHeaderOffset == 0) {
+    //
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH.
+    //
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase;
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress   = FwhInstance->FvBase + FwVolHeader->FvLength - 1;
+  } else {
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
+    CopyGuid (
+      &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
+      (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)
+      );
+  }
+
+  //
+  // Install the SMM Firmware Volume Block Protocol and Device Path Protocol.
+  //
+  FvbHandle = NULL;
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &FvbHandle,
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    &FvbDevice->FwVolBlockInstance
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gSmst->SmmInstallProtocolInterface (
+                    &FvbHandle,
+                    &gEfiDevicePathProtocolGuid,
+                    EFI_NATIVE_INTERFACE,
+                    FvbDevice->DevicePath
+                    );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Notify the Fvb wrapper driver SMM fvb is ready.
+  //
+  FvbHandle = NULL;
+  Status = gBS->InstallProtocolInterface (
+                  &FvbHandle,
+                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &FvbDevice->FwVolBlockInstance
+                  );
+}
+
+
+/**
+  The driver entry point for SMM Firmware Volume Block Driver.
+
+  The function does the necessary initialization work
+  Firmware Volume Block Driver.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       This funtion always return EFI_SUCCESS.
+                                It will ASSERT on errors.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSmmInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  FvbInitialize ();
+
+  return EFI_SUCCESS;
+}
+

+ 82 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf

@@ -0,0 +1,82 @@
+## @file
+# This driver implement the EFI_SMM_FIRMWARE_VOLUMEN_PROTOCOL.
+#
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FvbSmm
+  FILE_GUID                      = A4EC8ADB-B7A8-47d1-8E52-EC820D0ACF6F
+  MODULE_TYPE                    = DXE_SMM_DRIVER
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = FvbSmmInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+#  VIRTUAL_ADDRESS_MAP_CALLBACK  =  FvbVirtualddressChangeEvent
+#
+
+[Sources]
+  FvbInfo.c
+  FvbService.h
+  FvbService.c
+  FvbServiceSmm.c
+  FvbSmmCommon.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[LibraryClasses]
+  FlashDeviceLib
+  PcdLib
+  MemoryAllocationLib
+  CacheMaintenanceLib
+  IoLib
+  BaseMemoryLib
+  DebugLib
+  BaseLib
+  UefiLib
+  SmmLib
+  SmmServicesTableLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gEfiFirmwareFileSystem2Guid                   # ALWAYS_CONSUMED
+  gEfiSystemNvDataFvGuid                        # ALWAYS_CONSUMED
+  gEfiEventVirtualAddressChangeGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_PRODUCED
+  gEfiSmmFirmwareVolumeBlockProtocolGuid        # PROTOCOL ALWAYS_PRODUCED
+
+[FixedPcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase
+
+[Pcd]
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize
+  gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[Depex]
+  gEfiSmmSpiProtocolGuid
+

+ 73 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmCommon.h

@@ -0,0 +1,73 @@
+/** @file
+
+  The common header file for SMM FVB module and SMM FVB runtime Module.
+
+Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved. <BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _SMM_FVB_COMMON_H_
+#define _SMM_FVB_COMMON_H_
+
+#include <Protocol/SmmFirmwareVolumeBlock.h>
+
+#define EFI_FUNCTION_GET_ATTRIBUTES           1
+#define EFI_FUNCTION_SET_ATTRIBUTES           2
+#define EFI_FUNCTION_GET_PHYSICAL_ADDRESS     3
+#define EFI_FUNCTION_GET_BLOCK_SIZE           4
+#define EFI_FUNCTION_READ                     5
+#define EFI_FUNCTION_WRITE                    6
+#define EFI_FUNCTION_ERASE_BLOCKS             7
+
+typedef struct {
+  UINTN       Function;
+  EFI_STATUS  ReturnStatus;
+  UINT8       Data[1];
+} SMM_FVB_COMMUNICATE_FUNCTION_HEADER;
+
+
+///
+/// Size of SMM communicate header, without including the payload.
+///
+#define SMM_COMMUNICATE_HEADER_SIZE  (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))
+
+///
+/// Size of SMM FVB communicate function header, without including the payload.
+///
+#define SMM_FVB_COMMUNICATE_HEADER_SIZE  (OFFSET_OF (SMM_FVB_COMMUNICATE_FUNCTION_HEADER, Data))
+
+typedef struct {
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *SmmFvb;
+  EFI_FVB_ATTRIBUTES_2                       Attributes;
+} SMM_FVB_ATTRIBUTES_HEADER;
+
+typedef struct {
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *SmmFvb;
+  EFI_PHYSICAL_ADDRESS                       Address;
+} SMM_FVB_PHYSICAL_ADDRESS_HEADER;
+
+typedef struct {
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *SmmFvb;
+  EFI_LBA                                    Lba;
+  UINTN                                      BlockSize;
+  UINTN                                      NumOfBlocks;
+} SMM_FVB_BLOCK_SIZE_HEADER;
+
+typedef struct {
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL     *SmmFvb;
+  EFI_LBA                                    Lba;
+  UINTN                                      Offset;
+  UINTN                                      NumBytes;
+} SMM_FVB_READ_WRITE_HEADER;
+
+typedef struct {
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL         *SmmFvb;
+  EFI_LBA                                    StartLba;
+  UINTN                                      NumOfLba;
+} SMM_FVB_BLOCKS_HEADER;
+
+#endif

+ 944 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.c

@@ -0,0 +1,944 @@
+/** @file
+
+  Implement the Firmware Volume Block (FVB) services based on SMM FVB
+  module and install FVB protocol.
+
+Copyright (c) 2010  - 2014, Intel Corporation. All rights reserved. <BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#include "FvbSmmDxe.h"
+
+EFI_HANDLE                       mHandle           = NULL;
+EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication = NULL;
+
+//
+// Template structure used when installing FVB protocol.
+//
+EFI_FVB_DEVICE    mFvbDeviceTemplate = {
+  FVB_DEVICE_SIGNATURE,
+  NULL,
+  {
+    FvbGetAttributes,
+    FvbSetAttributes,
+    FvbGetPhysicalAddress,
+    FvbGetBlockSize,
+    FvbRead,
+    FvbWrite,
+    FvbEraseBlocks,
+    NULL
+  },
+  NULL
+};
+
+FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_MEMMAP_DP,
+      {
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+        (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8)
+      }
+    },
+    EfiMemoryMappedIO,
+    (EFI_PHYSICAL_ADDRESS) 0,
+    (EFI_PHYSICAL_ADDRESS) 0,
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = {
+  {
+    {
+      MEDIA_DEVICE_PATH,
+      MEDIA_PIWG_FW_VOL_DP,
+      {
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)),
+        (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8)
+      }
+    },
+    { 0 }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+/**
+  Initialize the communicate buffer using DataSize and Function.
+
+  The communicate size is: SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE +
+  DataSize.
+
+  @param[out]      CommunicateBuffer The communicate buffer. Caller should free it after use.
+  @param[out]      DataPtr           Points to the data in the communicate buffer. Caller should not free it.
+  @param[in]       DataSize          The payload size.
+  @param[in]       Function          The function number used to initialize the communicate header.
+
+  @retval EFI_INVALID_PARAMETER      The data size is too big.
+  @retval EFI_SUCCESS                Find the specified variable.
+
+**/
+EFI_STATUS
+InitCommunicateBuffer (
+  OUT     VOID                              **CommunicateBuffer,
+  OUT     VOID                              **DataPtr,
+  IN      UINTN                             DataSize,
+  IN      UINTN                             Function
+  )
+{
+  EFI_SMM_COMMUNICATE_HEADER                *SmmCommunicateHeader;
+  SMM_FVB_COMMUNICATE_FUNCTION_HEADER       *SmmFvbFunctionHeader;
+
+  //
+  // The whole buffer size: SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE + DataSize.
+  //
+  SmmCommunicateHeader = AllocatePool (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE);
+  ASSERT (SmmCommunicateHeader != NULL);
+
+  //
+  // Prepare data buffer.
+  //
+  CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmFirmwareVolumeBlockProtocolGuid);
+  SmmCommunicateHeader->MessageLength = DataSize + SMM_FVB_COMMUNICATE_HEADER_SIZE;
+
+  SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data;
+  SmmFvbFunctionHeader->Function = Function;
+
+  *CommunicateBuffer = SmmCommunicateHeader;
+  *DataPtr = SmmFvbFunctionHeader->Data;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Send the data in communicate buffer to SMM.
+
+  @param[out]      SmmCommunicateHeader    The communicate buffer.
+  @param[in]       DataSize                The payload size.
+
+**/
+EFI_STATUS
+SendCommunicateBuffer (
+  IN      EFI_SMM_COMMUNICATE_HEADER        *SmmCommunicateHeader,
+  IN      UINTN                             DataSize
+  )
+{
+  EFI_STATUS                                Status;
+  UINTN                                     CommSize;
+  SMM_FVB_COMMUNICATE_FUNCTION_HEADER       *SmmFvbFunctionHeader;
+
+  CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_FVB_COMMUNICATE_HEADER_SIZE;
+  Status = mSmmCommunication->Communicate (
+                                mSmmCommunication,
+                                SmmCommunicateHeader,
+                                &CommSize
+                                );
+  ASSERT_EFI_ERROR (Status);
+
+  SmmFvbFunctionHeader = (SMM_FVB_COMMUNICATE_FUNCTION_HEADER *) SmmCommunicateHeader->Data;
+  return  SmmFvbFunctionHeader->ReturnStatus;
+}
+
+/**
+  This function retrieves the attributes and current settings of the block.
+
+  @param[in]  This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes
+                         and current settings are returned. Type EFI_FVB_ATTRIBUTES_2
+                         is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS              The firmware volume attributes were returned.
+  @retval EFI_INVALID_PARAMETER    Attributes is NULL.
+**/
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+     OUT   EFI_FVB_ATTRIBUTES_2                 *Attributes
+  )
+{
+  EFI_STATUS                                    Status;
+  UINTN                                         PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                    *SmmCommunicateHeader;
+  SMM_FVB_ATTRIBUTES_HEADER                     *SmmFvbAttributesHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+  EFI_FVB_DEVICE                                *FvbDevice;
+
+  if (Attributes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_ATTRIBUTES_HEADER);
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbAttributesHeader,
+             PayloadSize,
+             EFI_FUNCTION_GET_ATTRIBUTES
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbAttributesHeader->SmmFvb     = SmmFvb;
+  SmmFvbAttributesHeader->Attributes = 0;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *Attributes = SmmFvbAttributesHeader->Attributes;
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  Sets Volume attributes. No polarity translations are done.
+
+  @param[in]  This        Calling context.
+  @param[out] Attributes  Output buffer which contains attributes.
+
+  @retval     EFI_SUCCESS              Set the Attributes successfully.
+  @retval     EFI_INVALID_PARAMETER    Attributes is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN OUT   EFI_FVB_ATTRIBUTES_2                 *Attributes
+  )
+{
+  EFI_STATUS                                    Status;
+  UINTN                                         PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                    *SmmCommunicateHeader;
+  SMM_FVB_ATTRIBUTES_HEADER                     *SmmFvbAttributesHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+  EFI_FVB_DEVICE                                *FvbDevice;
+
+  if (Attributes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_ATTRIBUTES_HEADER);
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbAttributesHeader,
+             PayloadSize,
+             EFI_FUNCTION_SET_ATTRIBUTES
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbAttributesHeader->SmmFvb     = SmmFvb;
+  SmmFvbAttributesHeader->Attributes = *Attributes;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *Attributes = SmmFvbAttributesHeader->Attributes;
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  Retrieves the physical address of the FVB instance.
+
+  @param[in]  SmmFvb         A pointer to EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
+  @param[out] Address        Output buffer containing the address.
+
+  @retval     EFI_SUCCESS    Get the address successfully.
+  @retval     Others         Failed to get address.
+
+**/
+EFI_STATUS
+GetPhysicalAddress (
+  IN   EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *SmmFvb,
+  OUT  EFI_PHYSICAL_ADDRESS                    *Address
+  )
+{
+  EFI_STATUS                                   Status;
+  UINTN                                        PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                   *SmmCommunicateHeader;
+  SMM_FVB_PHYSICAL_ADDRESS_HEADER              *SmmFvbPhysicalAddressHeader;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_PHYSICAL_ADDRESS_HEADER);
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbPhysicalAddressHeader,
+             PayloadSize,
+             EFI_FUNCTION_GET_PHYSICAL_ADDRESS
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbPhysicalAddressHeader->SmmFvb  = SmmFvb;
+  SmmFvbPhysicalAddressHeader->Address = 0;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *Address = SmmFvbPhysicalAddressHeader->Address;
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  Retrieves the physical address of the FVB instance.
+
+  @param[in]  This                     A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
+  @param[out] Address                  Output buffer containing the address.
+
+  @retval     EFI_SUCCESS              Get the address successfully.
+  @retval     Others                   Failed to get the address.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+     OUT   EFI_PHYSICAL_ADDRESS                *Address
+  )
+{
+  EFI_STATUS                                   Status;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *SmmFvb;
+  EFI_FVB_DEVICE                               *FvbDevice;
+
+  if (Address == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  Status = GetPhysicalAddress (SmmFvb, Address);
+
+  return Status;
+}
+
+
+/**
+  Retrieve the size of a logical block.
+
+  @param[in]  This        Calling context.
+  @param[in]  Lba         Indicates which block to return the size for.
+  @param[out] BlockSize   A pointer to a caller allocated UINTN in which
+                          the size of the block is returned.
+  @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which the
+                          number of consecutive blocks starting with Lba is
+                          returned. All blocks in this range have a size of
+                          BlockSize.
+
+  @retval     EFI_SUCCESS              Get BlockSize and NumOfBlocks successfully.
+  @retval     EFI_INVALID_PARAMETER    BlockSize or NumOfBlocks are NULL.
+**/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+  IN       EFI_LBA                             Lba,
+     OUT   UINTN                               *BlockSize,
+     OUT   UINTN                               *NumOfBlocks
+  )
+{
+  EFI_STATUS                                   Status;
+  UINTN                                        PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                   *SmmCommunicateHeader;
+  SMM_FVB_BLOCK_SIZE_HEADER                    *SmmFvbBlockSizeHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL       *SmmFvb;
+  EFI_FVB_DEVICE                               *FvbDevice;
+
+  if ((BlockSize == NULL) || (NumOfBlocks == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_BLOCK_SIZE_HEADER);
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbBlockSizeHeader,
+             PayloadSize,
+             EFI_FUNCTION_GET_BLOCK_SIZE
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbBlockSizeHeader->SmmFvb = SmmFvb;
+  SmmFvbBlockSizeHeader->Lba    = Lba;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *BlockSize   = SmmFvbBlockSizeHeader->BlockSize;
+  *NumOfBlocks = SmmFvbBlockSizeHeader->NumOfBlocks;
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  Reads data beginning at Lba:Offset from FV. The Read terminates either
+  when *NumBytes of data have been read, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This           Calling context
+  @param[in]      Lba            Block in which to begin write
+  @param[in]      Offset         Offset in the block at which to begin write
+  @param[in,out]  NumBytes       On input, indicates the requested write size. On
+                                 output, indicates the actual number of bytes written
+  @param[in]      Buffer         Buffer containing source data for the write.
+
+  @retval EFI_SUCCESS            The firmware volume was read successfully and
+                                 contents are in Buffer.
+  @retval EFI_BAD_BUFFER_SIZE    Read attempted across a LBA boundary. On output,
+                                 NumBytes contains the total number of bytes returned
+                                 in Buffer.
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the ReadDisabled state
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                 could not be read.
+  @retval EFI_INVALID_PARAMETER  NumBytes or Buffer are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN       EFI_LBA                              Lba,
+  IN       UINTN                                Offset,
+  IN OUT   UINTN                                *NumBytes,
+     OUT   UINT8                                *Buffer
+  )
+{
+  EFI_STATUS                                    Status;
+  UINTN                                         PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                    *SmmCommunicateHeader;
+  SMM_FVB_READ_WRITE_HEADER                     *SmmFvbReadWriteHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+  EFI_FVB_DEVICE                                *FvbDevice;
+
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes;
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbReadWriteHeader,
+             PayloadSize, EFI_FUNCTION_READ
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbReadWriteHeader->SmmFvb   = SmmFvb;
+  SmmFvbReadWriteHeader->Lba      = Lba;
+  SmmFvbReadWriteHeader->Offset   = Offset;
+  SmmFvbReadWriteHeader->NumBytes = *NumBytes;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *NumBytes = SmmFvbReadWriteHeader->NumBytes;
+  if (!EFI_ERROR (Status)) {
+    CopyMem (Buffer, (UINT8 *)(SmmFvbReadWriteHeader + 1), *NumBytes);
+  }
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  Writes data beginning at Lba:Offset from FV. The write terminates either
+  when *NumBytes of data have been written, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This           Calling context.
+  @param[in]      Lba            Block in which to begin write.
+  @param[in]      Offset         Offset in the block at which to begin write.
+  @param[in,out]  NumBytes       On input, indicates the requested write size. On
+                                 output, indicates the actual number of bytes written.
+  @param[in]      Buffer         Buffer containing source data for the write.
+
+  @retval EFI_SUCCESS            The firmware volume was written successfully.
+  @retval EFI_BAD_BUFFER_SIZE    Write attempted across a LBA boundary. On output,
+                                 NumBytes contains the total number of bytes
+                                 actually written.
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled state.
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                 could not be written.
+  @retval EFI_INVALID_PARAMETER  NumBytes or Buffer are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN       EFI_LBA                              Lba,
+  IN       UINTN                                Offset,
+  IN OUT   UINTN                                *NumBytes,
+  IN       UINT8                                *Buffer
+  )
+{
+  EFI_STATUS                                    Status;
+  UINTN                                         PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                    *SmmCommunicateHeader;
+  SMM_FVB_READ_WRITE_HEADER                     *SmmFvbReadWriteHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+  EFI_FVB_DEVICE                                *FvbDevice;
+
+  if ((NumBytes == NULL) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_READ_WRITE_HEADER) + *NumBytes;
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbReadWriteHeader,
+             PayloadSize,
+             EFI_FUNCTION_WRITE
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbReadWriteHeader->SmmFvb   = SmmFvb;
+  SmmFvbReadWriteHeader->Lba      = Lba;
+  SmmFvbReadWriteHeader->Offset   = Offset;
+  SmmFvbReadWriteHeader->NumBytes = *NumBytes;
+  CopyMem ((UINT8 *)(SmmFvbReadWriteHeader + 1), Buffer, *NumBytes);
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  *NumBytes = SmmFvbReadWriteHeader->NumBytes;
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  The EraseBlock() function erases NumOfLba blocks started from StartingLba.
+
+  @param[in] This            Calling context.
+  @param[in] StartingLba     Starting LBA followed to erase.
+  @param[in] NumOfLba        Number of block to erase.
+
+  @retval EFI_SUCCESS        The erase request was successfully completed.
+  @retval EFI_ACCESS_DENIED  The firmware volume is in the WriteDisabled state.
+  @retval EFI_DEVICE_ERROR   The block device is not functioning correctly and
+                             could not be written. Firmware device may have been
+                             partially erased.
+
+**/
+EFI_STATUS
+EraseBlock (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  IN       EFI_LBA                               StartingLba,
+  IN       UINTN                                 NumOfLba
+  )
+{
+  EFI_STATUS                                     Status;
+  UINTN                                          PayloadSize;
+  EFI_SMM_COMMUNICATE_HEADER                    *SmmCommunicateHeader;
+  SMM_FVB_BLOCKS_HEADER                         *SmmFvbBlocksHeader;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+  EFI_FVB_DEVICE                                *FvbDevice;
+
+  FvbDevice = FVB_DEVICE_FROM_THIS (This);
+  SmmFvb    = FvbDevice->SmmFvbInstance;
+
+  //
+  // Initialize the communicate buffer.
+  //
+  PayloadSize  = sizeof (SMM_FVB_BLOCKS_HEADER);
+  Status = InitCommunicateBuffer (
+             (VOID **)&SmmCommunicateHeader,
+             (VOID **)&SmmFvbBlocksHeader,
+             PayloadSize,
+             EFI_FUNCTION_ERASE_BLOCKS
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  SmmFvbBlocksHeader->SmmFvb   = SmmFvb;
+  SmmFvbBlocksHeader->StartLba = StartingLba;
+  SmmFvbBlocksHeader->NumOfLba = NumOfLba;
+
+  //
+  // Send data to SMM.
+  //
+  Status = SendCommunicateBuffer (SmmCommunicateHeader, PayloadSize);
+
+  //
+  // Get data from SMM.
+  //
+  FreePool (SmmCommunicateHeader);
+
+  return Status;
+}
+
+
+/**
+  The EraseBlocks() function erases one or more blocks as denoted by the
+  variable argument list. The entire parameter list of blocks must be verified
+  prior to erasing any blocks.  If a block is requested that does not exist
+  within the associated firmware volume (it has a larger index than the last
+  block of the firmware volume), the EraseBlock() function must return
+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+  @param[in] This           Calling context/
+  @param[in] ...            Starting LBA followed by Number of Lba to erase.
+                            a -1 to terminate the list.
+/
+  @retval EFI_SUCCESS       The erase request was successfully completed
+  @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state/
+  @retval EFI_DEVICE_ERROR  The block device is not functioning correctly and
+                            could not be written. Firmware device may have been
+                            partially erased/
+
+**/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  )
+{
+  EFI_STATUS                                     Status;
+  VA_LIST                                        Marker;
+  EFI_LBA                                        StartingLba;
+  UINTN                                          NumOfLba;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Check the parameter.
+  //
+  VA_START (Marker, This);
+  do {
+    StartingLba = VA_ARG (Marker, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR ) {
+      break;
+    }
+
+    NumOfLba = VA_ARG (Marker, UINTN);
+    if (NumOfLba == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+  } while ( 1 );
+  VA_END (Marker);
+
+  //
+  // Erase the blocks.
+  //
+  VA_START (Marker, This);
+  do {
+    StartingLba = VA_ARG (Marker, EFI_LBA);
+    if (StartingLba == EFI_LBA_LIST_TERMINATOR ) {
+      break;
+    }
+    NumOfLba = VA_ARG (Marker, UINTN);
+    Status = EraseBlock (This, StartingLba, NumOfLba);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+  } while ( 1 );
+  VA_END (Marker);
+
+  return Status;
+}
+
+
+/**
+  Install the FVB protocol which based on SMM FVB protocol.
+
+  @param[in] SmmFvb        The SMM FVB protocol.
+
+**/
+VOID
+InstallFvb (
+  IN    EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *SmmFvb
+  )
+{
+  EFI_STATUS                                    Status;
+  EFI_HANDLE                                    FvbHandle;
+  EFI_FVB_DEVICE                                *FvbDevice;
+  EFI_FIRMWARE_VOLUME_HEADER                    *VolumeHeader;
+  EFI_PHYSICAL_ADDRESS                          Address;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL            *OldFvbInterface;
+
+  FvbDevice = AllocateRuntimeCopyPool (sizeof (EFI_FVB_DEVICE), &mFvbDeviceTemplate);
+  ASSERT (FvbDevice != NULL);
+  FvbDevice->SmmFvbInstance = SmmFvb;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSmmCommunicationProtocolGuid,
+                  NULL,
+                  (VOID **) &mSmmCommunication
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = GetPhysicalAddress (SmmFvb, &Address);
+  ASSERT_EFI_ERROR (Status);
+
+  VolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN)Address;
+
+  //
+  // Set up the devicepath.
+  //
+  if (VolumeHeader->ExtHeaderOffset == 0) {
+    //
+    // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH.
+    //
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = (UINTN)Address;
+    ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress   = (UINTN)Address + VolumeHeader->FvLength - 1;
+  } else {
+    FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
+    CopyGuid (
+      &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
+      (GUID *)(UINTN)((UINTN)Address + VolumeHeader->ExtHeaderOffset)
+      );
+  }
+
+  //
+  // Find a handle with a matching device path that has supports FW Block protocol.
+  //
+  Status = gBS->LocateDevicePath (
+                  &gEfiFirmwareVolumeBlockProtocolGuid,
+                  &FvbDevice->DevicePath,
+                  &FvbHandle
+                  );
+  if (EFI_ERROR (Status) ) {
+    //
+    // LocateDevicePath fails so install a new interface and device path.
+    //
+    FvbHandle = NULL;
+    Status =  gBS->InstallMultipleProtocolInterfaces (
+                     &FvbHandle,
+                     &gEfiFirmwareVolumeBlockProtocolGuid,
+                     &FvbDevice->FvbInstance,
+                     &gEfiDevicePathProtocolGuid,
+                     FvbDevice->DevicePath,
+                     NULL
+                     );
+    ASSERT_EFI_ERROR (Status);
+  } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {
+    //
+    // Device allready exists, so reinstall the FVB protocol.
+    //
+    Status = gBS->HandleProtocol (
+                    FvbHandle,
+                    &gEfiFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) &OldFvbInterface
+                    );
+    ASSERT_EFI_ERROR (Status);
+
+    Status =  gBS->ReinstallProtocolInterface (
+                     FvbHandle,
+                     &gEfiFirmwareVolumeBlockProtocolGuid,
+                     OldFvbInterface,
+                     &FvbDevice->FvbInstance
+                     );
+    ASSERT_EFI_ERROR (Status);
+  } else {
+    //
+    // There was a FVB protocol on an End Device Path node.
+    //
+    ASSERT (FALSE);
+  }
+}
+
+
+/**
+  SMM Firmware Volume Block Protocol notification event handler.
+
+  Discover NV Variable Store and install Variable Write Arch Protocol.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+SmmFvbReady (
+  IN  EFI_EVENT                                 Event,
+  IN  VOID                                      *Context
+  )
+{
+  EFI_STATUS                                    Status;
+  EFI_HANDLE                                    *HandleBuffer;
+  UINTN                                         HandleCount;
+  UINTN                                         Index;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL        *SmmFvb;
+
+  //
+  // Locate all handles of Smm Fvb protocol.
+  //
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return ;
+  }
+
+  //
+  // Install FVB protocol.
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    SmmFvb = NULL;
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+                    (VOID **) &SmmFvb
+                    );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    InstallFvb (SmmFvb);
+  }
+
+  FreePool (HandleBuffer);
+}
+
+
+/**
+  The driver entry point for Firmware Volume Block Driver.
+
+  The function does the necessary initialization work
+  Firmware Volume Block Driver.
+
+  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
+  @param[in]  SystemTable       A pointer to the EFI system table.
+
+  @retval     EFI_SUCCESS       This funtion always return EFI_SUCCESS.
+                                It will ASSERT on errors.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSmmDxeInitialize (
+  IN EFI_HANDLE                                 ImageHandle,
+  IN EFI_SYSTEM_TABLE                           *SystemTable
+  )
+{
+  VOID                                          *SmmFvbRegistration;
+
+  //
+  // Smm FVB driver is ready.
+  //
+  EfiCreateProtocolNotifyEvent (
+    &gEfiSmmFirmwareVolumeBlockProtocolGuid,
+    TPL_CALLBACK,
+    SmmFvbReady,
+    NULL,
+    &SmmFvbRegistration
+    );
+
+  return EFI_SUCCESS;
+}
+

+ 232 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.h

@@ -0,0 +1,232 @@
+/** @file
+
+  The internal header file includes the common header files, defines
+  internal structure and functions used by FVB module.
+
+Copyright (c) 2010  - 2014, Intel Corporation. All rights reserved. <BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _SMM_FVB_DXE_H_
+#define _SMM_FVB_DXE_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/SmmFirmwareVolumeBlock.h>
+#include <Protocol/SmmCommunication.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+
+#include <Guid/EventGroup.h>
+#include "FvbSmmCommon.h"
+
+#define FVB_DEVICE_SIGNATURE              SIGNATURE_32 ('F', 'V', 'B', 'S')
+#define FVB_DEVICE_FROM_THIS(a)           CR (a, EFI_FVB_DEVICE, FvbInstance, FVB_DEVICE_SIGNATURE)
+
+typedef struct {
+  MEDIA_FW_VOL_DEVICE_PATH  FvDevPath;
+  EFI_DEVICE_PATH_PROTOCOL  EndDevPath;
+} FV_PIWG_DEVICE_PATH;
+
+typedef struct {
+  MEMMAP_DEVICE_PATH          MemMapDevPath;
+  EFI_DEVICE_PATH_PROTOCOL    EndDevPath;
+} FV_MEMMAP_DEVICE_PATH;
+
+typedef struct {
+  UINTN                                   Signature;
+  EFI_DEVICE_PATH_PROTOCOL                *DevicePath;
+  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL      FvbInstance;
+  EFI_SMM_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *SmmFvbInstance;
+} EFI_FVB_DEVICE;
+
+/**
+  This function retrieves the attributes and current settings of the block.
+
+  @param[in]  This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes
+                         and current settings are returned. Type EFI_FVB_ATTRIBUTES_2
+                         is defined in EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS    The firmware volume attributes were returned.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+     OUT   EFI_FVB_ATTRIBUTES_2                 *Attributes
+  );
+
+
+  /**
+  Sets Volume attributes. No polarity translations are done.
+
+  @param[in]  This        Calling context.
+  @param[out] Attributes  Output buffer which contains attributes.
+
+  @retval     EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN OUT   EFI_FVB_ATTRIBUTES_2                 *Attributes
+  );
+
+
+/**
+  Retrieves the physical address of the device.
+
+  @param[in]  This    A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL.
+  @param[out] Address Output buffer containing the address.
+
+  @retval EFI_SUCCESS The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+     OUT   EFI_PHYSICAL_ADDRESS                *Address
+  );
+
+
+/**
+  Retrieve the size of a logical block.
+
+  @param[in]  This         Calling context.
+  @param[in]  Lba          Indicates which block to return the size for.
+  @param[out] BlockSize    A pointer to a caller allocated UINTN in which
+                           the size of the block is returned.
+  @param[out] NumOfBlocks  A pointer to a caller allocated UINTN in which the
+                           number of consecutive blocks starting with Lba is
+                           returned. All blocks in this range have a size of
+                           BlockSize.
+
+  @retval     EFI_SUCCESS  The function always return successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *This,
+  IN       EFI_LBA                             Lba,
+     OUT   UINTN                               *BlockSize,
+     OUT   UINTN                               *NumOfBlocks
+  );
+
+
+/**
+  Reads data beginning at Lba:Offset from FV. The Read terminates either
+  when *NumBytes of data have been read, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This           Calling context.
+  @param[in]      Lba            Block in which to begin write.
+  @param[in]      Offset         Offset in the block at which to begin write
+  @param[in,out]  NumBytes       On input, indicates the requested write size. On
+                                 output, indicates the actual number of bytes written
+  @param[in]      Buffer         Buffer containing source data for the write.
+
+  @retval EFI_SUCCESS            The firmware volume was read successfully and
+                                 contents are in Buffer
+  @retval EFI_BAD_BUFFER_SIZE    Read attempted across a LBA boundary. On output,
+                                 NumBytes contains the total number of bytes returned
+                                 in Buffer
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the ReadDisabled state
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                 could not be read
+  @retval EFI_INVALID_PARAMETER  NumBytes or Buffer are NULL
+
+**/
+EFI_STATUS
+EFIAPI
+FvbRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN       EFI_LBA                              Lba,
+  IN       UINTN                                Offset,
+  IN OUT   UINTN                                *NumBytes,
+     OUT   UINT8                                *Buffer
+  );
+
+
+/**
+  Writes data beginning at Lba:Offset from FV. The write terminates either
+  when *NumBytes of data have been written, or when a block boundary is
+  reached.  *NumBytes is updated to reflect the actual number of bytes
+  written. The write opertion does not include erase. This routine will
+  attempt to write only the specified bytes. If the writes do not stick,
+  it will return an error.
+
+  @param[in]      This           Calling context.
+  @param[in]      Lba            Block in which to begin write.
+  @param[in]      Offset         Offset in the block at which to begin write.
+  @param[in,out]  NumBytes       On input, indicates the requested write size. On
+                                 output, indicates the actual number of bytes written
+  @param[in]      Buffer         Buffer containing source data for the write.
+
+  @retval EFI_SUCCESS            The firmware volume was written successfully
+  @retval EFI_BAD_BUFFER_SIZE    Write attempted across a LBA boundary. On output,
+                                 NumBytes contains the total number of bytes
+                                 actually written.
+  @retval EFI_ACCESS_DENIED      The firmware volume is in the WriteDisabled state
+  @retval EFI_DEVICE_ERROR       The block device is not functioning correctly and
+                                 could not be written.
+  @retval EFI_INVALID_PARAMETER  NumBytes or Buffer are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL   *This,
+  IN       EFI_LBA                              Lba,
+  IN       UINTN                                Offset,
+  IN OUT   UINTN                                *NumBytes,
+  IN       UINT8                                *Buffer
+  );
+
+
+/**
+  The EraseBlock() function erases one or more blocks as denoted by the
+  variable argument list. The entire parameter list of blocks must be verified
+  prior to erasing any blocks.  If a block is requested that does not exist
+  within the associated firmware volume (it has a larger index than the last
+  block of the firmware volume), the EraseBlock() function must return
+  EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+  @param[in] This         Calling context.
+  @param[in] ...          Starting LBA followed by Number of Lba to erase.
+                          a -1 to terminate the list.
+
+  @retval EFI_SUCCESS       The erase request was successfully completed.
+  @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state
+  @retval EFI_DEVICE_ERROR  The block device is not functioning correctly and
+                            could not be written. Firmware device may have been
+                            partially erased.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL    *This,
+  ...
+  );
+
+#endif

+ 50 - 0
Platform/Intel/Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmmDxe.inf

@@ -0,0 +1,50 @@
+## @file
+# Component description file for Firmware Volume Block module.
+#
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+#                                                                                  

+# SPDX-License-Identifier: BSD-2-Clause-Patent
+
+#                                                                                  

+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FvbSmmDxe
+  FILE_GUID                      = 9E8AD3F4-383D-4ec3-816E-7A4749371290
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FvbSmmDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FvbSmmDxe.c
+  FvbSmmDxe.h
+  FvbSmmCommon.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiBootServicesTableLib
+  DebugLib
+  DxeServicesTableLib
+  UefiDriverEntryPoint
+  PcdLib
+
+[Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid           ## ALWAYS_PRODUCES
+  gEfiSmmCommunicationProtocolGuid
+  gEfiSmmFirmwareVolumeBlockProtocolGuid
+
+[Depex]
+  gEfiSmmCommunicationProtocolGuid

BIN
Platform/Intel/Vlv2TbltDevicePkg/GenBiosId


BIN
Platform/Intel/Vlv2TbltDevicePkg/GenBiosId.exe


+ 122 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/AlertStandardFormatTable.h

@@ -0,0 +1,122 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  AlertStandardFormatTable.h
+
+Abstract:
+
+  ACPI Alert Standard Format Description Table ASF! as described
+  in the ASF2.0 Specification
+
+--*/
+
+#ifndef _ALERT_STANDARD_FORMAT_TABLE_H
+#define _ALERT_STANDARD_FORMAT_TABLE_H
+
+#include <IndustryStandard/Acpi20.h>
+
+//
+// Ensure proper structure formats.
+//
+#pragma pack (1)
+
+//
+// Information Record header that appears at the beginning of each record.
+//
+typedef struct {
+  UINT8                                Type;
+  UINT8                                Reserved;
+  UINT16                               RecordLength;
+} EFI_ACPI_ASF_RECORD_HEADER;
+
+//
+// This structure contains information that identifies the system type
+// and configuration.
+//
+typedef struct {
+  EFI_ACPI_ASF_RECORD_HEADER           RecordHeader;
+  UINT8                                MinWatchDogResetValue;
+  UINT8                                MinPollingInterval;
+  UINT16                               SystemID;
+  UINT32                               IANAManufactureID;
+  UINT8                                FeatureFlags;
+  UINT8                                Reserved[3];
+} EFI_ACPI_ASF_INFO;
+
+//
+// Alert sensors definition.
+//
+#define ASF_ALRT_SENSOR_ARRAY_LENGTH     36
+
+typedef struct {
+  EFI_ACPI_ASF_RECORD_HEADER           RecordHeader;
+  UINT8                                AssertionEventBitMask;
+  UINT8                                DeassertionEventBitMask;
+  UINT8                                NumberOfAlerts;
+  UINT8                                ArrayElementLength;
+  UINT8                                DeviceArray[ASF_ALRT_SENSOR_ARRAY_LENGTH];
+} EFI_ACPI_ASF_ALRT;
+
+//
+// Alert Remote Control System Actions.
+//
+#define ASF_RCTL_DEVICES_ARRAY_LENGTH      16
+
+typedef struct {
+  EFI_ACPI_ASF_RECORD_HEADER           RecordHeader;
+  UINT8                                NumberOfControls;
+  UINT8                                ArrayElementLength;
+  UINT16                               RctlReserved;
+  UINT8                                ControlArray[ASF_RCTL_DEVICES_ARRAY_LENGTH];
+} EFI_ACPI_ASF_RCTL;
+
+//
+// Remote Control Capabilities.
+//
+typedef struct {
+  EFI_ACPI_ASF_RECORD_HEADER           RecordHeader;
+  UINT8                                RemoteControlCapabilities[7];
+  UINT8                                RMCPCompletionCode;
+  UINT32                               RMCPIANA;
+  UINT8                                RMCPSpecialCommand;
+  UINT8                                RMCPSpecialCommandParameter[2];
+  UINT8                                RMCPBootOptions[2];
+  UINT8                                RMCPOEMParameters[2];
+} EFI_ACPI_ASF_RMCP;
+
+//
+// SMBus Devices with fixed addresses.
+//
+#define ASF_ADDR_DEVICE_ARRAY_LENGTH      16
+
+typedef struct {
+  EFI_ACPI_ASF_RECORD_HEADER           RecordHeader;
+  UINT8                                SEEPROMAddress;
+  UINT8                                NumberOfDevices;
+  UINT8                                FixedSmbusAddresses[ASF_ADDR_DEVICE_ARRAY_LENGTH];
+} EFI_ACPI_ASF_ADDR;
+
+typedef struct {
+  EFI_ACPI_DESCRIPTION_HEADER          Header;
+  EFI_ACPI_ASF_INFO                    AsfInfo;
+  EFI_ACPI_ASF_ALRT                    AsfAlert;
+  EFI_ACPI_ASF_RCTL                    AsfRctl;
+  EFI_ACPI_ASF_RMCP                    AsfRmcp;
+  EFI_ACPI_ASF_ADDR                    AsfAddr;
+} EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE;
+
+//
+// "ASF!" ASF Description Table Signature.
+//
+#define EFI_ACPI_1_0_ASF_DESCRIPTION_TABLE_SIGNATURE  0x21465341
+
+#pragma pack ()
+
+#endif // _ALERT_STANDARD_FORMAT_TABLE_H

+ 28 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/ChipsetAccess.h

@@ -0,0 +1,28 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+  ChipsetAccess.h
+
+Abstract:
+
+  Common Include file for Platform Drivers to access the Chipset registers.
+
+--*/
+
+#ifndef _CHIPSET_ACCESS_H_
+#define _CHIPSET_ACCESS_H_
+
+#include "PchAccess.h"
+#include "Valleyview.h"
+#include "VlvAccess.h"
+#include "VlvCommonDefinitions.h"
+
+#endif

+ 115 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/CommonIncludes.h

@@ -0,0 +1,115 @@
+/**
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+@file
+  CommonIncludes.h
+
+@brief
+  This file defines common equates.
+
+**/
+#ifndef _COMMON_INCLUDES_H_
+#define _COMMON_INCLUDES_H_
+
+#define V_INTEL_VID 0x8086
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND  1
+#endif
+#ifndef STALL_ONE_MILLI_SECOND
+#define STALL_ONE_MILLI_SECOND  1000
+#endif
+///
+/// Min Max
+///
+#define V_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define V_MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+///
+/// Bit map macro
+///
+#ifndef BIT0
+
+#define BIT63 0x8000000000000000
+#define BIT62 0x4000000000000000
+#define BIT61 0x2000000000000000
+#define BIT60 0x1000000000000000
+#define BIT59 0x0800000000000000
+#define BIT58 0x0400000000000000
+#define BIT57 0x0200000000000000
+#define BIT56 0x0100000000000000
+#define BIT55 0x0080000000000000
+#define BIT54 0x0040000000000000
+#define BIT53 0x0020000000000000
+#define BIT52 0x0010000000000000
+#define BIT51 0x0008000000000000
+#define BIT50 0x0004000000000000
+#define BIT49 0x0002000000000000
+#define BIT48 0x0001000000000000
+#define BIT47 0x0000800000000000
+#define BIT46 0x0000400000000000
+#define BIT45 0x0000200000000000
+#define BIT44 0x0000100000000000
+#define BIT43 0x0000080000000000
+#define BIT42 0x0000040000000000
+#define BIT41 0x0000020000000000
+#define BIT40 0x0000010000000000
+#define BIT39 0x0000008000000000
+#define BIT38 0x0000004000000000
+#define BIT37 0x0000002000000000
+#define BIT36 0x0000001000000000
+#define BIT35 0x0000000800000000
+#define BIT34 0x0000000400000000
+#define BIT33 0x0000000200000000
+#define BIT32 0x0000000100000000
+
+#define BIT31 0x80000000
+#define BIT30 0x40000000
+#define BIT29 0x20000000
+#define BIT28 0x10000000
+#define BIT27 0x08000000
+#define BIT26 0x04000000
+#define BIT25 0x02000000
+#define BIT24 0x01000000
+#define BIT23 0x00800000
+#define BIT22 0x00400000
+#define BIT21 0x00200000
+#define BIT20 0x00100000
+#define BIT19 0x00080000
+#define BIT18 0x00040000
+#define BIT17 0x00020000
+#define BIT16 0x00010000
+#define BIT15 0x00008000
+#define BIT14 0x00004000
+#define BIT13 0x00002000
+#define BIT12 0x00001000
+#define BIT11 0x00000800
+#define BIT10 0x00000400
+#define BIT9  0x00000200
+#define BIT8  0x00000100
+#define BIT7  0x00000080
+#define BIT6  0x00000040
+#define BIT5  0x00000020
+#define BIT4  0x00000010
+#define BIT3  0x00000008
+#define BIT2  0x00000004
+#define BIT1  0x00000002
+#define BIT0  0x00000001
+#endif
+
+#define BITS(x) (1 << (x))
+
+//
+// Notes :
+// 1.  Bit position always starts at 0.
+// 2.  Following macros are applicable only for Word alligned integers.
+//
+#define BIT(Pos, Value)               (1 << (Pos) & (Value))
+#define BITRANGE(From, Width, Value)  (((Value) >> (From)) & ((1 << (Width)) - 1))
+
+#endif

+ 59 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/CpuType.h

@@ -0,0 +1,59 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  CpuType.h
+
+Abstract:
+
+--*/
+
+#ifndef _CPU_TYPE_H
+#define _CPU_TYPE_H
+
+#pragma pack(1)
+
+typedef enum {
+  EnumCpuUarchUnknown = 0,
+  EnumNehalemUarch,
+} EFI_CPU_UARCH;
+
+typedef enum {
+  EnumCpuPlatformUnknown = 0,
+  EnumDesktop,
+  EnumMobile,
+  EnumServer,
+  EnumNetTop
+} EFI_CPU_PLATFORM;
+
+typedef enum {
+  EnumCpuTypeUnknown = 0,
+  EnumAtom,
+  EnumNehalemEx,
+  EnumBloomfield,
+  EnumGainestown,
+  EnumHavendale,
+  EnumLynnfield,
+  EnumAuburndale,
+  EnumClarksfield,
+  EnumPineview,
+  EnumCedarview,
+  EnumValleyview,
+  EnumClarkdale // Havendale 32nm
+} EFI_CPU_TYPE;
+
+typedef enum {
+  EnumCpuFamilyUnknown = 0,
+  EnumFamilyField,
+  EnumFamilyDale
+} EFI_CPU_FAMILY;
+
+#pragma pack()
+
+#endif

+ 499 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/FileHandleLib.h

@@ -0,0 +1,499 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+**/
+
+#ifndef _FILE_HANDLE_LIBRARY_HEADER_
+#define _FILE_HANDLE_LIBRARY_HEADER_
+
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// The tag for use in identifying UNICODE files.
+// If the file is UNICODE, the first 16 bits of the file will equal this value.
+//
+extern CONST UINT16 gUnicodeFileTag;
+
+/**
+  This function retrieves information about the file for the handle
+  specified and stores it in the allocated pool memory.
+
+  This function allocates a buffer to store the file's information. It is the
+  caller's responsibility to free the buffer.
+
+  @param[in] FileHandle         The file handle of the file for which information is
+                                being requested.
+
+  @retval NULL                  Information could not be retrieved.
+  @retval !NULL                 The information about the file.
+**/
+EFI_FILE_INFO*
+EFIAPI
+FileHandleGetInfo (
+  IN EFI_FILE_HANDLE            FileHandle
+  );
+
+/**
+  This function sets the information about the file for the opened handle
+  specified.
+
+  @param[in]  FileHandle        The file handle of the file for which information
+                                is being set.
+
+  @param[in]  FileInfo          The information to set.
+
+  @retval EFI_SUCCESS           The information was set.
+  @retval EFI_INVALID_PARAMETER A parameter was out of range or invalid.
+  @retval EFI_UNSUPPORTED       The FileHandle does not support FileInfo.
+  @retval EFI_NO_MEDIA          The device has no medium.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
+  @retval EFI_ACCESS_DENIED     The file was opened read only.
+  @retval EFI_VOLUME_FULL       The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetInfo (
+  IN EFI_FILE_HANDLE            FileHandle,
+  IN CONST EFI_FILE_INFO        *FileInfo
+  );
+
+/**
+  This function reads information from an opened file.
+
+  If FileHandle is not a directory, the function reads the requested number of
+  bytes from the file at the file's current position and returns them in Buffer.
+  If the read goes beyond the end of the file, the read length is truncated to the
+  end of the file. The file's current position is increased by the number of bytes
+  returned.  If FileHandle is a directory, the function reads the directory entry
+  at the file's current position and returns the entry in Buffer. If the Buffer
+  is not large enough to hold the current directory entry, then
+  EFI_BUFFER_TOO_SMALL is returned and the current file position is not updated.
+  BufferSize is set to be the size of the buffer needed to read the entry. On
+  success, the current position is updated to the next directory entry. If there
+  are no more directory entries, the read returns a zero-length buffer.
+  EFI_FILE_INFO is the structure returned as the directory entry.
+
+  @param[in] FileHandle          The opened file handle.
+  @param[in, out] BufferSize     On input, the size of buffer in bytes.  On return,
+                                 the number of bytes written.
+  @param[out] Buffer             The buffer to put read data into.
+
+  @retval EFI_SUCCESS            Data was read.
+  @retval EFI_NO_MEDIA           The device has no media.
+  @retval EFI_DEVICE_ERROR       The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED   The file system structures are corrupted.
+  @retval EFI_BUFFER_TO_SMALL    Buffer is too small. ReadSize contains required
+                                 size.
+
+**/
+EFI_STATUS
+EFIAPI
+FileHandleRead(
+  IN EFI_FILE_HANDLE            FileHandle,
+  IN OUT UINTN                  *BufferSize,
+  OUT VOID                      *Buffer
+  );
+
+/**
+  Write data to a file.
+
+  This function writes the specified number of bytes to the file at the current
+  file position. The current file position is advanced the actual number of bytes
+  written, which is returned in BufferSize. Partial writes only occur when there
+  has been a data error during the write attempt (such as "volume space full").
+  The file is automatically grown to hold the data if required. Direct writes to
+  opened directories are not supported.
+
+  @param[in] FileHandle         The opened file for writing.
+  @param[in, out] BufferSize    On input, the number of bytes in Buffer.  On output,
+                                the number of bytes written.
+  @param[in] Buffer             The buffer containing data to write is stored.
+
+  @retval EFI_SUCCESS           Data was written.
+  @retval EFI_UNSUPPORTED       Writes to an open directory are not supported.
+  @retval EFI_NO_MEDIA          The device has no media.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED   The device is write-protected.
+  @retval EFI_ACCESS_DENIED     The file was opened for read only.
+  @retval EFI_VOLUME_FULL       The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleWrite(
+  IN EFI_FILE_HANDLE            FileHandle,
+  IN OUT UINTN                  *BufferSize,
+  IN VOID                       *Buffer
+  );
+
+/**
+  Close an open file handle.
+
+  This function closes a specified file handle. All "dirty" cached file data is
+  flushed to the device, and the file is closed. In all cases the handle is
+  closed.
+
+  @param[in] FileHandle           The file handle to close.
+
+  @retval EFI_SUCCESS             The file handle was closed successfully.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleClose (
+  IN EFI_FILE_HANDLE            FileHandle
+  );
+
+/**
+  Delete a file and close the handle.
+
+  This function closes and deletes a file. In all cases the file handle is closed.
+  If the file cannot be deleted, the warning code EFI_WARN_DELETE_FAILURE is
+  returned, but the handle is still closed.
+
+  @param[in] FileHandle             The file handle to delete.
+
+  @retval EFI_SUCCESS               The file was closed successfully.
+  @retval EFI_WARN_DELETE_FAILURE   The handle was closed, but the file was not
+                                    deleted.
+  @retval INVALID_PARAMETER         One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleDelete (
+  IN EFI_FILE_HANDLE    FileHandle
+  );
+
+/**
+  Set the current position in a file.
+
+  This function sets the current file position for the handle to the position
+  supplied. With the exception of moving to position 0xFFFFFFFFFFFFFFFF, only
+  absolute positioning is supported, and moving past the end of the file is
+  allowed (a subsequent write would grow the file). Moving to position
+  0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file.
+  If FileHandle is a directory, the only position that may be set is zero. This
+  has the effect of starting the read process of the directory entries over again.
+
+  @param[in] FileHandle         The file handle on which the position is being set.
+  @param[in] Position           The byte position from the begining of the file.
+
+  @retval EFI_SUCCESS           The operation completed sucessfully.
+  @retval EFI_UNSUPPORTED       The request for non-zero is not valid on
+                                directories.
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetPosition (
+  IN EFI_FILE_HANDLE    FileHandle,
+  IN UINT64             Position
+  );
+
+/**
+  Gets a file's current position.
+
+  This function retrieves the current file position for the file handle. For
+  directories, the current file position has no meaning outside of the file
+  system driver. As such, the operation is not supported. An error is returned
+  if FileHandle is a directory.
+
+  @param[in] FileHandle         The open file handle on which to get the position.
+  @param[out] Position          The byte position from begining of file.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval INVALID_PARAMETER     One of the parameters has an invalid value.
+  @retval EFI_UNSUPPORTED       The request is not valid on directories.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetPosition (
+  IN EFI_FILE_HANDLE            FileHandle,
+  OUT UINT64                    *Position
+  );
+
+/**
+  Flushes data on a file.
+
+  This function flushes all modified data associated with a file to a device.
+
+  @param[in] FileHandle         The file handle on which to flush data.
+
+  @retval EFI_SUCCESS           The data was flushed.
+  @retval EFI_NO_MEDIA          The device has no media.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+  @retval EFI_WRITE_PROTECTED   The file or medium is write protected.
+  @retval EFI_ACCESS_DENIED     The file was opened for read only.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFlush (
+  IN EFI_FILE_HANDLE            FileHandle
+  );
+
+/**
+  Function to determine if a given handle is a directory handle.
+
+  If DirHandle is NULL, then ASSERT().
+
+  Open the file information on the DirHandle, and verify that the Attribute
+  includes EFI_FILE_DIRECTORY bit set.
+
+  @param[in] DirHandle           The handle to open the file.
+
+  @retval EFI_SUCCESS            DirHandle is a directory.
+  @retval EFI_INVALID_PARAMETER  DirHandle did not have EFI_FILE_INFO available.
+  @retval EFI_NOT_FOUND          DirHandle is not a directory.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleIsDirectory (
+  IN EFI_FILE_HANDLE            DirHandle
+  );
+
+/**
+  Retrieve first entry from a directory.
+
+  This function takes an open directory handle and gets information from the
+  first entry in the directory.  A buffer is allocated to contain
+  the information and a pointer to the buffer is returned in *Buffer.  The
+  caller can use FileHandleFindNextFile() to get subsequent directory entries.
+
+  The buffer will be freed by FileHandleFindNextFile() when the last directory
+  entry is read.  Otherwise, the caller must free the buffer, using FreePool,
+  when finished with it.
+
+  @param[in]  DirHandle         The file handle of the directory to search.
+  @param[out] Buffer            The pointer to pointer to buffer for file's information.
+
+  @retval EFI_SUCCESS           Found the first file.
+  @retval EFI_NOT_FOUND         Cannot find the directory.
+  @retval EFI_NO_MEDIA          The device has no media.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+  @return Others                The status of FileHandleGetInfo, FileHandleSetPosition,
+                                or FileHandleRead.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindFirstFile (
+  IN EFI_FILE_HANDLE            DirHandle,
+  OUT EFI_FILE_INFO             **Buffer
+  );
+
+/**
+  Retrieve next entries from a directory.
+
+  To use this function, the caller must first call the FileHandleFindFirstFile()
+  function to get the first directory entry.  Subsequent directory entries are
+  retrieved by using the FileHandleFindNextFile() function.  This function can
+  be called several times to get each entry from the directory.  If the call of
+  FileHandleFindNextFile() retrieved the last directory entry, the next call of
+  this function will set *NoFile to TRUE and free the buffer.
+
+  @param[in]  DirHandle         The file handle of the directory.
+  @param[out] Buffer            The pointer to buffer for file's information.
+  @param[out] NoFile            The pointer to boolean when last file is found.
+
+  @retval EFI_SUCCESS           Found the next file, or reached last file.
+  @retval EFI_NO_MEDIA          The device has no media.
+  @retval EFI_DEVICE_ERROR      The device reported an error.
+  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleFindNextFile(
+  IN EFI_FILE_HANDLE             DirHandle,
+  OUT EFI_FILE_INFO              *Buffer,
+  OUT BOOLEAN                    *NoFile
+  );
+
+/**
+  Retrieve the size of a file.
+
+  If FileHandle is NULL then ASSERT().
+  If Size is NULL then ASSERT().
+
+  This function extracts the file size info from the FileHandle's EFI_FILE_INFO
+  data.
+
+  @param[in] FileHandle         The file handle from which size is retrieved.
+  @param[out] Size              The pointer to size.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_DEVICE_ERROR      Cannot access the file.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetSize (
+  IN EFI_FILE_HANDLE            FileHandle,
+  OUT UINT64                    *Size
+  );
+
+/**
+  Set the size of a file.
+
+  If FileHandle is NULL then ASSERT().
+
+  This function changes the file size info from the FileHandle's EFI_FILE_INFO
+  data.
+
+  @param[in] FileHandle         The file handle whose size is to be changed.
+  @param[in] Size               The new size.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_DEVICE_ERROR      Cannot access the file.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleSetSize (
+  IN EFI_FILE_HANDLE            FileHandle,
+  IN UINT64                     Size
+  );
+
+/**
+  Function to get a full filename given a EFI_FILE_HANDLE somewhere lower on the
+  directory 'stack'.
+
+  @param[in] Handle              Handle to the Directory or File to create path to.
+  @param[out] FullFileName       Pointer to pointer to generated full file name.  It
+                                 is the responsibility of the caller to free this memory
+                                 with a call to FreePool().
+  @retval EFI_SUCCESS            The operation was successful and FullFileName is valid.
+  @retval EFI_INVALID_PARAMETER  Handle was NULL.
+  @retval EFI_INVALID_PARAMETER  FullFileName was NULL.
+  @retval EFI_OUT_OF_MEMORY      A memory allocation failed.
+**/
+EFI_STATUS
+EFIAPI
+FileHandleGetFileName (
+  IN CONST EFI_FILE_HANDLE      Handle,
+  OUT CHAR16                    **FullFileName
+  );
+
+/**
+  Function to read a single line (up to but not including the \n) from a file.
+
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
+  maintained and not changed for all operations with the same file.
+
+  @param[in]       Handle         FileHandle to read from.
+  @param[in, out]  Buffer         The pointer to buffer to read into.
+  @param[in, out]  Size           The pointer to number of bytes in Buffer.
+  @param[in]       Truncate       If the buffer is large enough, this has no effect.
+                                  If the buffer is is too small and Truncate is TRUE,
+                                  the line will be truncated.
+                                  If the buffer is is too small and Truncate is FALSE,
+                                  then no read will occur.
+
+  @param[in, out]  Ascii          Boolean value for indicating whether the file is
+                                  Ascii (TRUE) or UCS2 (FALSE).
+
+  @retval EFI_SUCCESS            The operation was successful.  The line is stored in
+                                 Buffer.
+  @retval EFI_INVALID_PARAMETER  Handle was NULL.
+  @retval EFI_INVALID_PARAMETER  Size was NULL.
+  @retval EFI_BUFFER_TOO_SMALL   Size was not large enough to store the line.
+                                 Size was updated to the minimum space required.
+  @sa FileHandleRead
+**/
+EFI_STATUS
+EFIAPI
+FileHandleReadLine(
+  IN EFI_FILE_HANDLE            Handle,
+  IN OUT CHAR16                 *Buffer,
+  IN OUT UINTN                  *Size,
+  IN BOOLEAN                    Truncate,
+  IN OUT BOOLEAN                *Ascii
+  );
+
+/**
+  Function to read a single line from a file. The \n is not included in the returned
+  buffer.  The returned buffer must be callee freed.
+
+  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
+  maintained and not changed for all operations with the same file.
+
+  @param[in]       Handle        FileHandle to read from.
+  @param[in, out]  Ascii         Boolean value for indicating whether the file is
+                                 Ascii (TRUE) or UCS2 (FALSE).
+
+  @return                        The line of text from the file.
+
+  @sa FileHandleReadLine
+**/
+CHAR16*
+EFIAPI
+FileHandleReturnLine(
+  IN EFI_FILE_HANDLE            Handle,
+  IN OUT BOOLEAN                *Ascii
+  );
+
+/**
+  Function to write a line of unicode text to a file.
+
+  If Handle is NULL, ASSERT.
+
+  @param[in]     Handle         FileHandle to write to.
+  @param[in]     Buffer         Buffer to write, if NULL the function will
+                                take no action and return EFI_SUCCESS.
+
+  @retval  EFI_SUCCESS          The data was written.
+  @retval  other                Failure.
+
+  @sa FileHandleWrite
+**/
+EFI_STATUS
+EFIAPI
+FileHandleWriteLine(
+  IN EFI_FILE_HANDLE Handle,
+  IN CHAR16          *Buffer
+  );
+
+/**
+  Function to take a formatted argument and print it to a file.
+
+  @param[in] Handle   The file handle for the file to write to.
+  @param[in] Format   The format argument (see printlib for the format specifier).
+  @param[in] ...      The variable arguments for the format.
+
+  @retval EFI_SUCCESS The operation was successful.
+  @retval other       A return value from FileHandleWriteLine.
+
+  @sa FileHandleWriteLine
+**/
+EFI_STATUS
+EFIAPI
+FileHandlePrintLine(
+  IN EFI_FILE_HANDLE  Handle,
+  IN CONST CHAR16     *Format,
+  ...
+  );
+
+/**
+  Function to determine if a FILE_HANDLE is at the end of the file.
+
+  This will NOT work on directories.
+
+  If Handle is NULL, then ASSERT().
+
+  @param[in] Handle     The file handle.
+
+  @retval TRUE          The position is at the end of the file.
+  @retval FALSE         The position is not at the end of the file.
+**/
+BOOLEAN
+EFIAPI
+FileHandleEof(
+  IN EFI_FILE_HANDLE Handle
+  );
+
+#endif //_FILE_HANDLE_LIBRARY_HEADER_
+

+ 30 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AcpiTableStorage.h

@@ -0,0 +1,30 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+  AcpiTableStorage.h
+
+Abstract:
+
+  GUID for the ACPI Table Storage filename.
+
+  This GUID is defined in the Tiano ACPI Table Storage EPS.
+
+--*/
+
+#ifndef _ACPI_TABLE_STORAGE_H_
+#define _ACPI_TABLE_STORAGE_H_
+
+#define EFI_ACPI_TABLE_STORAGE_GUID \
+  { 0x7e374e25, 0x8e01, 0x4fee, {0x87, 0xf2, 0x39, 0xc, 0x23, 0xc6, 0x6, 0xcd} }
+
+extern EFI_GUID gEfiAcpiTableStorageGuid;
+
+#endif

+ 86 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/AlertStandardFormat.h

@@ -0,0 +1,86 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+Module Name:
+
+  Asf.h
+
+Abstract:
+
+  Alert Standard Format address variable
+
+--*/
+
+#ifndef AlertStandardFormat_h_included
+#define AlertStandardFormat_h_included
+
+
+#pragma pack(1)
+
+//
+// ASF address
+//
+//
+// {3D995FB4-4F05-4073-BE72-A19CFB5DE690}
+//
+#define  ALERT_STANDARD_FORMAT_VARIABLE_GUID \
+  {0x3d995fb4, 0x4f05, 0x4073, 0xbe, 0x72, 0xa1, 0x9c, 0xfb, 0x5d, 0xe6, 0x90}
+
+#define ALERT_STANDARD_FORMAT_VARIABLE_NAME (L"ASF")
+#define ASCII_ALERT_STANDARD_FORMAT_VARIABLE_NAME ("ASF")
+
+extern EFI_GUID gAlertStandardFormatGuid;
+extern CHAR16   gAlertStandardFormatName[];
+
+typedef struct {
+  UINT8   SmbusAddr;
+  struct {
+    UINT32  VendorSpecificId;
+    UINT16  SubsystemDeviceId;
+    UINT16  SubsystemVendorId;
+    UINT16  Interface;
+    UINT16  DeviceId;
+    UINT16  VendorId;
+    UINT8   VendorRevision;
+    UINT8   DeviceCapabilities;
+  } Udid;
+  struct {
+    UINT8     SubCommand;
+    UINT8     Version;
+    UINT32    IanaId;
+    UINT8     SpecialCommand;
+    UINT16    SpecialCommandParam;
+    UINT16    BootOptionsBits;
+    UINT16    OemParam;
+  } AsfBootOptions;
+  struct {
+    UINT8     Bus;
+    UINT8     Device;
+    UINT8     Function;
+    UINT16    VendorId;
+    UINT16    DeviceId;
+    UINT16    IderCmdBar;
+    UINT16    IderCtrlBar;
+    UINT8     IderIrq;
+    UINT16    SolBar;
+    UINT8     SolIrq;
+  } PciInfo;
+  struct {
+  UINT8   IamtProvisioningStatus;
+  BOOLEAN IamtIsProvisioned;
+  } IamtInfo;
+  struct {
+    BOOLEAN FlashUpdatingIsAllowed;
+  } MeInfoForEbu;
+  UINT32  EitBPFAddress;
+} EFI_ASF_VARIABLE;
+
+#pragma pack()
+
+#endif
+

+ 30 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BiosId.h

@@ -0,0 +1,30 @@
+/*++
+
+Copyright (c)  1999  - 2014, Intel Corporation. All rights reserved
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+    BiosId.h
+
+Abstract:
+
+    GUIDs used for Bios ID.
+
+--*/
+
+#ifndef _BIOS_ID_H_
+#define _BIOS_ID_H_
+
+
+#define EFI_BIOS_ID_GUID \
+{ 0xC3E36D09, 0x8294, 0x4b97, 0xA8, 0x57, 0xD5, 0x28, 0x8F, 0xE3, 0x3E, 0x28 }
+
+
+extern EFI_GUID gEfiBiosIdGuid;
+
+#endif

+ 214 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/BoardFeatures.h

@@ -0,0 +1,214 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+    BoardFeatures.h
+
+Abstract:
+
+    EFI Platform Board Features
+
+
+
+--*/
+
+#ifndef BoardFeatures_h_included
+#define BoardFeatures_h_included
+
+#include <Base.h>
+
+#pragma pack(1)
+
+//
+// Board Features
+//
+#if defined LEGACY_BOARD_FEATURES && LEGACY_BOARD_FEATURES
+#define B_BOARD_FEATURES_CHIPSET_LAN           BIT0
+#define B_BOARD_FEATURES_LAN_MARVELL           BIT1
+#define B_BOARD_FEATURES_AA_NOT_FOUND           BIT2
+#define B_BOARD_FEATURES_SIO_NO_COM1           BIT3
+#define B_BOARD_FEATURES_SIO_COM2              BIT4
+#define B_BOARD_FEATURES_SIO_NO_PARALLEL       BIT5
+#define B_BOARD_FEATURES_CHIPSET_VIDEO         BIT6
+#define B_BOARD_FEATURES_CHIPSET_VIDEO_OPTION0 BIT7
+#define B_BOARD_FEATURES_VIDEO_SLOT            BIT8
+#define B_BOARD_FEATURES_MINI_CARD             BIT9
+#define B_BOARD_FEATURES_DISCRETE_1394         BIT10
+#define B_BOARD_FEATURES_LEGACY_FREE           BIT11
+#define B_BOARD_FEATURES_USB_HUB               BIT12
+#define B_BOARD_FEATURES_TPM                   BIT13
+#define B_BOARD_FEATURES_VIIV                   BIT14
+#define B_BOARD_FEATURES_FORM_FACTOR_MASK      (BIT15|BIT16|BIT17|BIT18|BIT19)
+#define B_BOARD_FEATURES_FORM_FACTOR_PBTX      BIT15
+#define B_BOARD_FEATURES_FORM_FACTOR_ATX       BIT16
+#define B_BOARD_FEATURES_FORM_FACTOR_BTX       BIT17
+#define B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX BIT18
+#define B_BOARD_FEATURES_FORM_FACTOR_MICRO_BTX BIT19
+#define B_BOARD_FEATURES_MEMORY_TYPE_DDR1      BIT20
+#define B_BOARD_FEATURES_MEMORY_TYPE_DDR2      BIT21
+#define B_BOARD_FEATURES_MEMORY_SLOT_MASK      BIT23 | BIT22
+#define   V_BOARD_FEATURES_1_MEMORY_SLOT         0              // BIT22=0, BIT23=0
+#define   V_BOARD_FEATURES_2_MEMORY_SLOT         BIT22          // BIT22=1, BIT23=0
+#define   V_BOARD_FEATURES_3_MEMORY_SLOT         BIT23          // BIT22=0, BIT23=1
+#define   V_BOARD_FEATURES_4_MEMORY_SLOT         BIT23 | BIT22  // BIT22=1, BIT23=1
+#define B_BOARD_FEATURES_ALT_MEM_CLK_RT         BIT24
+#define B_BOARD_FEATURES_SLEEP_MASK            BIT25
+#define   V_BOARD_FEATURES_SLEEP_S1              0              // BIT25=0
+#define   V_BOARD_FEATURES_SLEEP_S3              BIT25          // BIT25=1
+#define B_BOARD_FEATURES_3JACK_AUDIO_SOLUTION    BIT26          // 0/1= 5/3 Rear Jacks
+#define B_BOARD_FEATURES_DISCRETE_SATA         BIT27
+#define B_BOARD_FEATURES_2_SATA               BIT28    // 2SATA instead of 4(pre Ich8) or 4 SATA instead of 6(Ich8)
+#define B_BOARD_FEATURES_RVP                  BIT29    // Board is an RVP board
+#define B_BOARD_FEATURES_PORT80_LPC           BIT30    // Port80 PCI(0) or LPC(1)
+#define B_BOARD_FEATURES_LIMITED_CPU_SUPPORT  BIT31    // Limited CPU support
+#define B_BOARD_FEATURES_PMP_SUPPORT          BIT32    // Support for over-voltaging memory
+#define B_BOARD_FEATURES_HW_WATCHDOG_TIMER    BIT33    // Support for the HW-based 555 Watchdog Timer feature
+#define B_BOARD_FEATURES_NO_QRT               BIT34    // disable QRT
+#define B_BOARD_FEATURES_VERB_TABLE1          BIT35    // Verb table 1
+#define B_BOARD_FEATURES_VERB_TABLE2          BIT36    // Verb table 2
+#define B_BOARD_FEATURES_VERB_TABLE3          BIT37    // Verb table 3
+#define B_BOARD_FEATURES_VERB_TABLE4          BIT38    // Verb table 4
+#define B_BOARD_FEATURES_VERB_TABLE5          BIT39    // Reserved for Verb table 5
+#define B_BOARD_FEATURES_VERB_TABLE_MASK      BIT35 | BIT36 | BIT37 | BIT38 | BIT39
+#define B_BOARD_FEATURES_KENTSFIELD_BLOCK     BIT40    // Kentsfield not supported
+#define B_BOARD_FEATURES_KENTSFIELD_WARNING   BIT41    // Kentsfield warning
+#define B_BOARD_FEATURES_ESATA_PORT0          BIT42    // E-SATA on Port0
+#define B_BOARD_FEATURES_ESATA_PORT1          BIT43    // E-SATA on Port1
+#define B_BOARD_FEATURES_ESATA_PORT2          BIT44    // E-SATA on Port2
+#define B_BOARD_FEATURES_ESATA_PORT3          BIT45    // E-SATA on Port3
+#define B_BOARD_FEATURES_ESATA_PORT4          BIT46    // E-SATA on Port4
+#define B_BOARD_FEATURES_ESATA_PORT5          BIT47    // E-SATA on Port5
+#define B_BOARD_FEATURES_ECIR                 BIT48    // Enhanced Consumer IR
+#define B_BOARD_FEATURES_PS2WAKEFROMS5        BIT49    // Wake from S5 via PS2 keyboard
+#define B_BOARD_FEATURES_HDAUDIOLINK          BIT50    // HD audio link support
+#define B_BOARD_FEATURES_1_PATA               BIT51
+#define B_BOARD_FEATURES_MOBILE               BIT52
+#define B_BOARD_FEATURES_NO_FLOPPY            BIT53
+#define B_BOARD_FEATURES_DISABLE_UNUSED_FSB   BIT54
+
+//
+// Bit 55-58 reserved by PSID support.  CPU power requirement below are preliminary.
+// They might be changed.
+// This is not same as 8.6.1 products so be careful.
+//
+#define B_BOARD_FEATURES_CPU_POWER_BITNUM     55
+#define B_BOARD_FEATURES_CPU_POWER_MASK       (BIT55 | BIT56 | BIT57 | BIT58)
+#define B_BOARD_FEATURES_CPU_POWER_35W        0     // Theoretically doesn't exist.
+#define B_BOARD_FEATURES_CPU_POWER_40W        BIT55 // 0001
+#define B_BOARD_FEATURES_CPU_POWER_45W        BIT56 // 0010
+#define B_BOARD_FEATURES_CPU_POWER_50W        (BIT55 | BIT56) // 0011
+#define B_BOARD_FEATURES_CPU_POWER_65W        BIT57 // 0100 Wolfdale-H/-M
+#define B_BOARD_FEATURES_CPU_POWER_70W        (BIT55 | BIT57) // 0101
+#define B_BOARD_FEATURES_CPU_POWER_75W        (BIT56 | BIT57) // 0110
+#define B_BOARD_FEATURES_CPU_POWER_80W        (BIT55 | BIT56 | BIT57) // 0111
+#define B_BOARD_FEATURES_CPU_POWER_95W        BIT58 // 1000 Yorkfield
+#define B_BOARD_FEATURES_CPU_POWER_100W       (BIT55 | BIT58) // 1001
+#define B_BOARD_FEATURES_CPU_POWER_105W       (BIT56 | BIT58) // 1010
+#define B_BOARD_FEATURES_CPU_POWER_110W       (BIT55 | BIT56 | BIT58) // 1011
+#define B_BOARD_FEATURES_CPU_POWER_130W       (BIT57 | BIT58) // 1100 XE Yorkfield
+#define B_BOARD_FEATURES_CPU_POWER_135W       (BIT55 | BIT57 | BIT58) // 1101
+#define B_BOARD_FEATURES_CPU_POWER_Over135W   (BIT56 | BIT57 | BIT58) // 1110 Reserved
+#define B_BOARD_FEATURES_CPU_POWER_140W       (BIT55 | BIT56 | BIT57 | BIT58) // 1111 Reserved
+#define B_VV_BOARD_FEATURES                    BIT59
+#define B_BOARD_FEATURES_IDCC2_SUPPORT         BIT60 // Include IDCC2 support
+#define B_BOARD_FEATURES_NO_SATA_PORT2_3       BIT61 // No SATA Port2&3 Connector, used with B_BOARD_FEATURES_2_SATA flag
+#define B_BOARD_FEATURES_FORM_FACTOR_MINI_ITX  BIT62
+#define B_BOARD_FEATURES_NPI_QPI_VOLTAGE       BIT63
+
+#else
+
+#define B_BOARD_FEATURES_CHIPSET_LAN              BIT0
+#define B_BOARD_FEATURES_CHIPSET_VIDEO            BIT1
+#define B_BOARD_FEATURES_VIDEO_SLOT               BIT2
+#define B_BOARD_FEATURES_AA_NOT_FOUND             BIT3
+#define B_BOARD_FEATURES_SIO_NO_COM1              BIT4
+#define B_BOARD_FEATURES_SIO_COM2                 BIT5
+#define B_BOARD_FEATURES_SIO_NO_PARALLEL          BIT6
+#define B_BOARD_FEATURES_NO_FLOPPY                BIT7
+#define B_BOARD_FEATURES_PS2WAKEFROMS5            BIT8             // Wake from S5 via PS2 keyboard
+#define B_BOARD_FEATURES_ECIR                     BIT9             // Enhanced Consumer IR
+#define B_BOARD_FEATURES_LEGACY_FREE              BIT10
+#define B_BOARD_FEATURES_MINI_CARD                BIT11
+#define B_BOARD_FEATURES_DISCRETE_1394            BIT12
+#define B_BOARD_FEATURES_USB_HUB                  BIT13
+#define B_BOARD_FEATURES_TPM                      BIT14
+#define B_BOARD_FEATURES_FORM_FACTOR_MASK         (BIT15|BIT16|BIT17|BIT18|BIT19|BIT20)
+#define B_BOARD_FEATURES_FORM_FACTOR_PBTX         BIT15
+#define B_BOARD_FEATURES_FORM_FACTOR_ATX          BIT16
+#define B_BOARD_FEATURES_FORM_FACTOR_BTX          BIT17
+#define B_BOARD_FEATURES_FORM_FACTOR_MICRO_ATX    BIT18
+#define B_BOARD_FEATURES_FORM_FACTOR_MICRO_BTX    BIT19
+#define B_BOARD_FEATURES_FORM_FACTOR_MINI_ITX     BIT20
+#define B_BOARD_FEATURES_MEMORY_TYPE_DDR2         BIT21
+#define B_BOARD_FEATURES_MEMORY_TYPE_DDR3         BIT22
+#define B_BOARD_FEATURES_MEMORY_SLOT_MASK         (BIT24 | BIT23)
+#define   V_BOARD_FEATURES_1_MEMORY_SLOT            0              // BIT23=0, BIT24=0
+#define   V_BOARD_FEATURES_2_MEMORY_SLOT          BIT23            // BIT23=1, BIT24=0
+#define   V_BOARD_FEATURES_3_MEMORY_SLOT          BIT24            // BIT23=0, BIT24=1
+#define   V_BOARD_FEATURES_4_MEMORY_SLOT          (BIT24 | BIT23)  // BIT23=1, BIT24=1
+#define B_BOARD_FEATURES_2_C0_MEMORY_SLOT         BIT25            // 2 Channel 0 memory slot
+#define B_BOARD_FEATURES_SLEEP_MASK               BIT26
+#define   V_BOARD_FEATURES_SLEEP_S1                 0              // BIT26=0
+#define   V_BOARD_FEATURES_SLEEP_S3               BIT26            // BIT26=1
+#define B_BOARD_FEATURES_3JACK_AUDIO_SOLUTION     BIT27            // 0/1= 5/3 Rear Jacks
+#define B_BOARD_FEATURES_HDAUDIOLINK              BIT28            // HD audio link support
+#define B_BOARD_FEATURES_DISCRETE_SATA            BIT29
+#define B_BOARD_FEATURES_2_SATA                   BIT30            // 2SATA instead of 4(pre Ich8) or 4 SATA instead of 6(Ich8)
+#define B_BOARD_FEATURES_NO_SATA_PORT2_3          BIT31            // No SATA Port2&3 Connector, used with B_BOARD_FEATURES_2_SATA flag
+#define B_BOARD_FEATURES_RVP                      BIT32            // Board is an RVP board
+#define B_BOARD_FEATURES_ESATA_PORT0              BIT33            // E-SATA on Port0
+#define B_BOARD_FEATURES_ESATA_PORT1              BIT34            // E-SATA on Port1
+#define B_BOARD_FEATURES_ESATA_PORT2              BIT35            // E-SATA on Port2
+#define B_BOARD_FEATURES_ESATA_PORT3              BIT36            // E-SATA on Port3
+#define B_BOARD_FEATURES_ESATA_PORT4              BIT37            // E-SATA on Port4
+#define B_BOARD_FEATURES_ESATA_PORT5              BIT38            // E-SATA on Port5
+#define B_BOARD_FEATURES_IDCC2_SUPPORT            BIT39            // Include IDCC2 support
+#define B_BOARD_FEATURES_NPI_QPI_VOLTAGE          BIT40
+#define B_BOARD_FEATURES_LIMITED_CPU_SUPPORT      BIT41            // Limited CPU support
+#define B_BOARD_FEATURES_PMP_SUPPORT              BIT42            // Support for over-voltaging memory
+#define B_BOARD_FEATURES_HW_WATCHDOG_TIMER        BIT43            // Support for the HW-based 555 Watchdog Timer feature
+#define B_BOARD_FEATURES_LVDS                     BIT44            // Support for LVDS
+#define B_BOARD_FEATURES_VERB_TABLE_MASK          (BIT45|BIT46|BIT47|BIT48)    // Verb table
+#define B_BOARD_FEATURES_VERB_TABLE1              BIT45            // Verb table 1
+#define B_BOARD_FEATURES_VERB_TABLE2              BIT46            // Verb table 2
+#define B_BOARD_FEATURES_VERB_TABLE3              BIT47            // Verb table 3
+#define B_BOARD_FEATURES_VERB_TABLE4              BIT48            // Verb table 4
+#define B_BOARD_FEATURES_NO_MINIPCIE              BIT49            // Mini PCIe slot
+#define B_BOARD_FEATURES_HDMI_SLOT                BIT50            // HDMI slot
+#define B_BOARD_FEATURES_PS2_HIDE                 BIT51            // PS2 hide
+#define B_BOARD_FEATURES_DVID_SLOT                BIT52            // DVID slot
+
+#define B_BOARD_FEATURES_SIO_COM3                 BIT53
+#define B_BOARD_FEATURES_SIO_COM4                 BIT54
+
+#define B_BOARD_FEATURES_LAN2                     BIT55
+#define B_BOARD_FEATURES_PCIe_SLOT                BIT56
+#endif
+
+typedef UINT64 EFI_BOARD_FEATURES;
+
+#pragma pack()
+
+//
+// Global ID for the Platform Boot Mode Protocol.
+//
+#define EFI_BOARD_FEATURES_GUID \
+  { 0x94b9e8ae, 0x8877, 0x479a, 0x98, 0x42, 0xf5, 0x97, 0x4b, 0x82, 0xce, 0xd3 }
+
+extern EFI_GUID gEfiBoardFeaturesGuid;
+
+#define BOARD_FEATURES_NAME   L"BoardFeatures"
+
+#define EFI_BOARD_ID_GUID \
+  { 0x6b2dd245, 0x3f2, 0x414a, 0x8c, 0x2, 0x9f, 0xfc, 0x23, 0x52, 0xe3, 0x1e }
+#define EFI_BOARD_ID_NAME (L"BoardId")
+
+#endif
+

+ 156 - 0
Platform/Intel/Vlv2TbltDevicePkg/Include/Guid/EfiVpdData.h

@@ -0,0 +1,156 @@
+/*++
+
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>
+                                                                                   

+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+                                                                                   

+
+
+Module Name:
+
+  EfiVpdData.h
+
+Abstract:
+
+  Constants and declarations that are common accross PEI and DXE.
+--*/
+
+#ifndef _EFI_VPD_DATA_H_
+#define _EFI_VPD_DATA_H_
+
+
+#pragma pack(1)
+
+//
+// DMI data
+//
+typedef struct {
+
+  CHAR8 DmiGpnvHeader[4];             // $DMI
+  CHAR8 SystemInfoManufacturer[0x20]; // Structure Type 1 String 1
+  CHAR8 SystemInfoProductName[0x20];  // Structure Type 1 String 2
+  CHAR8 SystemInfoVersion[0x18];      // Structure Type 1 String 3
+  CHAR8 SystemInfoSerialNumber[0x20]; // Structure Type 1 String 4
+  CHAR8 BaseBoardManufacturer[0x20];  // Structure Type 2 String 1
+  CHAR8 BaseBoardProductName[0x20];   // Structure Type 2 String 2
+  CHAR8 BaseBoardVersion[0x18];       // Structure Type 2 String 3
+  CHAR8 BaseBoardSerialNumber[0x20];  // Structure Type 2 String 4
+  CHAR8 ChassisManufacturer[0x20];    // Structure Type 3 String 1
+  UINT8 ChassisType;                  // Enumerated
+  CHAR8 ChassisVersion[0x18];         // Structure Type 3 String 2
+  CHAR8 ChassisSerialNumber[0x20];    // Structure Type 3 String 3
+  CHAR8 ChassisAssetTag[0x20];        // Structure Type 3 String 4
+  UINT8 MfgAccessKeyWorkspace;
+
+  UINT8 ChecksumFixupPool[0xd];       // Checksum Fix-ups
+  UINT8 SwitchboardData[4];           // 32 switch switchboard
+  UINT8 IntelReserved;                // Reserved for Future Use
+} DMI_DATA;
+
+#define DMI_DATA_GUID \
+  { \
+    0x70e56c5e, 0x280c, 0x44b0, 0xa4, 0x97, 0x09, 0x68, 0x1a, 0xbc, 0x37, 0x5e \
+  }
+
+#define DMI_DATA_NAME       (L"DmiData")
+#define ASCII_DMI_DATA_NAME ("DmiData")
+
+extern EFI_GUID gDmiDataGuid;
+extern CHAR16   gDmiDataName[];
+
+//
+// UUID - universally unique system id.
+//
+#define UUID_VARIABLE_GUID \
+  { \
+    0xd357c710, 0x0ada, 0x4717, 0x8d, 0xba, 0xc6, 0xad, 0xc7, 0xcd, 0x2b, 0x2a \
+  }
+
+#define UUID_VARIABLE_NAME        (L"UUID")
+#define ASCII_UUID_VARIABLE_NAME  ("UUID")
+
+//
+// UUID data
+//
+typedef struct {
+  UINT32        UuidHigh;
+  UINT32        UuidLow;
+} SYSTEM_1394_UUID;
+
+typedef struct {
+  EFI_GUID          SystemUuid;                   // System Unique ID
+  SYSTEM_1394_UUID  System1394Uuid;               // Onboard 1394 UUID
+} UUID_DATA;
+
+extern EFI_GUID gUuidVariableGuid;
+extern CHAR16   gUuidVariableName[];
+
+//
+// MB32GUID for Computrace.
+//
+
+#define               MB32_GUID \
+  { 0x539D62BA, 0xDE35, 0x453E, 0xBA, 0xB0, 0x85, 0xDB, 0x8D, 0xA2, 0x42, 0xF9 }
+
+#define MB32_VARIABLE_NAME (L"MB32")
+#define ASCII_MB32_VARIABLE_NAME ("MB32")
+
+extern EFI_GUID gMb32Guid;
+extern CHAR16   gMb32VariableName[];
+
+//
+// ACPI OSFR Manufacturer String.
+//
+// {72234213-0FD7-48a1-A59F-B41BC107FBCD}
+//
+#define  ACPI_OSFR_MFG_STRING_VARIABLE_GUID \
+  {0x72234213, 0xfd7, 0x48a1, 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x7, 0xfb, 0xcd}
+#define ACPI_OSFR_MFG_STRING_VARIABLE_NAME (L"OcurMfg")
+#define ASCII_ACPI_OSFR_MF_STRING_VARIABLE_NAME ("OcurMfg")
+
+extern EFI_GUID gACPIOSFRMfgStringVariableGuid;
+
+
+//
+// ACPI OSFR Model String.
+//
+// {72234213-0FD7-48a1-A59F-B41BC107FBCD}
+//
+#define  ACPI_OSFR_MODEL_STRING_VARIABLE_GUID \
+  {0x72234213, 0xfd7, 0x48a1, 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x7, 0xfb, 0xcd}
+#define ACPI_OSFR_MODEL_STRING_VARIABLE_NAME (L"OcurModel")
+#define ASCII_ACPI_OSFR_MODEL_STRING_VARIABLE_NAME ("OcurModel")
+
+extern EFI_GUID gACPIOSFRModelStringVariableGuid;
+
+//
+// ACPI OSFR Reference Data Block.
+//
+// {72234213-0FD7-48a1-A59F-B41BC107FBCD}
+//
+#define  ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_GUID \
+  {0x72234213, 0xfd7, 0x48a1, 0xa5, 0x9f, 0xb4, 0x1b, 0xc1, 0x7, 0xfb, 0xcd}
+#define ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME (L"OcurRef")
+#define ASCII_ACPI_OSFR_REF_DATA_BLOCK_VARIABLE_NAME ("OcurRef")
+extern EFI_GUID gACPIOSFRRefDataBlockVariableGuid;
+
+//
+// Manufacturing mode GUID
+//
+#define MfgMode_GUID \
+  { 0xEF14FD78, 0x0793, 0x4e2b, 0xAC, 0x6D, 0x06, 0x28, 0x47, 0xE0, 0x17, 0x91 }
+
+#define MFGMODE_VARIABLE_NAME (L"MfgMode")
+#define ASCII_MFGMODE_VARIABLE_NAME ("MfgMode")
+
+typedef struct {
+	UINT8 MfgModeData;
+} MFG_MODE_VAR;
+
+extern EFI_GUID gMfgModeVariableGuid;
+extern CHAR16   gMfgModeVariableName[];
+
+#pragma pack()
+
+#endif

Some files were not shown because too many files changed in this diff